Apa perbedaan antara `diurutkan (daftar)` vs `list.sort ()`?

194

list.sort()mengurutkan daftar dan mengganti daftar asli, sedangkan sorted(list)mengembalikan salinan daftar yang diurutkan, tanpa mengubah daftar asli.

  • Kapan satu lebih disukai daripada yang lain?
  • Mana yang lebih efisien? Seberapa banyak?
  • Bisakah daftar dikembalikan ke status tidak disortir setelah list.sort()dilakukan?
alva
sumber
4
Waspadalah jika Anda (secara tidak sengaja) memanggil 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"
smci

Jawaban:

316

sorted()mengembalikan daftar diurutkan baru , meninggalkan daftar asli tidak terpengaruh. list.sort()mengurutkan daftar di tempat , memutasikan indeks daftar, dan mengembalikan None(seperti semua operasi di tempat).

sorted()bekerja pada semua iterable, bukan hanya daftar. String, tuple, kamus (Anda akan mendapatkan kunci), generator, dll., Mengembalikan daftar yang berisi semua elemen, diurutkan.

  • Gunakan list.sort()saat Anda ingin mengubah daftar, sorted()saat Anda ingin objek yang diurutkan kembali. Gunakan sorted()ketika Anda ingin mengurutkan sesuatu yang merupakan iterable, bukan daftar belum .

  • Untuk daftar, list.sort()lebih cepat daripada sorted()karena tidak harus membuat salinan. Untuk pilihan lain, Anda tidak punya pilihan.

  • Tidak, Anda tidak dapat mengambil posisi semula. Setelah Anda menelepon list.sort(), orde asli hilang.

Martijn Pieters
sumber
6
Secara umum, ketika fungsi python kembali None, itu adalah tanda, bahwa operasi dilakukan di tempat, itu sebabnya, ketika Anda ingin mencetaknya list.sort()mengembalikan Tidak ada.
user1767754
45

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.sortketika 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 sortedketika 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 sortedversi 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 sortedmembuat 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 sortedketika saya membutuhkan daftar data yang baru disortir, dan saya akan menggunakan list.sortketika saya perlu mengurutkan daftar di tempat, dan biarkan yang menentukan penggunaan saya.

Aaron Hall
sumber
4
Pengaturan generator bagus, tapi saya tidak akan menarik kesimpulan bahwa Anda merusak mitos terlalu cepat. Fakta tetap bahwa sorted()harus mengalokasikan objek daftar baru dan menyalin referensi; sisa jalur kode identik. Lihat apakah Anda dapat menjalankan tes yang sama dengan daftar yang lebih besar. Bandingkan dengan hanya membuat salinan daftar dan lihat apakah Anda dapat meniru perbedaan yang Anda temukan, dll.
Martijn Pieters
11

Perbedaan utama adalah bahwa sorted(some_list)mengembalikan yang barulist :

a = [3, 2, 1]
print sorted(a) # new list
print a         # is not modified

dan some_list.sort(), urutkan daftar di tempat :

a = [3, 2, 1]
print a.sort() # in place
print a         # it's modified

Perhatikan bahwa karena a.sort()tidak mengembalikan apa pun, print a.sort()akan dicetak None.


Bisakah daftar posisi asli diambil setelah list.sort ()?

Tidak, karena memodifikasi daftar asli.

Kristen
sumber
1
print a.sort()tidak akan mencetak apa pun.
Burhan Khalid
1
Akan dicetak None, saya akan mengklarifikasi itu.
Christian
1

Fungsi .sort () menyimpan nilai daftar baru secara langsung dalam variabel daftar; jadi jawaban untuk pertanyaan ketiga Anda adalah TIDAK. Juga jika Anda melakukan ini menggunakan diurutkan (daftar), maka Anda bisa menggunakannya karena tidak disimpan dalam variabel daftar. Kadang-kadang metode .sort () berfungsi sebagai fungsi, atau mengatakan bahwa dibutuhkan argumen di dalamnya.

Anda harus menyimpan nilai yang diurutkan (daftar) dalam variabel secara eksplisit.

Juga untuk pemrosesan data singkat kecepatan tidak akan memiliki perbedaan; tetapi untuk daftar panjang; Anda harus langsung menggunakan metode .sort () untuk pekerjaan cepat; tetapi sekali lagi Anda akan menghadapi tindakan yang tidak dapat diubah.

Vicrobot
sumber
"Fungsi .sort () menyimpan nilai daftar baru secara langsung dalam variabel daftar" Hah? Daftar baru apa? Tidak ada daftar baru. The list.sort()metode mengurutkan daftar objek di tempat.
PM 2Ring
Juga, apa artinya ini? "Kadang-kadang metode .sort () berfungsi sebagai fungsi, atau mengatakan bahwa dibutuhkan argumen di dalamnya."
PM 2Ring
Yang saya maksud dengan daftar baru adalah daftar yang dimodifikasi dan .sort () hanya menyimpan daftar yang diubah ke dalam variabel yang sama.
Vicrobot
Ya, terkadang .sort()metode mengambil argumen, dan bertindak sebagai fungsi. Kami juga menyebutnya metode karena merupakan atribut dari tipe data daftar.
Vicrobot
Jika ada semacam kesalahan dalam konsep saya kemudian katakan, saya akan mencarinya dan akan meningkatkan konsep saya, dan jawaban saya juga. Terima kasih
Vicrobot
1

Berikut adalah beberapa contoh sederhana untuk melihat perbedaan dalam tindakan:

Lihat daftar angka di sini:

nums = [1, 9, -3, 4, 8, 5, 7, 14]

Saat memanggil sorteddaftar ini, sortedakan membuat salinan daftar. (Artinya daftar asli Anda akan tetap tidak berubah.)

Ayo lihat.

sorted(nums)

kembali

[-3, 1, 4, 5, 7, 8, 9, 14]

Melihat numslagi

nums

Kami melihat daftar asli (tidak diubah dan TIDAK diurutkan.) sortedtidak mengubah daftar asli

[1, 2, -3, 4, 8, 5, 7, 14]

Mengambil numsdaftar yang sama dan menerapkan sortfungsi di atasnya, akan mengubah daftar yang sebenarnya.

Ayo lihat.

Dimulai dengan numsdaftar kami untuk memastikan, kontennya masih sama.

nums

[-3, 1, 4, 5, 7, 8, 9, 14]

nums.sort()

Sekarang daftar num asli diubah dan melihat num kita melihat daftar asli kita telah berubah dan sekarang disortir.

nums
[-3, 1, 2, 4, 5, 7, 8, 14]
Stryker
sumber
Terima kasih telah menunjukkan salinan asli vs. salinan secara lebih mendalam
Brendan Metcalfe
0

Catatan: Perbedaan paling sederhana antara sort () dan sortir () adalah: sort () tidak mengembalikan nilai apa pun, disortir () mengembalikan daftar iterable.

sort () tidak mengembalikan nilai apa pun.

Metode sort () hanya mengurutkan elemen daftar yang diberikan dalam urutan tertentu - Naik atau Turun tanpa mengembalikan nilai.

Sintaks metode sort () adalah:

list.sort(key=..., reverse=...)

Atau, Anda juga dapat menggunakan fungsi bawaan Python yang diurutkan () untuk tujuan yang sama. fungsi diurutkan mengembalikan daftar diurutkan

 list=sorted(list, key=..., reverse=...)
Projesh Bhoumik
sumber