Псевдослучайно выбирать элемент из списка, только если он еще не был выбран

Есть ли способ "псевдо"-случайно выбрать элемент из списка, который не был выбран ранее? Я знаю о функции choice, которая возвращает случайный элемент из списка, но без учета ранее выбранных элементов. Я мог бы отслеживать, какие элементы уже были выбраны, и продолжать случайным образом выбирать другой еще не выбранный элемент, но это может включать вложенные циклы и т. д.

Я также мог бы, например, удалять выбранный элемент из списка на каждой итерации, но это тоже не кажется хорошим решением.

Мой вопрос: существует ли «осведомленная» функция choice, которая выбирает только элементы, которые не были выбраны ранее? Обратите внимание, что я не спрашиваю, как реализовать такую ​​функцию, но возможные решения, конечно, также хорошо принимаются.


person nbro    schedule 12.02.2016    source источник
comment
Перемешайте список и вытащите элементы сверху.   -  person khelwood    schedule 12.02.2016
comment
Вы можете использовать random.sample или random.shuffle. Чтобы правильно ответить на ваш вопрос, необходимо больше контекста.   -  person Vincent Savard    schedule 12.02.2016
comment
Да, я думаю, что я выберу random.shuffle, так как в моем случае не имеет значения, изменен исходный список или нет, если другие решения не появятся. Спасибо!   -  person nbro    schedule 12.02.2016


Ответы (2)


Как уже говорили другие, вы можете перетасовать список, а затем использовать метод list.pop(). Вот пример:

>>> import random
>>> mylist = list(range(5))
>>> print(mylist)
[0, 1, 2, 3, 4]
>>> random.shuffle(mylist)
>>> print(mylist)
[4, 2, 0, 1, 3]
>>> while len(mylist) > 0:
...     print(mylist.pop())
...
3
1
0
2
4
>>> print(mylist)
[]
person zondo    schedule 12.02.2016
comment
Ваш код приводит к возникновению исключения: TypeError: 'range' object does not support item assignment. Вам нужно передать объект диапазона в список, например. mylist = list(range(5)). - person Arn; 02.05.2020
comment
@Арн: Ты прав. В то время, когда я писал, я имел дело с Python 2 гораздо больше, чем с Python 3, поэтому похоже, что я только что протестировал его в консоли Python 2, а затем добавил скобки для печати. Теперь это исправлено. - person zondo; 02.05.2020

Перемешайте список и вытащите элементы сверху. Это будет создавать каждый элемент списка только один раз.

person khelwood    schedule 12.02.2016