ฉันจะจัดเรียงสตริง Unicode ตามตัวอักษรใน Python ได้อย่างไร


99

Python เรียงลำดับตามค่าไบต์ตามค่าเริ่มต้นซึ่งหมายความว่าéมาหลัง z และสิ่งอื่น ๆ ที่ตลกพอ ๆ กัน วิธีที่ดีที่สุดในการจัดเรียงตามตัวอักษรใน Python คืออะไร?

มีห้องสมุดสำหรับสิ่งนี้หรือไม่? ฉันไม่พบอะไรเลย การเรียงลำดับควรมีการรองรับภาษาดังนั้นจึงเข้าใจว่าåäöควรเรียงตาม z ในภาษาสวีเดน แต่üควรจัดเรียงตาม u เป็นต้นการสนับสนุน Unicode จึงเป็นข้อกำหนดค่อนข้างมาก

หากไม่มีห้องสมุดจะทำอย่างไรดีที่สุด เพียงแค่ทำการแมปจากตัวอักษรเป็นค่าจำนวนเต็มและแมปสตริงกับรายการจำนวนเต็มด้วยสิ่งนั้น


11
โปรดทราบว่าสิ่งนี้ขึ้นอยู่กับภาษามากขึ้น: ในภาษาสวีเดน (ตามที่คุณระบุ) "Ä" ตามหลัง "Z" แต่ในภาษาเยอรมัน "Ä" มักจะจัดเรียงเป็น "AE"
balpha

@Georg: มีเหตุผลที่คุณเปิดรับรางวัลนี้หรือไม่? locale.strcollคำตอบที่ถูกต้องเมื่อคุณต้องการ Unicode เรียงลำดับโดยใช้สถานที่ของผู้ใช้และคำตอบที่ห้องไอซียูในสิ่งที่คุณต้องการเมื่อคุณจำเป็นต้องมากกว่านั้น (เรียงใช้มากกว่าหนึ่งสถานที่) locale.strcollส่วนใหญ่เวลาที่คุณต้องการ
Glenn Maynard

@Glenn: ฉันอยากรู้ว่าICUlocale.strcollทำงานได้ดีแค่ไหนและโดยเฉพาะอย่างยิ่งสิ่งที่ICUทำได้ดีกว่าฟังก์ชัน Python โดยทั่วไปให้ความสนใจมากขึ้นสำหรับคำถาม
Georg Schölly

1
@Georg: ช่วงนี้ฉันเล่น Unicode Collation Algorithm บ่อยมากอย่างที่คุณเห็นจากคำตอบของฉัน เป็นสิ่งที่ยอดเยี่ยมอย่างแท้จริงที่สามารถจัดเรียง--locale=de__phonebookเมื่อคุณต้องการ โมดูล Perl ผ่านชุดทดสอบ UCA และสคริปต์ที่ฉันให้มาช่วยให้เล่นกับ UCA ทั้งหมดได้ง่ายขึ้นมากรวมทั้งตัวเลือกทั้งหมดรวมถึงโลแคลเพียงจากบรรทัดคำสั่ง อาจจะไม่ตอบคำถาม แต่ก็ยังควรจะเป็นที่น่าสนใจอย่างมาก หากคุณอยู่ในสวิตเซอร์แลนด์ฉันมั่นใจว่าคุณสามารถใช้ความยืดหยุ่นได้ :)
tchrist

คำตอบ:


75

ห้องสมุดICUของ IBM ทำเช่นนั้น (และอื่น ๆ อีกมากมาย) แต่ก็มีการผูกหลาม: PyICU

ปรับปรุง : ความแตกต่างหลักในการคัดแยกระหว่างห้องไอซียูและlocale.strcollเป็นที่ห้องไอซียูใช้เต็มรูปแบบเปรียบเทียบ Unicode ขั้นตอนวิธีการในขณะที่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 2 และ Python 3 หรือไม่ ฉันใช้locale.strxfrmจากคำตอบของ u0b34a0f6ae และดูเหมือนว่าจะใช้งานได้และดูหรูหรากว่ามากและไม่ต้องใช้ซอฟต์แวร์เพิ่มเติม
สุภา

