Python sortiert standardmäßig nach Byte-Wert, was bedeutet, dass é nach z und anderen ebenso lustigen Dingen kommt. Was ist der beste Weg, um in Python alphabetisch zu sortieren?
Gibt es dafür eine Bibliothek? Ich konnte nichts finden. Das Sortieren sollte vorzugsweise eine Sprachunterstützung haben, damit verstanden wird, dass åäö auf Schwedisch nach z sortiert werden sollte, ü jedoch nach u usw. sortiert werden sollte. Die Unicode-Unterstützung ist daher so ziemlich eine Voraussetzung.
Wenn es keine Bibliothek dafür gibt, wie geht das am besten? Machen Sie einfach eine Zuordnung von einem Buchstaben zu einem ganzzahligen Wert und ordnen Sie die Zeichenfolge damit einer ganzzahligen Liste zu?
locale.strcoll
Antwort ist richtig, wenn Sie eine Unicode-Sortierung nach dem Gebietsschema des Benutzers benötigen, und die Intensivstation antwortet, was Sie möchten, wenn Sie mehr als das benötigen (Sortierung mit mehr als einem Gebietsschema). Meistens willst dulocale.strcoll
.locale.strcoll
funktioniert und was ICU besser macht als die Python-Funktion. Grundsätzlich etwas mehr Aufmerksamkeit für die Frage.--locale=de__phonebook
wenn Sie es brauchen. Das Perl-Modul besteht die UCA-Testsuite, und das von mir bereitgestellte Skript erleichtert das Spielen mit der gesamten UCA und allen Optionen, einschließlich Gebietsschemas, nur über die Befehlszeile. Könnte die Frage nicht beantworten , sollte aber trotzdem sehr interessant sein. Wenn Sie in der Schweiz sind, können Sie sicher die Flexibilität nutzen. :)Antworten:
Die IBM ICU- Bibliothek macht das (und vieles mehr). Es hat Python-Bindungen: PyICU .
Update : Der Hauptunterschied bei der Sortierung zwischen der Intensivstation und der Intensivstation
locale.strcoll
besteht darin, dass die Intensivstation den vollständigen Unicode- Kollatierungsalgorithmusstrcoll
verwendet, während ISO 14651 verwendet wird .Die Unterschiede zwischen diesen beiden Algorithmen werden hier kurz zusammengefasst: http://unicode.org/faq/collation.html#13 . Dies sind eher exotische Sonderfälle, die in der Praxis selten eine Rolle spielen sollten.
quelle
locale.strxfrm
aus der Antwort von u0b34a0f6ae verwendet und es scheint zu funktionieren und ist viel eleganter und erfordert keine zusätzliche Software.sudo pip3 install PyICU
nicht installieren und Python2 auch nicht.Ich sehe das nicht in den Antworten. Meine Anwendung sortiert nach dem Gebietsschema unter Verwendung der Python-Standardbibliothek. Es ist ziemlich einfach.
Frage an Lennart und andere Antwortende: Kennt niemand das Gebietsschema oder liegt es nicht an dieser Aufgabe?
quelle
Probieren Sie den Python Unicode-Kollatierungsalgorithmus von James Tauber aus . Es kann nicht genau das tun, was Sie wollen, aber es scheint einen Blick wert zu sein. Weitere Informationen zu den Themen finden Sie in diesem Beitrag von Christopher Lenz.
quelle
Sie könnten auch an Pyuca interessiert sein :
http://jtauber.com/blog/2006/01/27/python_unicode_collation_algorithm/
Obwohl es sicherlich nicht der genaueste Weg ist, ist es ein sehr einfacher Weg, es zumindest etwas richtig zu machen. Es schlägt auch das Gebietsschema in einer Webanwendung, da das Gebietsschema nicht threadsicher ist und die Spracheinstellungen prozessweit festlegt. Es ist auch einfacher einzurichten als PyICU, das auf einer externen C-Bibliothek basiert.
Ich habe das Skript auf github hochgeladen, da das Original zum Zeitpunkt des Schreibens nicht verfügbar war, und ich musste auf Web-Caches zurückgreifen, um es zu erhalten:
https://github.com/href/Python-Unicode-Collation-Algorithm
Ich habe dieses Skript erfolgreich verwendet, um deutschen / französischen / italienischen Text in einem Plone-Modul zu sortieren.
quelle
Eine Zusammenfassung und erweiterte Antwort:
locale.strcoll
unter Python 2, undlocale.strxfrm
wird in der Tat das Problem lösen, und macht einen guten Job, vorausgesetzt, Sie haben das betreffende Gebietsschema installiert. Ich habe es auch unter Windows getestet, wo die Namen der Gebietsschemas verwirrend unterschiedlich sind, aber andererseits scheinen standardmäßig alle unterstützten Gebietsschemas installiert zu sein.ICU
macht dies in der Praxis nicht unbedingt besser, macht aber viel mehr . Insbesondere werden Splitter unterstützt, mit denen Texte in verschiedenen Sprachen in Wörter aufgeteilt werden können. Dies ist sehr nützlich für Sprachen ohne Worttrennzeichen. Sie benötigen ein Korpus von Wörtern, um es als Grundlage für die Aufteilung zu verwenden, da dies jedoch nicht enthalten ist.Es hat auch lange Namen für die Gebietsschemas, so dass Sie hübsche Anzeigenamen für das Gebietsschema erhalten, Unterstützung für andere Kalender als Gregorian (obwohl ich nicht sicher bin, ob die Python-Oberfläche dies unterstützt) und Tonnen von anderen mehr oder weniger obskuren Gebietsschemas .
Alles in allem: Wenn Sie alphabetisch und vom Gebietsschema abhängig sortieren möchten, können Sie das
locale
Modul verwenden, es sei denn, Sie haben spezielle Anforderungen oder benötigen mehr vom Gebietsschema abhängige Funktionen wie den Wortsplitter.quelle
Ich sehe, dass die Antworten bereits hervorragende Arbeit geleistet haben, wollte nur auf eine Ineffizienz der Codierung in Human Sort hinweisen . Um eine selektive char-by-char-Übersetzung auf eine Unicode-Zeichenfolge anzuwenden, wird der folgende Code verwendet:
Python bietet eine viel bessere, schnellere und präzisere Möglichkeit, diese Hilfsaufgabe auszuführen (bei Unicode-Zeichenfolgen - die analoge Methode für Byte-Zeichenfolgen hat eine andere und etwas weniger hilfreiche Spezifikation! -):
Das Diktat, das Sie an die
translate
Methode übergeben, enthält Unicode-Ordnungszahlen (keine Zeichenfolgen) als Schlüssel. Deshalb benötigen wir diesen Wiederherstellungsschritt vom ursprünglichen Zeichen zu Zeichenspec_dict
. (Werte in dem Diktat, das Sie zur Übersetzung übergeben [im Gegensatz zu Schlüsseln, bei denen es sich um Ordnungszahlen handeln muss], können Unicode-Ordnungszahlen, beliebige Unicode-Zeichenfolgen oder Keine sein, um das entsprechende Zeichen als Teil der Übersetzung zu entfernen. Daher ist es einfach, "Ignorieren a" anzugeben bestimmtes Zeichen für Sortierzwecke "," Zu ä für Sortierzwecke zuordnen "und dergleichen).In Python 3 können Sie den Schritt "Wiederherstellen" einfacher ausführen, z.
Sehen Sie die Dokumentation für andere Möglichkeiten , wie Sie diese verwenden können
maketrans
statische Methode in Python 3.quelle
Um es zu implementieren, müssen Sie über "Unicode-Kollatierungsalgorithmus" lesen, siehe http://en.wikipedia.org/wiki/Unicode_collation_algorithm
http://www.unicode.org/unicode/reports/tr10/
Eine Beispielimplementierung finden Sie hier
http://jtauber.com/blog/2006/01/27/python_unicode_collation_algorithm/
quelle
In letzter Zeit habe ich zope.ucol ( https://pypi.python.org/pypi/zope.ucol ) für diese Aufgabe verwendet. Zum Beispiel sortieren Sie das deutsche ß:
zope.ucol verpackt auch die Intensivstation und wäre somit eine Alternative zur PyICU.
quelle
Eine vollständige UCA-Lösung
Die einfachste, einfachste und einfachste Möglichkeit, dies zu tun, besteht darin, ein Callout für das Perl-Bibliotheksmodul Unicode :: Collate :: Locale zu erstellen , das eine Unterklasse des Standardmoduls Unicode :: Collate ist . Sie müssen dem Konstruktor lediglich einen Gebietsschemawert
"xv"
für Schweden übergeben.(Sie werden dies vielleicht nicht unbedingt für schwedischen Text zu schätzen wissen, aber da Perl abstrakte Zeichen verwendet, können Sie jeden beliebigen Unicode-Codepunkt verwenden - unabhängig von der Plattform oder dem Build! Nur wenige Sprachen bieten einen solchen Komfort. Ich erwähne es, weil ich gegen a gekämpft habe Ich habe in letzter Zeit viel mit Java wegen dieses verrückten Problems verloren.)
Das Problem ist, dass ich nicht weiß, wie ich von Python aus auf ein Perl-Modul zugreifen soll - abgesehen von der Verwendung eines Shell-Callouts oder einer zweiseitigen Pipe. Zu diesem Zweck habe ich Ihnen daher ein vollständiges Arbeitsskript namens ucsort zur Verfügung gestellt , das Sie aufrufen können, um genau das zu tun, wonach Sie gefragt haben.
Dieses Skript ist zu 100% mit dem vollständigen Unicode-Kollatierungsalgorithmus kompatibel , wobei alle Anpassungsoptionen unterstützt werden !! Wenn Sie ein optionales Modul installiert haben oder Perl 5.13 oder besser ausführen, haben Sie vollen Zugriff auf benutzerfreundliche CLDR-Gebietsschemas. Siehe unten.
Demonstration
Stellen Sie sich einen Eingabesatz vor, der folgendermaßen angeordnet ist:
Eine Standard-Sortierung nach Codepunkt ergibt:
Das ist falsch in jedermanns Buch. Mit meinem Skript, das den Unicode-Kollatierungsalgorithmus verwendet, erhalten Sie folgende Reihenfolge:
Dies ist die Standard-UCA-Sortierung. Um das schwedische Gebietsschema zu erhalten, rufen Sie ucsort folgendermaßen auf :
Hier ist eine bessere Eingabedemo. Zunächst der Eingabesatz:
Nach Codepunkt sortiert das folgendermaßen:
Bei Verwendung der Standard-UCA wird dies jedoch folgendermaßen sortiert:
Aber im schwedischen Gebietsschema so:
Wenn Sie es vorziehen, Großbuchstaben vor Kleinbuchstaben zu sortieren, gehen Sie folgendermaßen vor:
Kundenspezifische Sorten
Mit ucsort können Sie viele andere Dinge tun . So sortieren Sie beispielsweise Titel auf Englisch:
Sie benötigen Perl 5.10.1 oder besser, um das Skript im Allgemeinen auszuführen. Für die Unterstützung des Gebietsschemas müssen Sie entweder das optionale CPAN-Modul installieren
Unicode::Collate::Locale
. Alternativ können Sie eine Entwicklungsversion von Perl 5.13+ installieren, die dieses Modul standardmäßig enthält.Konventionen aufrufen
Dies ist ein schneller Prototyp, daher ist ucsort größtenteils nicht (der) dokumentiert. Dies ist jedoch die ÜBERSICHT darüber, welche Schalter / Optionen in der Befehlszeile akzeptiert werden:
Ja, ok: Das ist wirklich die Argumentliste, die ich für den Anruf verwende
Getopt::Long
, aber Sie haben die Idee. :) :)Wenn Sie herausfinden können, wie Sie Perl-Bibliotheksmodule direkt aus Python aufrufen können, ohne ein Perl-Skript aufzurufen, tun Sie dies auf jeden Fall. Ich weiß nur nicht wie ich. Ich würde gerne lernen wie.
In der Zwischenzeit glaube ich, dass dieses Skript genau das tun wird, was Sie brauchen - und noch mehr! Ich benutze dies jetzt für die gesamte Textsortierung. Es macht endlich das, was ich für eine lange, lange Zeit gebraucht habe.
Der einzige Nachteil ist, dass das
--locale
Argument dazu führt, dass die Leistung in die Hose geht, obwohl es schnell genug für eine reguläre, nicht lokale, aber dennoch 100% UCA-konforme Sortierung ist. Da alles in den Speicher geladen wird, möchten Sie dies wahrscheinlich nicht für Gigabyte-Dokumente verwenden. Ich benutze es oft am Tag und es ist sicher großartig, endlich eine vernünftige Textsortierung zu haben.quelle
Es ist weit von einer vollständigen Lösung für Ihren Anwendungsfall, aber man kann einen Blick auf das nehmen unaccent.py Skript von effbot.org. Grundsätzlich werden alle Akzente aus einem Text entfernt. Sie können diesen "bereinigten" Text verwenden, um alphabetisch zu sortieren. (Eine bessere Beschreibung finden Sie auf dieser Seite.)
quelle
Jeff Atwood hat einen guten Beitrag über Natural Sort Order geschrieben , in dem er ein Skript verlinkt hat, das so ziemlich das tut , was Sie verlangen .
Es ist keineswegs ein triviales Skript, aber es macht den Trick.
quelle