Asumsikan saya memiliki daftar berikut:
foo = ['a', 'b', 'c', 'd', 'e']
Apa cara paling sederhana untuk mengambil item secara acak dari daftar ini?
Menggunakan random.choice()
import random
foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))
Untuk pilihan acak yang aman secara kriptografis (mis. Untuk membuat frasa sandi dari daftar kata) gunakansecrets.choice()
import secrets
foo = ['battery', 'correct', 'horse', 'staple']
print(secrets.choice(foo))
secrets
baru dalam Python 3.6, pada Python versi lama Anda bisa menggunakan random.SystemRandom
kelas:
import random
secure_random = random.SystemRandom()
print(secure_random.choice(foo))
random.choice(foo)
menghasilkan dua hasil yang berbeda?random.sample(lst, n)
Standard pseudo-random generators are not suitable for security/cryptographic purposes.
refJika Anda ingin secara acak memilih lebih dari satu item dari daftar, atau memilih item dari set, saya akan merekomendasikan menggunakan
random.sample
sebagai gantinya.Jika Anda hanya menarik satu item dari daftar, pilihannya kurang kikuk, karena menggunakan sampel akan memiliki sintaks
random.sample(some_list, 1)[0]
sebagai gantirandom.choice(some_list)
.Sayangnya, pilihan hanya berfungsi untuk satu output dari urutan (seperti daftar atau tupel). Meskipun
random.choice(tuple(some_set))
mungkin menjadi opsi untuk mendapatkan satu item dari set.EDIT: Menggunakan Rahasia
Seperti yang telah ditunjukkan oleh banyak orang, jika Anda memerlukan sampel pseudorandom yang lebih aman, Anda harus menggunakan modul rahasia:
EDIT: Pythonic One-Liner
Jika Anda menginginkan satu baris yang lebih pythonic untuk memilih beberapa item, Anda dapat menggunakan pembongkaran.
sumber
secrets
Modul BTW telah ditambahkan ke pustaka standar Python di versi 3.6 python.org/dev/peps/pep-0506Jika Anda juga membutuhkan indeks, gunakan
random.randrange
sumber
Pada Python 3.6 Anda dapat menggunakan
secrets
modul, yang lebih disukai daripadarandom
modul untuk kriptografi atau penggunaan keamanan.Untuk mencetak elemen acak dari daftar:
Untuk mencetak indeks acak:
Untuk detailnya, lihat PEP 506 .
sumber
Saya mengusulkan skrip untuk menghapus item yang diambil secara acak dari daftar sampai kosong:
Pertahankan
set
dan hapus elemen yang diambil secara acak (denganchoice
) sampai daftar kosong.Tiga langkah memberikan tiga jawaban berbeda:
sumber
random.shuffle
yanglist
sekali dan baik iterate atau pop untuk menghasilkan hasil. Entah akan menghasilkan aliran "pilih acak secara memadai", hanya saja keacakan akan diperkenalkan di awal.Dengan python 2:
Dengan python 3:
sumber
random.choices
dengan penggantian sementararandom.sample
tanpa penggantian.numpy
larutan:numpy.random.choice
Untuk pertanyaan ini, kerjanya sama dengan jawaban yang diterima (
import random; random.choice()
), tetapi saya menambahkannya karena pemrogram mungkin sudah mengimpornumpy
(seperti saya) & juga ada beberapa perbedaan antara dua metode yang mungkin terkait dengan kasus penggunaan aktual Anda.Untuk reproduktifitas, Anda dapat melakukan:
Untuk sampel satu atau lebih item , dikembalikan sebagai
array
, lulussize
argumen:sumber
Jika Anda ingin mendekati benar-benar acak , maka saya sarankan
secrets.choice
dari perpustakaan standar (Baru dalam Python 3.6.):Di atas sama dengan rekomendasi saya sebelumnya, menggunakan
SystemRandom
objek darirandom
modul denganchoice
metode - tersedia sebelumnya di Python 2:Dan sekarang:
Jika Anda ingin pemilihan acak semu deterministik, gunakan
choice
fungsi (yang sebenarnya merupakan metode terikat padaRandom
objek):Tampaknya acak, tetapi sebenarnya tidak, yang bisa kita lihat jika kita pasang kembali berulang kali:
Komentar:
Ya, Anda bisa memberikan argumen "seed", tetapi Anda akan melihat bahwa
SystemRandom
objek mengabaikannya :sumber
jika Anda membutuhkan indeks, gunakan saja:
random.choice melakukan hal yang sama :)
sumber
random.choice(self, seq)
adalahreturn seq[int(self.random() * len(seq))]
.randrange()
yang berarti misalnyarandom.SystemRandom().randrange(3<<51)
menunjukkan bias yang signifikan. Huh ...float
(ganda IEEE) hanya dapat mengambil sejumlah nilai hingga [0,1).Random.random()
menghasilkan output dengan cara tradisional: pilih bilangan bulat acak[0, 2**53)
dan bagi dengan2**53
(53 adalah jumlah bit dalam dua kali lipat). Jadi,random()
kembalikan 2 ** 53 ganda yang dapat disetel, dan Anda dapat membaginya secara merata menjadi keluaran N hanya jika N berkekuatan 2. Biasnya kecil untuk N kecil, tetapi lihatcollections.Counter(random.SystemRandom().randrange(3<<51)%6 for i in range(100000)).most_common()
. (Java's Random.nextInt () menghindari bias semacam itu.)2**40
, (yang 1099511627776), akan cukup kecil untuk bias tidak menjadi masalah dalam praktek? Ini harus benar-benar ditunjukkan dalam dokumentasi, karena jika seseorang tidak teliti, mereka mungkin tidak mengharapkan masalah datang dari bagian kode mereka.random
gunakangetrandbits
untuk mendapatkan jumlah bit yang memadai untuk menghasilkan hasil untukrandrange
s yang lebih besar (random.choice
juga menggunakannya). Ini berlaku untuk 2.7 dan 3.5. Ini hanya digunakanself.random() * len(seq)
saatgetrandbits
tidak tersedia. Anda tidak melakukan hal bodoh yang Anda pikirkan.Ini adalah kode dengan variabel yang mendefinisikan indeks acak:
Ini adalah kode tanpa variabel:
Dan ini adalah kode dengan cara terpendek dan paling cerdas untuk melakukannya:
(python 2.7)
sumber
Kode berikut menunjukkan jika Anda perlu membuat barang yang sama. Anda juga dapat menentukan berapa banyak sampel yang ingin Anda ekstrak.
The
sample
Metode mengembalikan daftar baru yang berisi elemen dari populasi sementara meninggalkan penduduk asli tidak berubah. Daftar yang dihasilkan dalam urutan seleksi sehingga semua sub-irisan juga akan menjadi sampel acak yang valid.sumber
Pemilihan item acak:
Untuk mempertahankan urutan daftar, Anda dapat melakukan:
Gandakan https://stackoverflow.com/a/49682832/4383027
sumber
Kita juga bisa melakukan ini menggunakan randint.
sumber
random.choice()
danrandom.randrange()
?None
hanya menendang kaleng ke beberapa titik nanti acak di mana "elemen" yang tidak valid memicu pengecualian; atau lebih buruk lagi, Anda mendapatkan program yang salah, bukan pengecualian, dan Anda bahkan tidak mengetahuinya.Anda bisa saja:
sumber