ใช้งานกับ Python3 ไม่ได้สำหรับฉันsudo pip3 install PyICUติดตั้งไม่สำเร็จและสำหรับ Python2
imrek

ฉันต้องติดตั้ง libicu-devel.x86_64 สำหรับ pyICU เพื่อรวบรวมและติดตั้งจาก Pip ใช้งานได้แม้ว่าผลลัพธ์จากคำสั่ง 'sorted' สุดท้ายคือ: ['a', '\ xc3 \ xa4', 'b', 'c']
Mike Stoddart

54

ฉันไม่เห็นสิ่งนี้ในคำตอบ แอปพลิเคชันของฉันจัดเรียงตามโลแคลโดยใช้ไลบรารีมาตรฐานของ 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 และผู้ตอบคำถามคนอื่น ๆ : ไม่มีใครรู้จัก 'locale' หรือว่ามันไม่ได้ขึ้นอยู่กับงานนี้?


โดยวิธีที่ 1) ฉันไม่คิดว่า locale.strxfrm เสียสำหรับ UTF-8 ที่เข้ารหัส `` str '; ฉันเปรียบเทียบโดยแอปพลิเคชันและสรุปได้ว่าการใช้ cmp = strcoll บนอ็อบเจ็กต์ Unicode นั้นถูกกว่าการถอดรหัสทั้งหมดเป็น UTF-8 และใช้ key = strxfrm
u0b34a0f6ae

6
2) โมดูลโลแคลจะทำงานกับโลแคลที่คุณสร้างขึ้นเท่านั้น (สำหรับกล่อง Linux) ไม่ใช่โลแคลใด ๆ "locale -a" จะบอกคุณว่า
u0b34a0f6ae

6
@Georg: ฉันเชื่อว่าโลแคลรองรับเฉพาะการแมปสตริงย่อย -> collating_element เท่านั้น ไม่จัดการสิ่งต่างๆเช่นการขยาย (æจัดเรียงเป็น "ae") การจัดเรียงสำเนียงฝรั่งเศส (ตัวอักษรเรียงจากซ้ายไปขวา แต่เน้นจากขวาไปซ้าย) การจัดเรียงใหม่และอาจมีอีกสองสามอย่าง ดูรายละเอียดที่นี่ (ชุดคุณลักษณะ UCA แบบเต็ม): unicode.org/reports/tr10และที่นี่ (การเปรียบเทียบตำแหน่ง): chm.tu-dresden.de/edv/manuals/aix/files/aixfiles/LC_COLLATE.htm
Rafał Dowgird

3
เพื่อที่จะตอบได้อย่างชัดเจนคำถาม: ใช่มันเป็นขึ้นอยู่กับงาน เห็นได้ชัดว่ามีบางกรณีพิเศษที่ Unicode Collation Algorithm ที่สมบูรณ์จะจัดการได้ดีกว่า แต่ถ้าคุณไม่ทราบแล้วคุณจะไม่สังเกตเห็นโอกาสนั้น
Lennart Regebro

1
ปัญหาใหญ่ที่สุดคือคุณต้องตั้งค่าภาษาทั่วโลกสำหรับแอปพลิเคชันทั้งหมด - คุณไม่สามารถมีไว้เพื่อเปรียบเทียบในมือได้
Robert Siemer

9

ลองเจมส์โตเบอร์ของงูหลามเปรียบเทียบ Unicode อัลกอริทึม อาจไม่ตรงตามที่คุณต้องการ แต่ก็คุ้มค่าที่จะดู สำหรับข้อมูลเพิ่มเติมเกี่ยวกับปัญหาโปรดดูโพสต์นี้โดย Christopher Lenz


อย่างน้อยก็ช่วยแก้ไขปัญหาทั่วไปได้ ฉันเดาว่าอาจมีการสร้างรายการเปรียบเทียบเวอร์ชันที่ละเอียดอ่อนทางภาษาด้วย
Lennart Regebro

