Python по умолчанию сортирует по байтовому значению, что означает, что é идет после z и других не менее забавных вещей. Как лучше всего сортировать по алфавиту в Python?
Есть ли для этого библиотека? Я ничего не нашел. Предпочтительно сортировка должна иметь языковую поддержку, чтобы понимать, что åäö следует сортировать после z на шведском языке, а ü следует сортировать по u и т. Д. Таким образом, поддержка Unicode в значительной степени является требованием.
Если для этого нет библиотеки, как лучше всего это сделать? Просто выполните сопоставление буквы с целочисленным значением и сопоставьте строку с целым списком с этим?
locale.strcoll
Ответ является правильным , когда вам нужно Unicode сортировки с использованием локали пользователя, и ICU ответ , что вы хотите , когда вам нужно больше , чем (сверку с использованием более одного языкового стандарта). В большинстве случаев вы хотитеlocale.strcoll
.locale.strcoll
работает и особенно то, что ICU лучше, чем функция Python. В основном еще немного внимания к вопросу.--locale=de__phonebook
когда вам это нужно. Модуль Perl проходит тестовый набор UCA, а предоставленный мной сценарий значительно упрощает работу со всем UCA, а также со всеми его параметрами, включая локали, прямо из командной строки. Не могу ответить на вопрос, но все равно должно быть очень интересно. Если вы находитесь в Швейцарии, я уверен, что вы могли бы воспользоваться этой гибкостью. :)Ответы:
Библиотека IBM ICU делает это (и многое другое). Он имеет привязки Python: PyICU .
Обновить : основное различие в сортировке между ICU и ICU
locale.strcoll
заключается в том, что ICU использует полный алгоритм сортировки Unicode, ноstrcoll
использует ISO 14651 .Здесь кратко описаны различия между этими двумя алгоритмами: http://unicode.org/faq/collation.html#13 . Это довольно экзотические частные случаи, которые редко имеют значение на практике.
источник
locale.strxfrm
ответ u0b34a0f6ae, и, похоже, он работает, намного элегантнее и не требует дополнительного программного обеспечения.sudo pip3 install PyICU
не устанавливается, как и с Python2.Я не вижу этого в ответах. Мое приложение сортируется по языку с использованием стандартной библиотеки python. Это довольно просто.
Вопрос к Леннарту и другим респондентам: никто не знает «локаль» или не справляется с этой задачей?
источник
Попробуйте алгоритм сортировки Unicode Python Джеймса Таубера . Возможно, это не совсем то, что вам нужно, но, похоже, стоит взглянуть. Для получения дополнительной информации о проблемах см. Этот пост Кристофера Ленца.
источник
Возможно, вас заинтересует пьюка :
http://jtauber.com/blog/2006/01/27/python_unicode_collation_algorithm/
Хотя это, конечно, не самый точный способ, но это очень простой способ хотя бы в некоторой степени сделать это правильно. Он также превосходит языковой стандарт в веб-приложении, поскольку языковой стандарт не является потокобезопасным и устанавливает языковые настройки для всего процесса. Его также проще настроить, чем PyICU, который использует внешнюю библиотеку C.
Я загрузил скрипт на github, так как оригинал был недоступен на момент написания этой статьи, и мне пришлось прибегнуть к веб-кешам, чтобы получить его:
https://github.com/href/Python-Unicode-Collation-Algorithm
Я успешно использовал этот скрипт для разумной сортировки немецкого / французского / итальянского текста в модуле plone.
источник
Резюме и расширенный ответ:
locale.strcoll
под Python 2, иlocale.strxfrm
фактически решит проблему и хорошо справится со своей задачей, если у вас установлен соответствующий языковой стандарт. Я также тестировал его под Windows, где имена языковых стандартов отличаются друг от друга, но с другой стороны, похоже, что все поддерживаемые языковые стандарты установлены по умолчанию.ICU
на практике это не обязательно лучше, но гораздо больше . В частности, он поддерживает разделители, которые могут разбивать тексты на разных языках на слова. Это очень полезно для языков, в которых нет разделителей слов. Вам понадобится набор слов для использования в качестве основы для разделения, потому что он не включен.Он также имеет длинные имена для локалей, поэтому вы можете получить красивые отображаемые имена для локали, поддержку других календарей, кроме григорианского (хотя я не уверен, что интерфейс Python поддерживает это) и множество других, более или менее неясных, поддерживает локаль. .
Итак, в целом: если вы хотите сортировать по алфавиту и в зависимости от языкового стандарта, вы можете использовать
locale
модуль, если у вас нет особых требований или если вам не нужны дополнительные функции, зависящие от языкового стандарта, такие как разделитель слов.источник
Я вижу, что ответы уже проделали отличную работу, просто хотел указать на одну неэффективность кодирования в Human Sort . Чтобы применить выборочный посимвольный перевод к строке юникода s, он использует код:
У Python есть гораздо лучший, более быстрый и лаконичный способ выполнения этой вспомогательной задачи (для строк Unicode - аналогичный метод для байтовых строк имеет другую и несколько менее полезную спецификацию! -):
В dict, который вы передаете
translate
методу, в качестве ключей используются порядковые номера Unicode (а не строки), поэтому нам нужен этот шаг восстановления от исходного char-to-charspec_dict
. (Значения в dict, который вы передаете для перевода [в отличие от ключей, которые должны быть порядковыми], могут быть порядковыми номерами Unicode, произвольными строками Unicode или None, чтобы удалить соответствующий символ как часть перевода, поэтому легко указать «игнорировать определенный символ для целей сортировки "," сопоставить ä с ae для целей сортировки "и т.п.).В Python 3 этап «перестройки» можно сделать проще, например:
См. Документацию о других способах использования этого
maketrans
статического метода в Python 3.источник
Чтобы реализовать его, вам нужно будет прочитать об "алгоритме сортировки Unicode" см. Http://en.wikipedia.org/wiki/Unicode_collation_algorithm
http://www.unicode.org/unicode/reports/tr10/
образец реализации здесь
http://jtauber.com/blog/2006/01/27/python_unicode_collation_algorithm/
источник
В последнее время я использую zope.ucol ( https://pypi.python.org/pypi/zope.ucol ) для этой задачи. Например, сортировка немецкого ß:
zope.ucol также является оболочкой для ICU, поэтому он может быть альтернативой PyICU.
источник
Полное решение УЦА
Самый простой, легкий и понятный способ сделать это - вызвать модуль библиотеки Perl, Unicode :: Collate :: Locale , который является подклассом стандартного модуля Unicode :: Collate . Все, что вам нужно сделать, это передать конструктору значение локали
"xv"
для Швеции.(Вы можете не обязательно ценить это для шведского текста, но поскольку Perl использует абстрактные символы, вы можете использовать любой код Unicode, какой захотите - независимо от платформы или сборки! Некоторые языки предлагают такое удобство. Я упоминаю об этом, потому что я борюсь с в последнее время много проигрывает битве с Java из-за этой сводящей с ума проблемы.)
Проблема в том, что я не знаю, как получить доступ к модулю Perl из Python - за исключением использования выноски оболочки или двустороннего канала. С этой целью я предоставил вам полный рабочий сценарий под названием ucsort. который вы можете вызвать, чтобы с легкостью выполнить именно то, что вы просили.
Этот скрипт на 100% совместим с полным алгоритмом сортировки Unicode , при этом поддерживаются все параметры настройки !! А если у вас установлен дополнительный модуль или вы используете Perl 5.13 или выше, то у вас есть полный доступ к простым в использовании языковым стандартам CLDR. Увидеть ниже.
Демонстрация
Представьте себе набор входных данных, упорядоченный таким образом:
Сортировка по умолчанию по кодовой точке дает:
что неверно всеми книгами. Используя мой скрипт, который использует алгоритм сортировки Unicode, вы получите следующий порядок:
Это стандартная сортировка UCA. Чтобы получить шведский язык, вызовите ucsort следующим образом:
Вот лучшая демонстрация ввода. Во-первых, входной набор:
По кодовой точке это сортируется следующим образом:
Но использование UCA по умолчанию позволяет отсортировать это следующим образом:
Но в шведском регионе так:
Если вы предпочитаете сортировать заглавные буквы перед строчными, сделайте следующее:
Индивидуальные сортировки
С ucsort вы можете делать многое другое . Например, вот как отсортировать заголовки на английском языке:
Вам понадобится Perl 5.10.1 или лучше для запуска сценария в целом. Для поддержки локали необходимо установить дополнительный модуль CPAN
Unicode::Collate::Locale
. Кроме того, вы можете установить разрабатываемые версии Perl, 5.13+, которые стандартно включают этот модуль.Соглашения о вызовах
Это быстрый прототип, поэтому ucsort в основном не документирован. Но это его СИНОПСИС того, какие переключатели / параметры он принимает в командной строке:
Да, хорошо: это действительно список аргументов, который я использую для вызова
Getopt::Long
, но вы поняли идею. :)Если вы можете понять, как вызывать модули библиотеки Perl из Python напрямую, не вызывая Perl-скрипт, обязательно сделайте это. Я просто не знаю, как сам. Я бы хотел узнать, как это сделать.
А пока я считаю, что этот скрипт сделает то, что вам нужно, во всех его деталях - и даже больше! Теперь я использую это для всей сортировки текста. Это , наконец , делает то , что я нужен в течение долгого, долгого времени.
Единственным недостатком является то, что этот
--locale
аргумент приводит к падению производительности, хотя этого достаточно для обычной, не локальной, но все же 100% -ной сортировки, соответствующей требованиям UCA . Поскольку он загружает все в память, вы, вероятно, не захотите использовать его для гигабайтных документов. Я использую его много раз в день, и я уверен, что наконец-то здорово, что у меня появилась разумная сортировка текста.источник
Это далеко от полного решения для Вашего случая использования, но вы могли бы взглянуть на unaccent.py сценарий из effbot.org. По сути, он удаляет все акценты из текста. Вы можете использовать этот «очищенный» текст для сортировки по алфавиту. (Более подробное описание см. На этой странице.)
источник
Джефф Этвуд написал хороший пост о естественном порядке сортировки , в нем он сослался на скрипт, который делает почти то, что вы просите .
В любом случае это нетривиальный сценарий, но он помогает.
источник