Metode Python API yang mengubah struktur di tempat biasanya mengembalikan None, bukan struktur data yang dimodifikasi.
Jika Anda ingin membuat daftar baru yang diacak secara acak berdasarkan daftar yang sudah ada, di mana daftar yang ada disimpan secara berurutan, Anda dapat menggunakan random.sample()dengan input lengkap:
x = ['foo', 'bar', 'black', 'sheep']
random.sample(x, len(x))
tetapi ini memanggil pengurutan (operasi O (NlogN)), sementara pengambilan sampel ke panjang input hanya membutuhkan operasi O (N) (proses yang sama seperti random.shuffle()yang digunakan, menukar nilai acak dari kumpulan menyusut).
Apakah menggunakan keyfungsi nilai acak benar- benar dijamin? Beberapa algoritme pengurutan cepat gagal jika perbandingan tidak konsisten. Saya dapat melihat ini bekerja dengan cara apa pun, tergantung pada implementasinya (decorate-sort-undecorate hanya perlu diterapkan keysekali pada setiap elemen sehingga akan terdefinisi dengan baik).
torek
2
@torek: Python menggunakan decorate-sort-undecorate saat menyortir dengan keycallable. Jadi ya, itu dijamin karena setiap nilai diberikan kunci acaknya tepat satu kali.
Martijn Pieters
37
Metode ini juga berhasil.
import random
shuffled = random.sample(original, len(original))
Kocok urutan x di tempatnya. Argumen opsional acak adalah fungsi 0-argumen yang mengembalikan float acak di [0.0, 1.0); secara default, ini adalah fungsi random ().
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> shuffle(x)
>>> x
['bar', 'black', 'sheep', 'foo']
shufflemengubah daftar di tempat. Ini bagus, karena menyalin daftar yang besar akan menjadi overhead murni jika Anda tidak memerlukan daftar asli lagi.
2. Gaya pythonic
Menurut prinsip "eksplisit lebih baik daripada implisit" dari gaya pythonic , mengembalikan daftar akan menjadi ide yang buruk, karena kemudian orang mungkin berpikir itu adalah yang baru meskipun pada kenyataannya tidak.
Tapi saya tidak suka seperti ini!
Jika Anda memang membutuhkan daftar baru, Anda harus menulis sesuatu seperti
new_x = list(x) # make a copy
random.shuffle(new_x)
yang sangat eksplisit. Jika Anda sering membutuhkan idiom ini, bungkus dalam fungsi shuffled(lihat sorted) yang mengembalikan new_x.
Anda dapat mengembalikan daftar yang diacak menggunakan random.sample()seperti yang dijelaskan oleh orang lain. Ini bekerja dengan mengambil sampel k elemen dari daftar tanpa penggantian . Jadi jika ada elemen duplikat dalam daftar Anda, mereka akan diperlakukan secara unik.
Jawaban:
random.shuffle()
mengubahx
daftar di tempat .Metode Python API yang mengubah struktur di tempat biasanya mengembalikan
None
, bukan struktur data yang dimodifikasi.Jika Anda ingin membuat daftar baru yang diacak secara acak berdasarkan daftar yang sudah ada, di mana daftar yang ada disimpan secara berurutan, Anda dapat menggunakan
random.sample()
dengan input lengkap:x = ['foo', 'bar', 'black', 'sheep'] random.sample(x, len(x))
Anda juga bisa menggunakan
sorted()
withrandom.random()
untuk kunci penyortiran:shuffled = sorted(x, key=lambda k: random.random())
tetapi ini memanggil pengurutan (operasi O (NlogN)), sementara pengambilan sampel ke panjang input hanya membutuhkan operasi O (N) (proses yang sama seperti
random.shuffle()
yang digunakan, menukar nilai acak dari kumpulan menyusut).Demo:
>>> import random >>> x = ['foo', 'bar', 'black', 'sheep'] >>> random.sample(x, len(x)) ['bar', 'sheep', 'black', 'foo'] >>> sorted(x, key=lambda k: random.random()) ['sheep', 'foo', 'black', 'bar'] >>> x ['foo', 'bar', 'black', 'sheep']
sumber
key
fungsi nilai acak benar- benar dijamin? Beberapa algoritme pengurutan cepat gagal jika perbandingan tidak konsisten. Saya dapat melihat ini bekerja dengan cara apa pun, tergantung pada implementasinya (decorate-sort-undecorate hanya perlu diterapkankey
sekali pada setiap elemen sehingga akan terdefinisi dengan baik).key
callable. Jadi ya, itu dijamin karena setiap nilai diberikan kunci acaknya tepat satu kali.Metode ini juga berhasil.
import random shuffled = random.sample(original, len(original))
sumber
Menurut dokumen :
>>> x = ['foo','bar','black','sheep'] >>> from random import shuffle >>> shuffle(x) >>> x ['bar', 'black', 'sheep', 'foo']
sumber
Kenapa benarkah?
1. Efisiensi
shuffle
mengubah daftar di tempat. Ini bagus, karena menyalin daftar yang besar akan menjadi overhead murni jika Anda tidak memerlukan daftar asli lagi.2. Gaya pythonic
Menurut prinsip "eksplisit lebih baik daripada implisit" dari gaya pythonic , mengembalikan daftar akan menjadi ide yang buruk, karena kemudian orang mungkin berpikir itu adalah yang baru meskipun pada kenyataannya tidak.
Tapi saya tidak suka seperti ini!
Jika Anda memang membutuhkan daftar baru, Anda harus menulis sesuatu seperti
new_x = list(x) # make a copy random.shuffle(new_x)
yang sangat eksplisit. Jika Anda sering membutuhkan idiom ini, bungkus dalam fungsi
shuffled
(lihatsorted
) yang mengembalikannew_x
.sumber
Saya mengalami momen aha saya dengan konsep ini seperti ini:
from random import shuffle x = ['foo','black','sheep'] #original list y = list(x) # an independent copy of the original for i in range(5): print shuffle(y) # shuffles the original "in place" prints "None" return print x,y #prints original, and shuffled independent copy >>> None ['foo', 'black', 'sheep'] ['foo', 'black', 'sheep'] None ['foo', 'black', 'sheep'] ['black', 'foo', 'sheep'] None ['foo', 'black', 'sheep'] ['sheep', 'black', 'foo'] None ['foo', 'black', 'sheep'] ['black', 'foo', 'sheep'] None ['foo', 'black', 'sheep'] ['sheep', 'black', 'foo']
sumber
Python API yang mengubah struktur di tempatnya sendiri mengembalikan None sebagai keluaran.
list = [1,2,3,4,5,6,7,8] print(list)
Keluaran: [1, 2, 3, 4, 5, 6, 7, 8]
from random import shuffle print(shuffle(list))
Output: Tidak Ada
from random import sample print(sample(list, len(list)))
Keluaran: [7, 3, 2, 4, 5, 6, 1, 8]
sumber
Anda dapat mengembalikan daftar yang diacak menggunakan
random.sample()
seperti yang dijelaskan oleh orang lain. Ini bekerja dengan mengambil sampel k elemen dari daftar tanpa penggantian . Jadi jika ada elemen duplikat dalam daftar Anda, mereka akan diperlakukan secara unik.>>> l = [1,4,5,3,5] >>> random.sample(l,len(l)) [4, 5, 5, 3, 1] >>> random.sample(l,len(l)-1) [4, 1, 5, 3] >>> random.sample(l,len(l)-1) [3, 5, 5, 1]
sumber