สิ่งนี้ไม่อนุญาตให้คุณระบุโลแคลและไฟล์กำหนดค่าอ้างอิงทำให้เกิด ValueError
thebjorn

8

คุณอาจสนใจpyuca :

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

แม้ว่าจะไม่ใช่วิธีที่แน่นอนที่สุด แต่ก็เป็นวิธีที่ง่ายมากอย่างน้อยก็ทำให้ถูกต้อง นอกจากนี้ยังเต้นโลแคลในเว็บแอปเนื่องจากโลแคลไม่ปลอดภัยและตั้งค่าภาษาทั้งกระบวนการ นอกจากนี้ยังตั้งค่าได้ง่ายกว่า PyICU ซึ่งอาศัยไลบรารี C ภายนอก

ฉันอัปโหลดสคริปต์ไปยัง github เนื่องจากต้นฉบับหยุดทำงานในขณะที่เขียนนี้และฉันต้องใช้เว็บแคชเพื่อรับมัน:

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

ฉันใช้สคริปต์นี้เพื่อจัดเรียงข้อความภาษาเยอรมัน / ฝรั่งเศส / อิตาลีในโมดูล plone ได้สำเร็จ


+1 สำหรับ pyuca ค่อนข้างเร็ว (3 วินาทีในการเรียง 28000 คำ) เป็น python ที่บริสุทธิ์และไม่ต้องพึ่งพา
michaelmeyer

7

สรุปและคำตอบเพิ่มเติม:

locale.strcollภายใต้ Python 2 และlocale.strxfrmในความเป็นจริงจะแก้ปัญหาและทำงานได้ดีโดยสมมติว่าคุณติดตั้งโลแคลที่เป็นปัญหาแล้ว ฉันทดสอบภายใต้ Windows ด้วยเช่นกันซึ่งชื่อภาษาต่างกันอย่างสับสน แต่ในทางกลับกันดูเหมือนว่าจะมีภาษาทั้งหมดที่รองรับการติดตั้งโดยค่าเริ่มต้น

ICUไม่จำเป็นต้องทำสิ่งนี้ให้ดีขึ้นในทางปฏิบัติ แต่ก็ทำได้มากกว่านี้นี้ ที่โดดเด่นที่สุดคือรองรับตัวแยกที่สามารถแยกข้อความในภาษาต่างๆออกเป็นคำได้ สิ่งนี้มีประโยชน์มากสำหรับภาษาที่ไม่มีตัวคั่นคำ คุณจะต้องมีคลังคำเพื่อใช้เป็นฐานในการแยกเนื่องจากไม่รวมอยู่ด้วย

นอกจากนี้ยังมีชื่อที่ยาวสำหรับสถานที่เพื่อให้คุณสามารถรับชื่อที่แสดงสำหรับภาษาได้อย่างสวยงามรองรับปฏิทินอื่นที่ไม่ใช่แบบเกรกอเรียน (แม้ว่าฉันจะไม่แน่ใจว่าอินเทอร์เฟซ Python รองรับสิ่งนั้น) และโลแคลที่คลุมเครืออื่น ๆ อีกมากมายหรือน้อยกว่านั้นรองรับ .

สรุปทั้งหมด:หากคุณต้องการเรียงลำดับตามตัวอักษรและตามสถานที่คุณสามารถใช้localeโมดูลนี้ได้เว้นแต่คุณจะมีข้อกำหนดพิเศษหรือต้องการฟังก์ชันที่ขึ้นกับโลแคลเพิ่มเติมเช่นตัวแยกคำ


6

ผมเห็นคำตอบที่ได้ทำมาแล้วงานที่ยอดเยี่ยมเพียงแค่อยากจะชี้ให้เห็นหนึ่งขาดประสิทธิภาพในการเข้ารหัสมนุษย์เรียง ในการใช้การแปล char-by-char แบบเลือกกับสตริง unicode s จะใช้รหัส:

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

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

