복붙노트

[PYTHON] 파이썬에서 알파벳순으로 유니 코드 문자열을 정렬하려면 어떻게해야합니까?

PYTHON

파이썬에서 알파벳순으로 유니 코드 문자열을 정렬하려면 어떻게해야합니까?

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

이것을위한 라이브러리가 있습니까? 나는 아무것도 찾을 수 없었다. 바람직하게 정렬은 언어 지원을 가져야하므로 Åäö가 스웨덴어로 z 다음에 정렬되어야하지만 ü는 u 등으로 정렬되어야한다는 것을 이해하므로 유니 코드 지원은 거의 요구 사항입니다.

라이브러리가없는 경우이를 수행하는 가장 좋은 방법은 무엇입니까? 문자에서 정수 값으로의 매핑을 만들고 그 문자열을 정수리스트에 매핑 하시겠습니까?

해결법

  1. ==============================

    1.IBM의 ICU 라이브러리는 그렇게합니다 (그리고 훨씬 더). Python 바인딩을 가지고 있습니다 : PyICU.

    IBM의 ICU 라이브러리는 그렇게합니다 (그리고 훨씬 더). Python 바인딩을 가지고 있습니다 : PyICU.

    업데이트 : ICU와 locale.strcoll 사이의 정렬의 핵심 차이점은 ICU는 완전한 Unicode Collation Algorithm을 사용하고 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']
    
  2. ==============================

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

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

    # 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)와 다른 응답자들에게 질문 : "로케일 (locale)"을 아는 사람이 없거나이 일에 부합되지 않는가?

  3. ==============================

    3.James Tauber의 Python Unicode Collation Algorithm을 사용해보십시오. 당신이 원하는대로 정확하게 할 수는 없겠지 만보기 좋을 것 같습니다. 문제에 대한 자세한 내용은 Christopher Lenz의이 게시물을 참조하십시오.

    James Tauber의 Python Unicode Collation Algorithm을 사용해보십시오. 당신이 원하는대로 정확하게 할 수는 없겠지 만보기 좋을 것 같습니다. 문제에 대한 자세한 내용은 Christopher Lenz의이 게시물을 참조하십시오.

  4. ==============================

    4.당신은 또한에 관심이있을 수 있습니다 pyuca :

    당신은 또한에 관심이있을 수 있습니다 pyuca :

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

    그것은 확실히 가장 정확한 방법은 아니지만 적어도 다소 이상하게 만드는 것은 매우 간단한 방법입니다. 로케일은 스레드 세이프가 아니며 프로세스 전반에 걸쳐 언어 설정을 설정하기 때문에 웹 애플리케이션에서도 로케일보다 우수합니다. 또한 외부 C 라이브러리에 의존하는 PyICU보다 설치가 쉽습니다.

    필자는이 글을 쓰던 당시 원본이 다운되었으므로 스크립트를 github에 업로드했으며 웹 캐시를 사용하여 스크립트를 가져와야했습니다.

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

    나는 성공적으로이 스크립트를 plone 모듈에서 독일어 / 프랑스어 / 이탈리아어 텍스트를 정렬하기 위해 사용했다.

  5. ==============================

    5.요약 및 확장 답변 :

    요약 및 확장 답변 :

    Python 2의 locale.strcoll과 locale.strxfrm은 사실 문제를 해결할 것이고 문제의 로케일을 설치했다면 좋은 일을 할 것입니다. 나는 로캘 이름이 혼란스럽게 다른 Windows에서도 테스트했지만 다른 한편으로는 기본적으로 지원되는 모든 로케일을 갖고있는 것으로 보입니다.

    ICU는 실제로이 점을 더 잘 수행하지는 않지만 더 많은 일을합니다. 특히 다른 언어로 된 텍스트를 단어로 분리 할 수있는 스플리터를 지원합니다. 이것은 단어 분리 기호가없는 언어에 매우 유용합니다. 당신은 단어의 코퍼스를 나누기의 기초로 사용할 필요가 있습니다. 왜냐하면 그것은 포함되지 않기 때문입니다.

    또한 로케일의 이름이 길어서 로케일에 대한 예쁜 이름을 표시 할 수 있고 그레고리오 (Python 인터페이스가 지원하는지는 잘 모르겠지만) 이외의 다른 캘린더를 지원할 수 있으며 다소 많거나 적은 애매한 로케일 지원 .

    따라서 모두 : 알파벳순과 로캘 별 정렬을 원할 경우 특별한 요구 사항이 없거나 단어 분리기와 같은 로캘 별 기능이 더 많이 필요한 경우가 아니면 로캘 모듈을 사용할 수 있습니다.

  6. ==============================

    6.해답은 이미 훌륭한 일을 한 것 같습니다. 인간 분류에서 비효율적 인 코딩을 지적하고 싶었습니다. 선택적 char-by-char 변환을 유니 코드 문자열 s에 적용하기 위해 다음 코드를 사용합니다.

    해답은 이미 훌륭한 일을 한 것 같습니다. 인간 분류에서 비효율적 인 코딩을 지적하고 싶었습니다. 선택적 char-by-char 변환을 유니 코드 문자열 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의 값은 [ordinal이되어야하는 키가 아닌] 유니 코드 서수, 임의의 유니 코드 문자열 또는 번역의 일부로 해당 문자를 제거하는 None 일 수 있으므로 "ignore a 소트 목적을위한 특정 문자 ","소트 목적을위한 맵 a "등).

    Python 3에서는 "재구성"단계를보다 간단하게 할 수 있습니다 (예 :

    spec_dict = ''.maketrans(spec_dict)
    

    파이썬 3에서이 maketrans 정적 메소드를 사용할 수있는 다른 방법은 문서를 참조하십시오.

  7. ==============================

    7.Perl 라이브러리 모듈, 표준 Unicode :: Collate 모듈의 하위 클래스 인 Unicode :: Collate :: Locale에 대한 콜 아웃을 수행하는 가장 간단하고 쉽고 가장 직접적인 방법입니다. 당신이해야 할 일은 스웨덴의 로캘 값인 "xv"를 생성자에 전달하기 만하면됩니다.

    Perl 라이브러리 모듈, 표준 Unicode :: Collate 모듈의 하위 클래스 인 Unicode :: Collate :: Locale에 대한 콜 아웃을 수행하는 가장 간단하고 쉽고 가장 직접적인 방법입니다. 당신이해야 할 일은 스웨덴의 로캘 값인 "xv"를 생성자에 전달하기 만하면됩니다.

    (당신은 스웨덴어 텍스트에 대해 필연적으로 이것을 고맙게 생각하지 않을 수 있지만 Perl은 추상적 인 문자를 사용하기 때문에 플랫폼이나 빌드와 상관없이 원하는 유니 코드 코드 포인트를 사용할 수 있습니다! 편의를 제공하는 언어는 거의 없습니다. 자바와의 싸움은 최근에이 엄청난 문제를 놓치고 있습니다.)

    문제는 Python에서 Perl 모듈에 액세스하는 방법을 알지 못한다는 것입니다. 즉, 쉘 콜 아웃이나 양면 파이프를 사용하는 것과는 다릅니다. 이를 위해 필자는 ucsort라는 완벽한 작업 스크립트를 제공하여 완벽하게 쉽게 요청한 작업을 수행 할 수 있습니다.

    이 스크립트는 모든 유니 코드 데이터 정렬 알고리즘을 100 % 준수하며 모든 조정 옵션이 지원됩니다! 또한 선택적 모듈을 설치하거나 Perl 5.13 이상을 실행하면 사용하기 쉬운 CLDR 로켈에 모든 권한을 갖게됩니다. 아래를 참조하십시오.

    이 방법으로 정렬 된 입력 집합을 상상해보십시오.

    b o i j n l m å y e v s k h d f g t ö r x p z a ä c u q
    

    코드 포인트 별 기본 정렬은 다음을 산출합니다.

    a b c d e f g h i j k l m n o p q r s t u v x y z ä å ö
    

    모든 사람의 책에 의해 부정확하다. 유니 코드 데이터 정렬 알고리즘을 사용하는 스크립트를 사용하면 다음과 같은 순서로 표시됩니다.

    % perl ucsort /tmp/swedish_alphabet | fmt
    a å ä b c d e f g h i j k l m n o ö p q r s t u v x y z
    

    이것이 기본 UCA 정렬입니다. 스웨덴어 로케일을 얻으려면 다음과 같이 ucsort를 호출하십시오.

    % perl ucsort --locale=sv /tmp/swedish_alphabet | fmt
    a b c d e f g h i j k l m n o p q r s t u v x y z å ä ö
    

    다음은 더 나은 입력 데모입니다. 첫째, 입력 집합 :

    % fmt /tmp/swedish_set
    cTD cDD Cöd Cbd cAD cCD cYD Cud cZD Cod cBD Cnd cQD cFD Ced Cfd cOD
    cLD cXD Cid Cpd cID Cgd cVD cMD cÅD cGD Cqd Cäd cJD Cdd Ckd cÖD cÄD
    Ctd Czd Cxd cHD cND cKD Cvd Chd Cyd cUD Cld Cmd cED Crd Cad Cåd Ccd
    cRD cSD Csd Cjd cPD
    

    코드 포인트에 의해,이 방식으로 정렬됩니다.

    Cad Cbd Ccd Cdd Ced Cfd Cgd Chd Cid Cjd Ckd Cld Cmd Cnd Cod Cpd Cqd
    Crd Csd Ctd Cud Cvd Cxd Cyd Czd Cäd Cåd Cöd cAD cBD cCD cDD cED cFD
    cGD cHD cID cJD cKD cLD cMD cND cOD cPD cQD cRD cSD cTD cUD cVD cXD
    cYD cZD cÄD cÅD cÖD
    

    그러나 기본 UCA를 사용하면 다음과 같이 정렬됩니다.

    % ucsort /tmp/swedish_set | fmt
    cAD Cad cÅD Cåd cÄD Cäd cBD Cbd cCD Ccd cDD Cdd cED Ced cFD Cfd cGD
    Cgd cHD Chd cID Cid cJD Cjd cKD Ckd cLD Cld cMD Cmd cND Cnd cOD Cod
    cÖD Cöd cPD Cpd cQD Cqd cRD Crd cSD Csd cTD Ctd cUD Cud cVD Cvd cXD
    Cxd cYD Cyd cZD Czd
    

    그러나 스웨덴의 로케일에서 이런 식으로 :

    % ucsort --locale=sv /tmp/swedish_set | fmt
    cAD Cad cBD Cbd cCD Ccd cDD Cdd cED Ced cFD Cfd cGD Cgd cHD Chd cID
    Cid cJD Cjd cKD Ckd cLD Cld cMD Cmd cND Cnd cOD Cod cPD Cpd cQD Cqd
    cRD Crd cSD Csd cTD Ctd cUD Cud cVD Cvd cXD Cxd cYD Cyd cZD Czd cÅD
    Cåd cÄD Cäd cÖD Cöd
    

    소문자보다 먼저 소문자를 정렬하려면 다음과 같이하십시오.

    % ucsort --upper-before-lower --locale=sv /tmp/swedish_set | fmt
    Cad cAD Cbd cBD Ccd cCD Cdd cDD Ced cED Cfd cFD Cgd cGD Chd cHD Cid
    cID Cjd cJD Ckd cKD Cld cLD Cmd cMD Cnd cND Cod cOD Cpd cPD Cqd cQD
    Crd cRD Csd cSD Ctd cTD Cud cUD Cvd cVD Cxd cXD Cyd cYD Czd cZD Cåd
    cÅD Cäd cÄD Cöd cÖD
    

    ucsort로 다른 많은 일을 할 수 있습니다. 예를 들어 영어로 제목을 정렬하는 방법은 다음과 같습니다.

    % ucsort --preprocess='s/^(an?|the)\s+//i' /tmp/titles
    Anathem
    The Book of Skulls
    A Civil Campaign
    The Claw of the Conciliator
    The Demolished Man
    Dune
    An Early Dawn
    The Faded Sun: Kesrith
    The Fall of Hyperion
    A Feast for Crows
    Flowers for Algernon
    The Forbidden Tower
    Foundation and Empire
    Foundation’s Edge
    The Goblin Reservation
    The High Crusade
    Jack of Shadows
    The Man in the High Castle
    The Ringworld Engineers
    The Robots of Dawn
    A Storm of Swords
    Stranger in a Strange Land
    There Will Be Time
    The White Dragon
    

    일반적으로 스크립트를 실행하려면 Perl 5.10.1 이상이 필요합니다. 로켈 지원을 위해서는 선택적 CPAN 모듈 인 Unicode :: Collate :: Locale을 설치해야합니다. 또는 모듈을 표준으로 포함하는 Perl, 5.13+의 개발 버전을 설치할 수 있습니다.

    이것은 빠른 프로토 타입이므로 ucsort는 대부분 문서화되어 있지 않습니다. 그러나 이것은 명령 행에서 받아 들일 수있는 스위치 / 옵션의 구문입니다 :

        # standard options
        --help|?
        --man|m
        --debug|d
    
        # collator constructor options
        --backwards-levels=i
        --collation-level|level|l=i
        --katakana-before-hiragana
        --normalization|n=s
        --override-CJK=s
        --override-Hangul=s
        --preprocess|P=s
        --upper-before-lower|u
        --variable=s
    
        # program specific options
        --case-insensitive|insensitive|i
        --input-encoding|e=s
        --locale|L=s
        --paragraph|p
        --reverse-fields|last
        --reverse-output|r
        --right-to-left|reverse-input
    

    그래, 알았어 : Getopt :: Long에 대한 호출에 사용되는 인수 목록이지만 생각은 나옵니다. :)

    Perl 스크립트를 호출하지 않고 직접 Python에서 Perl 라이브러리 모듈을 호출하는 방법을 알아낼 수 있다면 꼭 그렇게하십시오. 나는 단지 나 자신을 모른다. 나는 방법을 배우고 싶다.

    그 동안, 나는이 스크립트가 당신이 필요로하는 것을 모든 일에서 할 것이라고 믿습니다 - 그리고 더! 이제 모든 텍스트 정렬에 이것을 사용합니다. 마침내 내가 오랫동안 필요로했던 것을 마친다.

    유일한 단점은 --locale 인수를 사용하면 일반, 비 로케일이지만 여전히 100 % UCA 호환 정렬에 충분히 빠르지 만 성능이 튜브를 내려 가게됩니다. 메모리에 모든 것을로드하므로 기가비트 문서에이 파일을 사용하고 싶지 않을 것입니다. 나는 하루에도 여러 번 사용하며, 마침내 정돈 된 텍스트 정렬을하는 것이 좋습니다.

  8. ==============================

    8.이것을 구현하려면 "유니 코드 조합 알고리즘" 만나다 http://en.wikipedia.org/wiki/Unicode_collation_algorithm

    이것을 구현하려면 "유니 코드 조합 알고리즘" 만나다 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/

  9. ==============================

    9.요즘 나는이 작업을 위해 zope.ucol (https://pypi.python.org/pypi/zope.ucol)을 사용 해왔다. 예를 들어, 독일어 ß :

    요즘 나는이 작업을 위해 zope.ucol (https://pypi.python.org/pypi/zope.ucol)을 사용 해왔다. 예를 들어, 독일어 ß :

    >>> import zope.ucol
    >>> collator = zope.ucol.Collator("de-de")
    >>> mylist = [u"a", u'x', u'\u00DF']
    >>> print mylist
    [u'a', u'x', u'\xdf']
    >>> print sorted(mylist, key=collator.key)
    [u'a', u'\xdf', u'x']
    

    zope.ucol은 또한 ICU를 랩핑하므로 PyICU의 대안이 될 수 있습니다.

  10. ==============================

    10.제프 앳 우드 (Jeff Atwood)는 Natural Sort Order에 대한 좋은 글을 올렸습니다.

    제프 앳 우드 (Jeff Atwood)는 Natural Sort Order에 대한 좋은 글을 올렸습니다.

    그것은 사소한 스크립트는 아니지만 어떤 방법 으로든, 그것은 트릭을 않습니다.

  11. ==============================

    11.유스 케이스를위한 완벽한 해결책은 아니지만 effbot.org의 unaccent.py 스크립트를 살펴볼 수 있습니다. 기본적으로 텍스트에서 모든 악센트를 제거합니다. 그 'sanitized'텍스트를 사용하여 사전 순으로 정렬 할 수 있습니다. (더 자세한 설명은이 페이지를 참조하십시오.)

    유스 케이스를위한 완벽한 해결책은 아니지만 effbot.org의 unaccent.py 스크립트를 살펴볼 수 있습니다. 기본적으로 텍스트에서 모든 악센트를 제거합니다. 그 'sanitized'텍스트를 사용하여 사전 순으로 정렬 할 수 있습니다. (더 자세한 설명은이 페이지를 참조하십시오.)

  12. from https://stackoverflow.com/questions/1097908/how-do-i-sort-unicode-strings-alphabetically-in-python by cc-by-sa and MIT license