ข้อแตกต่างระหว่างsorted(list)
vs list.sort()
คืออะไร?
list.sort
ปิดท้ายรายการและส่งคืน None
sorted
ใช้ซ้ำได้และส่งคืนรายการใหม่เรียงลำดับ
sorted
เทียบเท่ากับการใช้งาน Python นี้ แต่ฟังก์ชั่น CPython ในตัวควรรันได้เร็วขึ้นอย่างรวดเร็วตามที่เขียนไว้ใน C:
def sorted(iterable, key=None):
new_list = list(iterable) # make a new list
new_list.sort(key=key) # sort it
return new_list # return it
จะใช้เมื่อใด
- ใช้
list.sort
เมื่อคุณไม่ต้องการรักษาลำดับการจัดเรียงดั้งเดิม (ดังนั้นคุณจะสามารถนำรายการกลับมาใช้ซ้ำได้ในหน่วยความจำ) และเมื่อคุณเป็นเจ้าของรายการ แต่เพียงผู้เดียว (หากมีการแบ่งปันรายการด้วยรหัสอื่นและคุณ การกลายพันธุ์คุณสามารถแนะนำบั๊กที่ใช้รายการนั้น)
- ใช้
sorted
เมื่อคุณต้องการรักษาลำดับการจัดเรียงดั้งเดิมหรือเมื่อคุณต้องการสร้างรายการใหม่ที่มีเฉพาะรหัสท้องถิ่นของคุณ
สามารถดึงตำแหน่งดั้งเดิมของรายการหลังจาก list.sort () ได้หรือไม่?
ไม่ - ถ้าคุณทำสำเนาด้วยตัวเองข้อมูลนั้นจะหายไปเนื่องจากการเรียงลำดับเสร็จสิ้นแล้ว
"และอันไหนเร็วกว่ากันและเร็วเท่าไหร่"
เพื่อแสดงให้เห็นถึงการลงโทษในการสร้างรายการใหม่ให้ใช้โมดูล timeit นี่คือการตั้งค่าของเรา:
import timeit
setup = """
import random
lists = [list(range(10000)) for _ in range(1000)] # list of lists
for l in lists:
random.shuffle(l) # shuffle each list
shuffled_iter = iter(lists) # wrap as iterator so next() yields one at a time
"""
และนี่คือผลลัพธ์ของเราสำหรับรายการของการจัดเรียงแบบสุ่ม 10,000 จำนวนเต็มตามที่เราเห็นที่นี่เราพิสูจน์หักล้างตำนานค่าใช้จ่ายในการสร้างรายการแบบเก่า :
Python 2.7
>>> timeit.repeat("next(shuffled_iter).sort()", setup=setup, number = 1000)
[3.75168503401801, 3.7473005310166627, 3.753129180986434]
>>> timeit.repeat("sorted(next(shuffled_iter))", setup=setup, number = 1000)
[3.702025591977872, 3.709248117986135, 3.71071034099441]
Python 3
>>> timeit.repeat("next(shuffled_iter).sort()", setup=setup, number = 1000)
[2.797430992126465, 2.796825885772705, 2.7744789123535156]
>>> timeit.repeat("sorted(next(shuffled_iter))", setup=setup, number = 1000)
[2.675589084625244, 2.8019039630889893, 2.849375009536743]
หลังจากข้อเสนอแนะบางอย่างฉันตัดสินใจว่าการทดสอบอื่นจะเป็นที่น่าพอใจด้วยคุณสมบัติที่แตกต่าง ที่นี่ฉันให้รายการเรียงลำดับแบบสุ่มที่มีความยาว 100,000 รายการสำหรับการวนซ้ำแต่ละครั้ง 1,000 ครั้ง
import timeit
setup = """
import random
random.seed(0)
lst = list(range(100000))
random.shuffle(lst)
"""
ฉันตีความความแตกต่างของการเรียงลำดับที่ใหญ่กว่านี้ซึ่งมาจากการคัดลอกที่กล่าวถึงโดย Martijn แต่มันไม่ได้ครองจุดที่ระบุไว้ในคำตอบที่ได้รับความนิยมมากกว่าเก่าที่นี่เวลาเพิ่มขึ้นเพียง 10%
>>> timeit.repeat("lst[:].sort()", setup=setup, number = 10000)
[572.919036605, 573.1384446719999, 568.5923951]
>>> timeit.repeat("sorted(lst[:])", setup=setup, number = 10000)
[647.0584738299999, 653.4040515829997, 657.9457361929999]
ฉันยังวิ่งไปด้านบนในประเภทที่เล็กกว่ามากและเห็นว่าsorted
รุ่นสำเนาใหม่ยังคงใช้เวลาทำงานนานขึ้นประมาณ 2% ในความยาว 1,000 เท่า
Poke ใช้รหัสของเขาเองเช่นกันนี่คือรหัส:
setup = '''
import random
random.seed(12122353453462456)
lst = list(range({length}))
random.shuffle(lst)
lists = [lst[:] for _ in range({repeats})]
it = iter(lists)
'''
t1 = 'l = next(it); l.sort()'
t2 = 'l = next(it); sorted(l)'
length = 10 ** 7
repeats = 10 ** 2
print(length, repeats)
for t in t1, t2:
print(t)
print(timeit(t, setup=setup.format(length=length, repeats=repeats), number=repeats))
เขาค้นหาความยาว 1000000 เรียง (วิ่ง 100 ครั้ง) ผลลัพธ์ที่คล้ายกัน แต่เพิ่มขึ้นเพียง 5% ในเวลานี่คือผลลัพธ์:
10000000 100
l = next(it); l.sort()
610.5015971539542
l = next(it); sorted(l)
646.7786222379655
สรุป:
รายการขนาดใหญ่ที่เรียงลำดับด้วยsorted
การทำสำเนาอาจมีอิทธิพลเหนือความแตกต่าง แต่การเรียงลำดับจะควบคุมการดำเนินการและการจัดระเบียบรหัสของคุณเกี่ยวกับความแตกต่างเหล่านี้จะเป็นการปรับให้เหมาะสมก่อนกำหนด ฉันจะใช้sorted
เมื่อฉันต้องการรายการที่เรียงลำดับใหม่ของข้อมูลและฉันจะใช้list.sort
เมื่อฉันต้องการเรียงลำดับรายการในสถานที่และให้ที่กำหนดการใช้งานของฉัน
sorted()
อาร์กิวเมนต์ string แต่คิดว่าเป็นรายการคุณจะได้รับรายการผลลัพธ์ไม่ใช่สตริง :sorted("abcd", reverse=True)
ให้['d', 'c', 'b', 'a']
ไม่ใช่"dcba"