Python มีวิธีที่ดีกว่าเร็วกว่าและรัดกุมกว่ามากในการทำงานเสริมนี้ (บนสตริง Unicode - วิธีการที่คล้ายคลึงกันสำหรับสตริงไบต์มีข้อกำหนดที่แตกต่างกันและค่อนข้างเป็นประโยชน์น้อยกว่า! -):

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

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

คำสั่งที่คุณส่งผ่านไปยังtranslateเมธอดนั้นมีลำดับ Unicode (ไม่ใช่สตริง) เป็นคีย์ซึ่งเป็นเหตุผลว่าทำไมเราถึงต้องการขั้นตอนการสร้างใหม่จาก char-to-char ดั้งเดิมspec_dictดั้งเดิม (ค่าในคำสั่งที่คุณส่งไปแปล [ตรงข้ามกับคีย์ซึ่งต้องเป็นลำดับ) อาจเป็นลำดับ Unicode สตริง Unicode ตามอำเภอใจหรือไม่มีเพื่อลบอักขระที่เกี่ยวข้องออกเป็นส่วนหนึ่งของการแปลดังนั้นจึงเป็นเรื่องง่ายที่จะระบุ "ละเว้น a อักขระบางตัวเพื่อวัตถุประสงค์ในการจัดเรียง "," แมปäถึง ae เพื่อวัตถุประสงค์ในการจัดเรียง "และอื่น ๆ )

ใน Python 3 คุณสามารถรับขั้นตอน "สร้างใหม่" ได้ง่ายขึ้นเช่น:

spec_dict = ''.maketrans(spec_dict)

ดูเอกสารสำหรับวิธีอื่น ๆ ที่คุณสามารถใช้maketransวิธีการคงที่นี้ใน Python 3


วิธีนี้ดี แต่ไม่อนุญาตให้คุณวางáระหว่าง az และ b
Barney Szabolcs


1

เมื่อเร็ว ๆ นี้ฉันใช้ 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


1

โซลูชัน UCA ที่สมบูรณ์

วิธีที่ง่ายที่สุดง่ายที่สุดและตรงไปตรงมาที่สุดในการสร้างคำบรรยายภาพไปยังโมดูลไลบรารี Perl Unicode :: Collate :: Localeซึ่งเป็นคลาสย่อยของโมดูลUnicode :: Collateมาตรฐาน สิ่งที่คุณต้องทำคือส่งตัวสร้างค่าโลแคล"xv"สำหรับสวีเดน

(คุณอาจไม่จำเป็นต้องชื่นชมสิ่งนี้สำหรับข้อความภาษาสวีเดน แต่เนื่องจาก Perl ใช้อักขระนามธรรมคุณสามารถใช้จุดรหัส Unicode ใดก็ได้ที่คุณต้องการไม่ว่าจะเป็นแพลตฟอร์มหรือสร้างก็ตามมีภาษาไม่กี่ภาษาที่ให้ความสะดวกเช่นนี้ฉันพูดถึงเพราะฉันต่อสู้กับ สูญเสียการต่อสู้กับ Java เป็นจำนวนมากสำหรับปัญหาที่น่าสยดสยองเมื่อเร็ว ๆ นี้)

ปัญหาคือฉันไม่ทราบวิธีเข้าถึงโมดูล Perl จาก Python - นอกเหนือจากการใช้คำบรรยายภาพเชลล์หรือท่อสองด้าน ด้วยเหตุนี้ฉันจึงได้จัดเตรียมสคริปต์การทำงานที่เรียกว่าucsortที่คุณสามารถเรียกใช้เพื่อทำสิ่งที่คุณขอได้อย่างง่ายดาย

สคริปต์นี้สอดคล้อง 100% กับUnicode Collation Algorithmแบบเต็มตัวเลือกการปรับแต่งทั้งหมดที่รองรับ !! และหากคุณติดตั้งโมดูลเสริมหรือรัน 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 ä å ö

ซึ่งไม่ถูกต้องตามหนังสือของทุกคน การใช้สคริปต์ของฉันซึ่งใช้ Unicode Collation Algorithm คุณจะได้รับคำสั่งนี้:

