Предположим, у меня есть следующий список:

foo = ['a', 'b', 'c', 'd', 'e']

Какой самый простой способ получить элемент в случайном порядке из этого списка?

2095
Ray 20 Ноя 2008 в 21:42

12 ответов

Лучший ответ

Используйте 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 class:

import random

secure_random = random.SystemRandom()
print(secure_random.choice(foo))
2622
Boris 21 Дек 2019 в 04:00

Случайный выбор товара:

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]

Дубликат https://stackoverflow.com/a/49682832/4383027

1
Solomon Vimal 27 Авг 2019 в 21:29

Я предлагаю скрипт для удаления случайно выбранных элементов из списка, пока он не станет пустым:

Сохраняйте 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([])
33
Community 24 Июн 2014 в 10:56

Если вам также нужен индекс, используйте random.randrange

from random import randrange
random_index = randrange(len(foo))
print(foo[random_index])
153
Boris 18 Авг 2018 в 04:02

Если вам нужен индекс, просто используйте:

import random
foo = ['a', 'b', 'c', 'd', 'e']
print int(random.random() * len(foo))
print foo[int(random.random() * len(foo))]

Random.choice делает то же самое :)

8
Janek Olszak 23 Дек 2012 в 22:06

Мы также можем сделать это, используя 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)
0
Liam 6 Сен 2016 в 19:00

Это код с переменной, которая определяет случайный индекс:

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))

(Python 2.7)

7
Will Dereham 25 Май 2015 в 16:56

Как случайным образом выбрать элемент из списка?

Предположим, у меня есть следующий список:

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')

Комментарий:

Это не о том, является ли random.choice действительно случайным или нет. Если вы почините семя, вы получите воспроизводимые результаты - и для этого семя предназначено. Вы также можете передать семена в SystemRandom. sr = random.SystemRandom(42)

Да, вы можете передать ему аргумент "seed", но вы увидите, что SystemRandom объект просто игнорирует его:

def seed(self, *args, **kwds):
    "Stub method.  Not used for a system random number generator."
    return None
9
Aaron Hall 21 Дек 2019 в 03:27

Следующий код демонстрирует, нужно ли вам производить одинаковые предметы. Вы также можете указать, сколько образцов вы хотите извлечь.
Метод 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']
3
Memin 12 Окт 2018 в 15:47

Если вы хотите случайным образом выбрать более одного элемента из списка или выбрать элемент из набора, я бы рекомендовал вместо этого использовать 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)) может быть вариантом для получения одного элемента из набора.

РЕДАКТИРОВАТЬ: используя секреты

Как уже отмечали многие, если вам требуются более безопасные псевдослучайные образцы, вы должны использовать модуль секретов:

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]
180
Paul 9 Ноя 2018 в 14:23
foo = ['a', 'b', 'c', 'd', 'e']
number_of_samples = 1

В питоне 2:

random_items = random.sample(population=foo, k=number_of_samples)

В питоне 3:

random_items = random.choices(population=foo, k=number_of_samples)
14
Fardin 29 Ноя 2017 в 16:40

Начиная с Python 3.6 вы можете использовать secrets модуль, который предпочтительнее модуля random для криптографии или безопасности.

Чтобы распечатать случайный элемент из списка:

import secrets
foo = ['a', 'b', 'c', 'd', 'e']
print(secrets.choice(foo))

Чтобы напечатать случайный индекс:

print(secrets.randbelow(len(foo)))

Подробнее см. PEP 506.

40
Chris_Rands 6 Дек 2016 в 12:06