วิธีการเรียงลำดับรายการสตริง?


417

วิธีที่ดีที่สุดในการสร้างรายการเรียงตามตัวอักษรใน Python คืออะไร?


1
ใช้localeและเป็นวิธีการเรียงสตริงเพื่อเรียงลำดับตามโลแคลปัจจุบัน
u0b34a0f6ae

คำตอบ:


519

คำตอบพื้นฐาน:

mylist = ["b", "C", "A"]
mylist.sort()

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

for x in sorted(mylist):
    print x

อย่างไรก็ตามตัวอย่างข้างต้นค่อนข้างไร้เดียงสาเพราะไม่คำนึงถึงสถานที่และทำการเรียงลำดับตามตัวพิมพ์ใหญ่ - เล็ก คุณสามารถใช้ประโยชน์จากพารามิเตอร์ทางเลือกkeyเพื่อระบุลำดับการจัดเรียงแบบกำหนดเอง (ทางเลือกโดยใช้cmpเป็นโซลูชันที่เลิกใช้แล้วเนื่องจากต้องมีการประเมินหลายครั้ง - keyคำนวณเพียงหนึ่งครั้งต่อองค์ประกอบ)

ดังนั้นหากต้องการจัดเรียงตามภาษาปัจจุบันให้คำนึงถึงกฎเฉพาะภาษา ( cmp_to_keyเป็นฟังก์ชันผู้ช่วยจาก functools):

sorted(mylist, key=cmp_to_key(locale.strcoll))

และในที่สุดหากคุณต้องการคุณสามารถระบุสถานที่ที่กำหนดเองสำหรับการเรียงลำดับ:

import locale
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') # vary depending on your lang/locale
assert sorted((u'Ab', u'ad', u'aa'),
  key=cmp_to_key(locale.strcoll)) == [u'aa', u'Ab', u'ad']

บันทึกล่าสุด: คุณจะเห็นตัวอย่างของการเรียงลำดับตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ซึ่งใช้lower()วิธีการ - สิ่งเหล่านี้ไม่ถูกต้องเนื่องจากมันทำงานเฉพาะกับชุดย่อยของอักขระ ASCII เท่านั้น ทั้งสองนั้นผิดสำหรับข้อมูลที่ไม่ใช่ภาษาอังกฤษ:

# this is incorrect!
mylist.sort(key=lambda x: x.lower())
# alternative notation, a bit faster, but still wrong
mylist.sort(key=str.lower)

37
mylist.sort(key=str.lower)เร็วกว่า.
jfs

1
จุดดี. ฉันจะทิ้งตัวอย่างปัจจุบันของฉันตามที่เป็นอยู่เพราะอาจเป็นเรื่องง่ายสำหรับผู้เริ่มต้นที่จะเห็นว่าเกิดอะไรขึ้น แต่ฉันจะจำไว้ในอนาคต
Eli Courtwright

1
ถ้าใครอยากรู้อยากเห็นประสิทธิภาพการทำงานของ list.sort () สามารถพบได้ที่นี่
ฮาริ Ganesan

1
@BornToCode: 1- ฉันรู้ว่า ดูการแก้ไข (2008) ความคิดเห็นของฉันตอบกลับ (ความคิดเห็นของฉันเกี่ยวกับการใช้แลมบ์ดาโดยไม่จำเป็น) 2- การเรียงลำดับอักขระที่ไม่ใช่ ASCII เป็นหัวข้อแยกใหญ่ สามารถใช้ PyICUแทนวิธีแก้ไขปัญหาแบบโลแคล
jfs

1
@Dmitry [1, 2, 3].sort()นี้เป็นเพราะคุณกำลังพิมพ์ค่าตอบแทนของฟังก์ชั่นการจัดเรียงที่เรียกว่าใน เนื่องจากsort()เรียงลำดับรายการไว้ (เช่นเปลี่ยนรายการโดยตรง) จะไม่ส่งคืนรายการที่เรียงและจริง ๆ แล้วไม่ส่งคืนสิ่งใดดังนั้นคำสั่งพิมพ์ของคุณจะพิมพ์ออกNoneมา หากคุณบันทึกรายการของคุณเป็นตัวแปรพูดxเรียกx.sort()แล้วprint(x)คุณจะเห็นรายการเรียงลำดับ
bjg222