% 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 หรือดีกว่าเพื่อเรียกใช้สคริปต์โดยทั่วไป Unicode::Collate::Localeสำหรับการสนับสนุนสถานที่คุณอาจต้องติดตั้งโมดูล CPAN ตัวเลือก หรือคุณสามารถติดตั้ง Perl เวอร์ชันพัฒนา 5.13+ ซึ่งรวมถึงโมดูลนั้นได้ตามมาตรฐาน

การเรียกประชุม

นี่คือต้นแบบที่รวดเร็วดังนั้นucsortส่วนใหญ่จึงมีการจัดทำเป็นเอกสาร แต่นี่คือ SYNOPSIS ของสวิตช์ / ตัวเลือกที่ยอมรับในบรรทัดคำสั่ง:

    # 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อาร์กิวเมนต์ทำให้ประสิทธิภาพลดลงแม้ว่าจะเร็วพอสำหรับการเรียงลำดับปกติที่ไม่ใช่ภาษาแต่ก็ยังคงเป็นไปตามมาตรฐาน UCA 100% เนื่องจากโหลดทุกอย่างในหน่วยความจำคุณอาจไม่ต้องการใช้สิ่งนี้กับเอกสารกิกะไบต์ ฉันใช้มันหลายครั้งต่อวันและแน่ใจว่าการเรียงลำดับข้อความที่ดีในที่สุด


2
ทำไมคุณถึงเรียกสคริปต์ Perl บนโลกเพื่อทำบางสิ่งที่มีไลบรารี Python สำหรับ?
Lennart Regebro

2
เพราะผมไม่ได้รู้ว่ามีเป็นห้องสมุดงูใหญ่ว่าทำไม!
tchrist

@ Lennart: ฉันชอบไลบรารีเนทีฟจริงๆหรืออย่างมากก็คือไลบรารีที่เชื่อมโยงกับ C API และโหลดแบบไดนามิก (ซึ่งบางครั้งคุณต้องการ) ฉันไม่พบโซลูชัน PyPerl และ Inline :: Perl ต่างๆที่น่าเชื่อถือหรือแข็งแกร่งหรือยืดหยุ่น หรือบางสิ่งบางอย่าง. พวกเขารู้สึกไม่ถูกต้องด้วยเหตุผลบางประการ ฉันลองสิ่งนี้ครั้งล่าสุดเมื่อฉันต้องการการตรวจจับชาร์ตที่ดี (ซึ่งฉันไม่เคยได้รับเลย)
tchrist

4
การใช้ Perl ภายใน Python เป็นเพียงการเสพติด
Utku Zihnioglu

1
ว้าว. ใช่ - ดูเหมือน Perl สำหรับฉันจริงๆแล้วเราเห็นว่าตอนนี้มีมากกว่าสองวิธีในการทำสิ่งต่างๆ :) แต่การเรียก C จาก Python โดยทั่วไปไม่ได้หมายความถึงประเภทของการอ้างอิงที่เพิ่มเข้ามาและปัญหาการสนับสนุนในทางปฏิบัติที่เรียก Perl ดังนั้นมัน ยากมากที่จะเห็นการเรียกร้องให้ทำเช่นนี้
nealmcb

0

มันยังห่างไกลจากโซลูชันที่สมบูรณ์สำหรับกรณีการใช้งานของคุณ แต่คุณสามารถดูสคริปต์unaccent.pyจาก effbot.org สิ่งที่ทำโดยทั่วไปคือลบสำเนียงทั้งหมดออกจากข้อความ คุณสามารถใช้ข้อความ 'ฆ่าเชื้อ' เพื่อจัดเรียงตามตัวอักษร (สำหรับคำอธิบายที่ดีเห็นนี้หน้า.)


0

Jeff Atwood เขียนโพสต์ที่ดีเกี่ยวกับNatural Sort Orderในนั้นเขาเชื่อมโยงกับสคริปต์ที่ทำสิ่งที่คุณถามได้ดีทีเดียวได้ดีทีเดียว

ไม่ใช่สคริปต์ที่ไม่สำคัญไม่ว่าจะด้วยวิธีใด ๆ แต่เป็นการหลอกลวง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.