Apa perbedaan antara sorted(list)
vs list.sort()
?
list.sort
mengubah daftar di tempat & mengembalikan None
sorted
mengambil setiap iterable & mengembalikan daftar baru, disortir.
sorted
setara dengan implementasi Python ini, tetapi fungsi built-in CPython harus berjalan lebih cepat seperti yang tertulis dalam 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
kapan harus menggunakan yang mana?
- Gunakan
list.sort
ketika Anda tidak ingin mempertahankan urutan pengurutan asli (Dengan demikian Anda akan dapat menggunakan kembali daftar di tempat dalam memori.) Dan ketika Anda adalah satu-satunya pemilik daftar (jika daftar dibagi oleh kode lain dan Anda mutasi itu, Anda bisa memperkenalkan bug di mana daftar itu digunakan.)
- Gunakan
sorted
ketika Anda ingin mempertahankan urutan pengurutan asli atau ketika Anda ingin membuat daftar baru yang hanya dimiliki oleh kode lokal Anda.
Bisakah posisi asli daftar diambil setelah list.sort ()?
Tidak - kecuali Anda membuat salinan sendiri, informasi itu hilang karena pengurutan dilakukan di tempat.
"Dan mana yang lebih cepat? Dan seberapa cepat?"
Untuk mengilustrasikan penalti membuat daftar baru, gunakan modul timeit, inilah pengaturan kami:
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
"""
Dan inilah hasil kami untuk daftar 10.000 bilangan bulat yang disusun secara acak, seperti yang dapat kita lihat di sini, kami telah menyangkal mitos biaya pembuatan daftar yang lebih lama :
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]
Setelah beberapa umpan balik, saya memutuskan tes lain akan diinginkan dengan karakteristik berbeda. Di sini saya memberikan daftar 100.000 panjang yang dipesan secara acak yang sama untuk setiap iterasi 1.000 kali.
import timeit
setup = """
import random
random.seed(0)
lst = list(range(100000))
random.shuffle(lst)
"""
Saya menafsirkan perbedaan jenis yang lebih besar ini berasal dari penyalinan yang disebutkan oleh Martijn, tetapi itu tidak mendominasi sampai titik yang dinyatakan dalam jawaban yang lebih lama lebih populer di sini, di sini peningkatan waktu hanya sekitar 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]
Saya juga menjalankan di atas pada jenis yang jauh lebih kecil, dan melihat bahwa sorted
versi salinan baru masih membutuhkan waktu sekitar 2% lebih lama pada 1000 panjang.
Poke juga menjalankan kodenya sendiri, inilah kodenya:
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))
Dia menemukan untuk jenis panjang 1000000, (berlari 100 kali) hasil yang sama, tetapi hanya sekitar 5% peningkatan waktu, inilah hasilnya:
10000000 100
l = next(it); l.sort()
610.5015971539542
l = next(it); sorted(l)
646.7786222379655
Kesimpulan:
Daftar berukuran besar yang disortir dengan sorted
membuat salinan kemungkinan akan mendominasi perbedaan, tetapi penyortiran itu sendiri mendominasi operasi, dan mengatur kode Anda di sekitar perbedaan-perbedaan ini akan menjadi optimasi prematur. Saya akan menggunakan sorted
ketika saya membutuhkan daftar data yang baru disortir, dan saya akan menggunakan list.sort
ketika saya perlu mengurutkan daftar di tempat, dan biarkan yang menentukan penggunaan saya.
sorted()
argumen string tetapi berpikir itu adalah daftar, Anda mendapatkan hasil daftar, bukan string :sorted("abcd", reverse=True)
memberi['d', 'c', 'b', 'a']
tidak"dcba"