Відповіді:
Використовуйте random.choice()
import random
foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))
Для криптографічно безпечних випадкових виборів (наприклад, для створення парольної фрази зі списку слів) використовуйтеsecrets.choice()
import secrets
foo = ['battery', 'correct', 'horse', 'staple']
print(secrets.choice(foo))
secrets
є новим у Python 3.6, у старих версіях Python ви можете використовувати random.SystemRandom
клас:
import random
secure_random = random.SystemRandom()
print(secure_random.choice(foo))
random.sample(lst, n)
Якщо ви хочете випадковим чином вибрати декілька елементів зі списку або вибрати елемент із набору, я рекомендую використовувати його random.sample
замість.
import random
group_of_items = {1, 2, 3, 4} # a sequence or set will work here.
num_to_select = 2 # set the number to select here.
list_of_random_items = random.sample(group_of_items, num_to_select)
first_random_item = list_of_random_items[0]
second_random_item = list_of_random_items[1]
Якщо ви витягуєте лише один елемент зі списку, вибір є менш незграбним, оскільки використання зразка матиме синтаксис random.sample(some_list, 1)[0]
замість random.choice(some_list)
.
На жаль, вибір працює лише для одного виходу з послідовностей (таких як списки або кортежі). Хоча це random.choice(tuple(some_set))
може бути варіант отримання одного предмета з набору.
EDIT: Використання секретів
Як багато хто зазначав, якщо вам потрібні більш безпечні псевдовипадкові зразки, вам слід використовувати модуль секретів:
import secrets # imports secure module.
secure_random = secrets.SystemRandom() # creates a secure random object.
group_of_items = {1, 2, 3, 4} # a sequence or set will work here.
num_to_select = 2 # set the number to select here.
list_of_random_items = secure_random.sample(group_of_items, num_to_select)
first_random_item = list_of_random_items[0]
second_random_item = list_of_random_items[1]
EDIT: Пітонічний однолінійний
Якщо ви хочете отримати більше пітонічного однопластового для вибору декількох предметів, ви можете використовувати розпакування.
import random
first_random_item, second_random_item = random.sample(group_of_items, 2)
secrets
Модуль BTW був доданий до стандартної бібліотеки Python у версії 3.6 python.org/dev/peps/pep-0506
Якщо вам також потрібен індекс, використовуйте random.randrange
from random import randrange
random_index = randrange(len(foo))
print(foo[random_index])
Станом на Python 3.6, ви можете використовувати secrets
модуль, який є кращим перед random
модулем для криптографії або використання безпеки.
Щоб надрукувати випадковий елемент зі списку:
import secrets
foo = ['a', 'b', 'c', 'd', 'e']
print(secrets.choice(foo))
Щоб надрукувати випадковий індекс:
print(secrets.randbelow(len(foo)))
Детальніше див. PEP 506 .
Я пропоную сценарій для видалення випадково підібраних предметів зі списку, поки він не буде порожнім:
Підтримуйте a set
і видаляйте випадково вибраний елемент (з choice
), поки список не буде порожнім.
s=set(range(1,6))
import random
while len(s)>0:
s.remove(random.choice(list(s)))
print(s)
Три пробіги дають три різні відповіді:
>>>
set([1, 3, 4, 5])
set([3, 4, 5])
set([3, 4])
set([4])
set([])
>>>
set([1, 2, 3, 5])
set([2, 3, 5])
set([2, 3])
set([2])
set([])
>>>
set([1, 2, 3, 5])
set([1, 2, 3])
set([1, 2])
set([1])
set([])
random.shuffle
list
foo = ['a', 'b', 'c', 'd', 'e']
number_of_samples = 1
У python 2:
random_items = random.sample(population=foo, k=number_of_samples)
У пітоні 3:
random_items = random.choices(population=foo, k=number_of_samples)
random.choices
це заміна, поки random.sample
вона без заміни.
numpy
рішення: numpy.random.choice
Для цього питання він працює так само, як прийнятий відповідь ( import random; random.choice()
), але я додав його, оскільки програміст вже імпортував numpy
(як я), а також є деякі відмінності між двома методами, які можуть стосуватися вашого фактичного випадку використання.
import numpy as np
np.random.choice(foo) # randomly selects a single item
Для відтворюваності ви можете:
np.random.seed(123)
np.random.choice(foo) # first call will always return 'c'
Для зразків одного або декількох елементів , повернутих як array
, передайте size
аргумент:
np.random.choice(foo, 5) # sample with replacement (default)
np.random.choice(foo, 5, False) # sample without replacement
Як довільно вибрати елемент зі списку?
Припустимо, у мене є такий список:
foo = ['a', 'b', 'c', 'd', 'e']
Який найпростіший спосіб отримати об'єкт навмання зі цього списку?
Якщо ви хочете, щоб вони були справді випадковими , то я пропоную secrets.choice
зі стандартної бібліотеки (Нове в Python 3.6.):
>>> from secrets import choice # Python 3 only
>>> choice(list('abcde'))
'c'
Сказане вище еквівалентно моїй попередній рекомендації, використовуючи SystemRandom
об'єкт з random
модуля choice
методом - доступним раніше в Python 2:
>>> import random # Python 2 compatible
>>> sr = random.SystemRandom()
>>> foo = list('abcde')
>>> foo
['a', 'b', 'c', 'd', 'e']
І зараз:
>>> sr.choice(foo)
'd'
>>> sr.choice(foo)
'e'
>>> sr.choice(foo)
'a'
>>> sr.choice(foo)
'b'
>>> sr.choice(foo)
'a'
>>> sr.choice(foo)
'c'
>>> sr.choice(foo)
'c'
Якщо ви хочете детермінований псевдослучайний вибір, використовуйте choice
функцію (яка насправді пов'язаний метод на Random
об'єкт):
>>> random.choice
<bound method Random.choice of <random.Random object at 0x800c1034>>
Це здається випадковим, але насправді це не так, що ми можемо побачити, чи повторно його перезавантажували:
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
>>> random.seed(42); random.choice(foo), random.choice(foo), random.choice(foo)
('d', 'a', 'b')
Йдеться не про те, чи справді випадковий вибір є випадковим чи ні. Якщо ви зафіксуєте насіння, ви отримаєте відтворювані результати - і саме для цього насіння призначене. Ви також можете передати насіння в SystemRandom.
sr = random.SystemRandom(42)
Що ж, так, ви можете передати йому "насіннєвий" аргумент, але ви побачите, що SystemRandom
об'єкт просто ігнорує його :
def seed(self, *args, **kwds):
"Stub method. Not used for a system random number generator."
return None
якщо вам потрібен індекс, просто використовуйте:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print int(random.random() * len(foo))
print foo[int(random.random() * len(foo))]
random.choice робить те саме :)
random.choice(self, seq)
є return seq[int(self.random() * len(seq))]
.
randrange()
що означає, наприклад, що random.SystemRandom().randrange(3<<51)
виявляє значну упередженість. Зітхнути ...
float
(подвійний IEEE) може приймати лише кінцеве число значень у [0,1). Random.random()
генерує свій вихід традиційним способом: виберіть випадкове ціле число [0, 2**53)
і поділіть на 2**53
(53 - кількість бітів удвічі). Таким чином, random()
повертається 2 ** 53 рівномірних подвоєнь, і ви можете розділити це рівномірно на N виходів, лише якщо N - потужність 2. Ухил невеликий для малого N, але див collections.Counter(random.SystemRandom().randrange(3<<51)%6 for i in range(100000)).most_common()
. (Java Random.nextInt () уникає таких упереджень.)
2**40
, (що становить 1099511627776), було б досить малим, щоб упередження не мали значення на практиці? Це дійсно слід зазначити в документації, тому що якщо хтось не є ретельним, він може не очікувати, що проблеми виникнуть з цієї частини коду.
random
використовує getrandbits
для отримання адекватної кількості бітів для отримання результату для більшого randrange
s ( random.choice
також це використовується). Це справедливо як для 2.7, так і для 3.5. Він використовується лише self.random() * len(seq)
тоді, коли getrandbits
він недоступний. Це не дурне, що ти думаєш.
Це код зі змінною, яка визначає випадковий індекс:
import random
foo = ['a', 'b', 'c', 'd', 'e']
randomindex = random.randint(0,len(foo)-1)
print (foo[randomindex])
## print (randomindex)
Це код без змінної:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print (foo[random.randint(0,len(foo)-1)])
І це код найкоротшим та найрозумнішим способом:
import random
foo = ['a', 'b', 'c', 'd', 'e']
print(random.choice(foo))
(пітон 2.7)
Наступний код демонструє, чи потрібно виробляти ті самі елементи. Ви також можете вказати, скільки зразків потрібно витягти. Метод повертає новий список , що містить елементи населення, залишаючи вихідне населення без змін. Отриманий список складається в порядку відбору, щоб усі підрозрізи також були дійсними випадковими вибірками.sample
import random as random
random.seed(0) # don't use seed function, if you want different results in each run
print(random.sample(foo,3)) # 3 is the number of sample you want to retrieve
Output:['d', 'e', 'a']
import random
my_list = [1, 2, 3, 4, 5]
num_selections = 2
new_list = random.sample(my_list, num_selections)
randIndex = random.sample(range(len(my_list)), n_selections)
randIndex.sort()
new_list = [my_list[i] for i in randIndex]
Ми також можемо це зробити, використовуючи randint.
from random import randint
l= ['a','b','c']
def get_rand_element(l):
if l:
return l[randint(0,len(l)-1)]
else:
return None
get_rand_element(l)
random.choice()
і random.randrange()
?
None
просто натискає баночку до якоїсь випадкової пізнішої точки, де недійсний "елемент" запускає виняток; або ще гірше, ви отримуєте неправильну програму замість винятку, і навіть не знаєте її.
Ви могли просто:
from random import randint
foo = ["a", "b", "c", "d", "e"]
print(foo[randint(0,4)])
random.choice(foo)
повернення два різні результати?