[python] 파이썬에서 알파벳순으로 유니 코드 문자열을 정렬하는 방법은 무엇입니까?

파이썬은 기본적으로 바이트 값을 기준으로 정렬합니다. 즉, é는 z 뒤에 오는 다른 똑같이 재미있는 것들입니다. Python에서 알파벳순으로 정렬하는 가장 좋은 방법은 무엇입니까?

이것에 대한 도서관이 있습니까? 나는 아무것도 찾을 수 없었다. 선호하는 정렬은 언어 지원이 있어야 åäö가 스웨덴어로 z 다음에 정렬되어야하지만 ü는 u 등으로 정렬되어야한다는 것을 이해합니다. 따라서 유니 코드 지원은 거의 필수 요건입니다.

라이브러리가없는 경우이를 수행하는 가장 좋은 방법은 무엇입니까? 문자에서 정수 값으로 매핑하고 문자열을 정수 목록에 매핑하십시오.



답변

IBM의 ICU 라이브러리가이를 수행합니다. Python 바인딩이 있습니다 : PyICU .

업데이트 : ICU와 ICU 정렬의 핵심 차이점은 locale.strcollICU가 전체 유니 코드 데이터 정렬 알고리즘strcoll사용하고 ISO 14651 을 사용 한다는 것 입니다.

이 두 알고리즘의 차이점은 http://unicode.org/faq/collation.html#13에 간략하게 요약되어 있습니다 . 이것은 실제로는 거의 중요하지 않은 다소 이국적인 특수한 경우입니다.

>>> import icu # pip install PyICU
>>> sorted(['a','b','c','ä'])
['a', 'b', 'c', 'ä']
>>> collator = icu.Collator.createInstance(icu.Locale('de_DE.UTF-8'))
>>> sorted(['a','b','c','ä'], key=collator.getSortKey)
['a', 'ä', 'b', 'c']


답변

나는 대답에서 이것을 보지 못합니다. 내 응용 프로그램은 Python의 표준 라이브러리를 사용하여 로케일에 따라 정렬됩니다. 꽤 쉽습니다.

# python2.5 code below
# corpus is our unicode() strings collection as a list
corpus = [u"Art", u"Älg", u"Ved", u"Wasa"]

import locale
# this reads the environment and inits the right locale
locale.setlocale(locale.LC_ALL, "")
# alternatively, (but it's bad to hardcode)
# locale.setlocale(locale.LC_ALL, "sv_SE.UTF-8")

corpus.sort(cmp=locale.strcoll)

# in python2.x, locale.strxfrm is broken and does not work for unicode strings
# in python3.x however:
# corpus.sort(key=locale.strxfrm)

Lennart 및 기타 답변자에게 질문 : ‘로케일’을 아는 ​​사람이 없습니까? 아니면이 작업에 맞지 않습니까?


답변

James Tauber의 Python Unicode Collation Algorithm을 사용해보십시오 . 원하는대로 정확하게 수행되지 않을 수 있지만 살펴볼 가치가있는 것 같습니다. 문제에 대한 자세한 정보는 Christopher Lenz 의이 게시물 을 참조하십시오 .


답변

pyuca에 관심이있을 수도 있습니다 .

http://jtauber.com/blog/2006/01/27/python_unicode_collation_algorithm/

확실히 가장 정확한 방법은 아니지만 최소한 어느 정도 옳게 만드는 아주 간단한 방법입니다. 또한 로케일이 스레드 세이프가 아니고 프로세스 전반에 걸쳐 언어 설정을 설정하기 때문에 웹앱에서 로케일을 능가합니다. 또한 외부 C 라이브러리에 의존하는 PyICU보다 설정하기 쉽습니다.

이 글을 쓰는 시점에 원본이 다운 되었기 때문에 스크립트를 github에 업로드했으며이를 얻기 위해 웹 캐시에 의존해야했습니다.

https://github.com/href/Python-Unicode-Collation-Algorithm

이 스크립트를 사용하여 plone 모듈에서 독일어 / 프랑스어 / 이탈리아어 텍스트를 올바르게 정렬했습니다.


답변

요약 및 확장 답변 :

locale.strcollPython 2 locale.strxfrm에서 실제로 문제를 해결하고 문제의 로케일이 설치되어 있다고 가정하면 실제로 문제를 해결할 수 있습니다. 로케일 이름이 혼란스럽게 다른 Windows에서도 테스트했지만 다른 한편으로는 기본적으로 지원되는 모든 로케일이 설치되어있는 것 같습니다.

ICU실제로이 작업을 더 잘 수행하는 것은 아니지만 훨씬 더 많은 작업을 수행 합니다. 특히 다른 언어로 된 텍스트를 단어로 분할 할 수있는 스플리터를 지원합니다. 이것은 단어 구분 기호가없는 언어에 매우 유용합니다. 하지만 포함되어 있지 않기 때문에 분할의 기본으로 사용할 단어 모음이 있어야합니다.

또한 로케일에 대한 긴 이름을 가지고 있으므로 로케일에 대한 예쁜 표시 이름, Gregorian 이외의 다른 달력에 대한 지원 (Python 인터페이스가 지원하는지 확실하지 않음) 및 기타 다소 모호한 로케일 지원의 톤과 톤을 얻을 수 있습니다. .

따라서 전체적으로 : 알파벳순으로 로케일에 따라 정렬하려는 경우 locale특별한 요구 사항이 없거나 단어 분할기와 같은 더 많은 로케일 종속 기능이 필요한 경우가 아니면 모듈을 사용할 수 있습니다 .


답변

나는 대답이 이미 훌륭한 작업을 수행했음을 알았습니다 . Human Sort의 코딩 비 효율성을 지적하고 싶었습니다 . 선택적 문자 별 변환을 유니 코드 문자열 s에 적용하려면 다음 코드를 사용합니다.

spec_dict = {'Å':'A', 'Ä':'A'}

def spec_order(s):
    return ''.join([spec_dict.get(ch, ch) for ch in s])

파이썬은이 보조 작업을 수행하는 훨씬 더 좋고 빠르며 간결한 방법을 가지고 있습니다 (유니 코드 문자열에서-바이트 문자열에 대한 유사한 방법은 다소 덜 도움이되는 사양을 가지고 있습니다!-) :

spec_dict = dict((ord(k), spec_dict[k]) for k in spec_dict)

def spec_order(s):
    return s.translate(spec_dict)

translate메서드에 전달하는 dict 에는 유니 코드 서수 (문자열 아님)가 키로 있으므로 원래 char-to-char에서 다시 빌드하는 단계가 필요합니다 spec_dict. ([서수 여야하는 키와는 반대로] 번역하기 위해 전달하는 dict의 값은 유니 코드 서수, 임의의 유니 코드 문자열 또는 번역의 일부로 해당 문자를 제거하기위한 None 일 수 있으므로 “ignore a 정렬 목적을위한 특정 문자 “,”정렬 목적을 위해 ä를 ae에 매핑 “등).

Python 3에서는 “재 구축”단계를 더 간단하게 수행 할 수 있습니다. 예 :

spec_dict = ''.maketrans(spec_dict)

Python 3 에서이 정적 메서드를 사용할 수있는 다른 방법 은 문서 를 참조하세요 maketrans.


답변

이를 구현하려면 “유니 코드 조합 알고리즘”에 대해 읽어야합니다. 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/