56

นอกจากนี้ยังเป็นที่น่าสังเกตว่าsorted()ฟังก์ชั่น:

for x in sorted(list):
    print x

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



18

วิธีที่เหมาะสมในการจัดเรียงสตริงคือ:

import locale
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') # vary depending on your lang/locale
assert sorted((u'Ab', u'ad', u'aa'), cmp=locale.strcoll) == [u'aa', u'Ab', u'ad']

# Without using locale.strcoll you get:
assert sorted((u'Ab', u'ad', u'aa')) == [u'Ab', u'aa', u'ad']

ตัวอย่างก่อนหน้านี้ของmylist.sort(key=lambda x: x.lower())จะทำงานได้ดีสำหรับบริบท ASCII เท่านั้น



10

แต่วิธีนี้จัดการกับกฎการเรียงลำดับภาษาเฉพาะได้อย่างไร มันคำนึงถึงสถานที่เกิดเหตุหรือไม่?

ไม่list.sort()เป็นฟังก์ชันการเรียงลำดับทั่วไป หากคุณต้องการเรียงลำดับตามกฎ Unicode คุณจะต้องกำหนดฟังก์ชันคีย์การเรียงลำดับแบบกำหนดเอง คุณสามารถลองใช้โมดูลpyuca ได้แต่ฉันไม่รู้ว่ามันสมบูรณ์แค่ไหน


1

คำถามเก่า ๆ แต่ถ้าคุณต้องการเรียงลำดับตามที่ตั้งไว้โดยไม่ต้องตั้งค่า locale.LC_ALLคุณสามารถทำได้โดยใช้ไลบรารี PyICUตามคำแนะนำนี้ :

import icu # PyICU

def sorted_strings(strings, locale=None):
    if locale is None:
       return sorted(strings)
    collator = icu.Collator.createInstance(icu.Locale(locale))
    return sorted(strings, key=collator.getSortKey)

จากนั้นโทรด้วยเช่น:

new_list = sorted_strings(list_of_strings, "de_DE.utf8")

สิ่งนี้ใช้ได้สำหรับฉันโดยไม่ต้องติดตั้งตำแหน่งที่ตั้งหรือเปลี่ยนแปลงการตั้งค่าระบบอื่น

(นี่เป็นข้อเสนอแนะแล้วในความคิดเห็นข้างต้นแต่ฉันต้องการให้ความโดดเด่นมากขึ้นเพราะฉันคิดถึงตัวเองในตอนแรก)


0

สมมติ s = "ZWzaAd"

ในการจัดเรียงสตริงด้านบนทางออกที่ง่ายจะอยู่ด้านล่าง

print ''.join(sorted(s))

ที่ไม่ได้เป็นรายการของสตริงคุณกำลังเรียงลำดับที่นี่
MNL

0

หรืออาจจะ:

names = ['Jasmine', 'Alberto', 'Ross', 'dig-dog']
print ("The solution for this is about this names being sorted:",sorted(names, key=lambda name:name.lower()))


0

มันง่าย: https://trinket.io/library/trinkets/5db81676e4

scores = '54 - Alice,35 - Bob,27 - Carol,27 - Chuck,05 - Craig,30 - Dan,27 - Erin,77 - Eve,14 - Fay,20 - Frank,48 - Grace,61 - Heidi,03 - Judy,28 - Mallory,05 - Olivia,44 - Oscar,34 - Peggy,30 - Sybil,82 - Trent,75 - Trudy,92 - Victor,37 - Walter'

คะแนน = score.split (',') สำหรับ x ในเรียงลำดับ (คะแนน): พิมพ์ (x)

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