Mengapa random.shuffle
kembali None
dengan Python?
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
Bagaimana cara mendapatkan nilai yang diacak None
?
Mengapa random.shuffle
kembali None
dengan Python?
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
Bagaimana cara mendapatkan nilai yang diacak None
?
Jawaban:
random.shuffle()
mengubah x
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()
with random.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']
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 diterapkan key
sekali pada setiap elemen sehingga akan terdefinisi dengan baik).
key
callable. Jadi ya, itu dijamin karena setiap nilai diberikan kunci acaknya tepat satu kali.
Menurut dokumen :
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']
shuffle
mengubah daftar di tempat. Ini bagus, karena menyalin daftar yang besar akan menjadi overhead murni jika Anda tidak memerlukan daftar asli lagi.
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.
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
.
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']
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]
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]