Python domyślnie sortuje według wartości bajtów, co oznacza, że é występuje po z i innych równie zabawnych rzeczach. Jaki jest najlepszy sposób sortowania alfabetycznego w Pythonie?
Czy jest do tego biblioteka? Nic nie mogłem znaleźć. Najlepiej, jeśli sortowanie powinno mieć obsługę języka, aby rozumieć, że åäö powinno być sortowane po szwedzku po z, ale ü powinno być sortowane według u, itd. Dlatego obsługa Unicode jest w dużym stopniu wymagana.
Jeśli nie ma do tego biblioteki, jaki jest najlepszy sposób, aby to zrobić? Po prostu wykonaj mapowanie z litery na wartość całkowitą i zamapuj ciąg na listę liczb całkowitych za pomocą tego?
locale.strcoll
Odpowiedź jest poprawna, kiedy trzeba Unicode sortowania za pomocą ustawień regionalnych użytkownika, a odpowiedź ICU co chcesz i kiedy trzeba więcej niż (sortowanie przy użyciu więcej niż jednego regionu). W większości przypadków chceszlocale.strcoll
.locale.strcoll
działa, a zwłaszcza co ICU robi lepiej niż funkcja Pythona. Zasadniczo trochę więcej uwagi na pytanie.--locale=de__phonebook
kiedy tego potrzebujesz. Moduł Perl przechodzi zestaw testów UCA, a skrypt, który dostarczyłem , znacznie ułatwia grę z całym UCA i wszystkimi jego opcjami, w tym ustawieniami narodowymi, tylko z wiersza poleceń. Może nie odpowiedzieć na pytanie, ale powinno być bardzo interesujące. Jeśli jesteś w Szwajcarii, jestem pewien, że możesz skorzystać z elastyczności. :)Odpowiedzi:
Robi to biblioteka IBM ICU (i wiele więcej). Posiada powiązania Pythona: PyICU .
Aktualizacja : Podstawowa różnica w sortowaniu między jednostkami ICU
locale.strcoll
polega na tym, że ICU używa pełnego algorytmu sortowania Unicode, podczas gdystrcoll
używa ISO 14651 .Różnice między tymi dwoma algorytmami zostały pokrótce podsumowane tutaj: http://unicode.org/faq/collation.html#13 . Są to raczej egzotyczne przypadki szczególne, które w praktyce rzadko mają znaczenie.
źródło
locale.strxfrm
z odpowiedzi u0b34a0f6ae i wydaje się, że działa i jest znacznie bardziej elegancki i nie wymaga żadnego dodatkowego oprogramowania.sudo pip3 install PyICU
nie można zainstalować, podobnie jak w przypadku Python2.Nie widzę tego w odpowiedziach. Moja aplikacja sortuje według ustawień regionalnych przy użyciu standardowej biblioteki Pythona. To całkiem proste.
Pytanie do Lennarta i innych osób odpowiadających: Czy nikt nie zna „lokalizacji”, czy też nie spełnia tego zadania?
źródło
Wypróbuj algorytm sortowania w formacie Python Unicode Jamesa Taubera . Może nie działać dokładnie tak, jak chcesz, ale wydaje się, że warto go zobaczyć. Aby uzyskać więcej informacji na temat problemów, zobacz ten post autorstwa Christophera Lenza.
źródło
Możesz być także zainteresowany Pyuca :
http://jtauber.com/blog/2006/01/27/python_unicode_collation_algorithm/
Chociaż z pewnością nie jest to najdokładniejszy sposób, jest to bardzo prosty sposób, aby przynajmniej zrobić to trochę dobrze. Przebiega również ustawienia regionalne w aplikacjach internetowych, ponieważ ustawienia regionalne nie są bezpieczne dla wątków i ustawiają ustawienia języka w całym procesie. Jest również łatwiejszy w konfiguracji niż PyICU, który opiera się na zewnętrznej bibliotece C.
Przesłałem skrypt na github, ponieważ oryginał nie działał w momencie pisania tego tekstu i musiałem skorzystać z pamięci podręcznej sieci, aby go zdobyć:
https://github.com/href/Python-Unicode-Collation-Algorithm
Z powodzeniem użyłem tego skryptu do zdrowego sortowania tekstu niemieckiego / francuskiego / włoskiego w module plone.
źródło
Podsumowanie i rozszerzona odpowiedź:
locale.strcoll
w Pythonie 2 ilocale.strxfrm
faktycznie rozwiąże problem i wykonuje dobrą robotę, zakładając, że masz zainstalowane odpowiednie ustawienie regionalne. Przetestowałem go również pod Windows, gdzie nazwy ustawień narodowych są myląco różne, ale z drugiej strony wydaje się, że domyślnie są zainstalowane wszystkie obsługiwane lokalizacje.ICU
niekoniecznie robi to lepiej w praktyce, jednak robi o wiele więcej . Przede wszystkim obsługuje rozdzielacze, które mogą dzielić teksty w różnych językach na słowa. Jest to bardzo przydatne w językach, w których nie ma separatorów słów. Będziesz musiał mieć zbiór słów, które posłużą jako podstawa do podziału, ponieważ nie są one uwzględnione.Ma również długie nazwy ustawień regionalnych, dzięki czemu można uzyskać ładne nazwy wyświetlane dla ustawień regionalnych, obsługę kalendarzy innych niż gregoriański (chociaż nie jestem pewien, czy interfejs Pythona to obsługuje) i mnóstwo innych mniej lub bardziej niejasnych obsługiwanych ustawień regionalnych .
Podsumowując: jeśli chcesz sortować alfabetycznie i zależnie od lokalizacji, możesz użyć
locale
modułu, chyba że masz specjalne wymagania lub potrzebujesz więcej funkcji zależnych od lokalizacji, takich jak rozdzielacz słów.źródło
Widzę, że odpowiedzi już wykonały świetną robotę, chciałem tylko wskazać jedną nieskuteczność kodowania w sortowaniu ludzkim . Aby zastosować selektywne tłumaczenie znak po znaku do ciągu znaków Unicode, używa kodu:
Python ma znacznie lepszy, szybszy i bardziej zwięzły sposób wykonania tego zadania pomocniczego (na łańcuchach Unicode - analogiczna metoda dla ciągów bajtów ma inną i nieco mniej pomocną specyfikację! -):
Dykt, który przekazujesz do
translate
metody, ma liczby porządkowe Unicode (nie ciągi) jako klucze, dlatego potrzebujemy tego kroku przebudowy z oryginalnego znaku-znakuspec_dict
. (Wartości w dyktandzie, które przekazujesz do przetłumaczenia [w przeciwieństwie do kluczy, które muszą być liczbami porządkowymi] mogą być liczbami porządkowymi Unicode, dowolnymi ciągami znaków Unicode lub Brak, aby usunąć odpowiedni znak jako część tłumaczenia, więc łatwo jest określić „ignoruj określony znak do celów sortowania ”,„ map ä to ae do celów sortowania ”i tym podobne).W Pythonie 3 krok „przebudowy” jest prostszy, np .:
Zobacz dokumentację, aby poznać inne sposoby użycia tej
maketrans
metody statycznej w Pythonie 3.źródło
Aby go zaimplementować, musisz przeczytać o „algorytmie sortowania Unicode”, patrz http://en.wikipedia.org/wiki/Unicode_collation_algorithm
http://www.unicode.org/unicode/reports/tr10/
przykładowa implementacja jest tutaj
http://jtauber.com/blog/2006/01/27/python_unicode_collation_algorithm/
źródło
Ostatnio do tego zadania używam zope.ucol ( https://pypi.python.org/pypi/zope.ucol ). Na przykład sortowanie niemieckiego ß:
zope.ucol obejmuje również OIOM, więc byłby alternatywą dla PyICU.
źródło
Kompletne rozwiązanie UCA
Najprostszym, najłatwiejszym i najprostszym sposobem wykonania tego jest wywołanie modułu biblioteki Perl, Unicode :: Collate :: Locale , który jest podklasą standardowego modułu Unicode :: Collate . Wszystko, co musisz zrobić, to przekazać konstruktorowi wartość locale
"xv"
dla Szwecji.(Być może niekoniecznie doceniasz to w szwedzkim tekście, ale ponieważ Perl używa abstrakcyjnych znaków, możesz użyć dowolnego punktu kodu Unicode, który Ci się podoba - bez względu na platformę lub wersję! Niewiele języków oferuje taką wygodę. Wspominam o tym, ponieważ walczę z ostatnio przegrywała bitwę z Javą z powodu tego irytującego problemu.)
Problem polega na tym, że nie wiem, jak uzyskać dostęp do modułu Perla z Pythona - pomijając, to znaczy używając wywołania powłoki lub dwustronnego potoku. W tym celu dostarczyłem ci zatem kompletny skrypt roboczy zwany ucsort , który możesz wywołać, aby zrobić dokładnie to, o co prosiłeś, z doskonałą łatwością.
Ten skrypt jest w 100% zgodny z pełnym algorytmem sortowania Unicode , z obsługą wszystkich opcji dostosowywania !! A jeśli masz zainstalowany opcjonalny moduł lub korzystasz z Perla 5.13 lub nowszego, masz pełny dostęp do łatwych w użyciu ustawień regionalnych CLDR. Zobacz poniżej.
Demonstracja
Wyobraź sobie zestaw wejściowy uporządkowany w ten sposób:
Domyślne sortowanie według punktu kodowego daje:
co jest błędne w książce wszystkich. Korzystając z mojego skryptu, który używa algorytmu sortowania Unicode, otrzymujesz następującą kolejność:
To jest domyślne sortowanie UCA. Aby uzyskać szwedzkie ustawienie regionalne, zadzwoń do ucsort w ten sposób:
Oto lepsze demo wejścia. Najpierw zestaw wejściowy:
Według punktu kodowego, to sortuje w ten sposób:
Ale użycie domyślnego UCA powoduje sortowanie w ten sposób:
Ale w szwedzkim lokalu tak:
Jeśli wolisz sortować wielkie litery przed małymi, zrób to:
Niestandardowe rodzaje
Możesz zrobić wiele innych rzeczy za pomocą ucsort . Na przykład, oto jak sortować tytuły w języku angielskim:
Do uruchomienia skryptu będziesz potrzebować Perla 5.10.1 lub nowszego. Aby zapewnić obsługę ustawień regionalnych, należy albo zainstalować opcjonalny moduł CPAN
Unicode::Collate::Locale
. Alternatywnie możesz zainstalować wersje rozwojowe Perla, 5.13+, które standardowo zawierają ten moduł.Konwencje telefoniczne
Jest to szybki prototyp, więc ucsort jest przeważnie nieudokumentowany. Ale to jest jego SKŁADNIA tego, jakie przełączniki / opcje akceptuje w wierszu poleceń:
Tak, ok: to naprawdę lista argumentów, której używam w wywołaniu
Getopt::Long
, ale masz pomysł. :)Jeśli potrafisz dowiedzieć się, jak wywołać moduły biblioteki Perla bezpośrednio z Pythona bez wywoływania skryptu Perla, zrób to. Po prostu nie wiem, jak ja. Chciałbym się dowiedzieć, jak to zrobić.
W międzyczasie uważam, że ten skrypt zrobi to, czego potrzebujesz w każdym szczególe - a nawet więcej! Teraz używam tego do sortowania całego tekstu. W końcu robi to, czego potrzebowałem przez długi, długi czas.
Jedynym minusem jest to, że
--locale
argument powoduje spadek wydajności, chociaż jest wystarczająco szybki do regularnego, nielokalnego, ale nadal w 100% zgodnego z UCA sortowania. Ponieważ ładuje wszystko w pamięci, prawdopodobnie nie chcesz używać tego w dokumentach gigabajtowych. Używam go wiele razy dziennie i na pewno świetnie jest mieć wreszcie rozsądne sortowanie tekstu.źródło
To jest daleko od kompletnego rozwiązania dla przypadku użycia, ale można spojrzeć na unaccent.py skrypt z effbot.org. W zasadzie usuwa wszystkie akcenty z tekstu. Możesz użyć tego „oczyszczonego” tekstu do sortowania alfabetycznego. (Dokładniejszy opis znajduje się na tej stronie).
źródło
Jeff Atwood napisał dobry post na temat naturalnego porządku sortowania , w którym umieścił link do scenariusza, który robi prawie to, o co prosisz .
W żadnym wypadku nie jest to trywialny skrypt, ale załatwia sprawę.
źródło