случайная итерация в Python - PullRequest
       32

случайная итерация в Python

24 голосов
/ 13 февраля 2012

Если вы хотите последовательно выполнить итерацию по списку чисел, вы напишите:

for i in range(1000):
  # do something with i

Но что, если вы хотите выполнить итерацию по списку чисел из диапазона (0..999) случайным образом?Необходимо (на каждой итерации) случайным образом выбирать число, которое не было выбрано на любой предыдущей итерации, и необходимо выполнять итерацию по всем числам из диапазона (0..999).

Вы знаете, как это сделать (умный)?

Ответы [ 6 ]

27 голосов
/ 13 февраля 2012

Вы можете использовать random.shuffle(), чтобы перетасовать список:

import random

r = list(range(1000))
random.shuffle(r)
for i in r:
  # do something with i

Кстати, во многих случаях, когда вы используете цикл for наддиапазон целых чисел в других языках программирования, вы можете напрямую описать «вещь», которую вы хотите перебрать в Python.
Например, если вы хотите использовать значения i для доступа к элементам списка, вам следуетлучше перетасовать список напрямую:

lst = [1970, 1991, 2012]
random.shuffle(lst)
for x in lst:
  print x

ПРИМЕЧАНИЕ: При использовании random.shuffle() следует учитывать следующее (взято из docs :

Обратите внимание, что даже для довольно небольшого len (x) общее число перестановок x больше, чем период большинства генераторов случайных чисел, это означает, что большинство перестановок длинной последовательности никогда не может быть сгенерировано.

16 голосов
/ 13 февраля 2012

Люди часто упускают возможности для модульности. Вы можете определить функцию, чтобы инкапсулировать идею «итерировать случайно»:

def randomly(seq):
    shuffled = list(seq)
    random.shuffle(shuffled)
    return iter(shuffled)

тогда:

for i in randomly(range(1000)):
    #.. we're good to go ..
6 голосов
/ 13 января 2015

Демонстрация генераторов Python и перемешивание Фишера-Йейтса .

import random

def shuffled(sequence):
    deck = list(sequence)
    while len(deck):
        i = random.randint(0, len(deck) - 1) # choose random card
        card = deck[i]                       # take the card
        deck[i] = deck[-1]                   # put top card in its place
        deck.pop()                           # remove top card
        yield card

Вы генерируете столько случайных чисел, сколько используете.Но, честно говоря, это, вероятно, не сильно экономит, поэтому вы должны обычно использовать random.shuffle.

Примечание: если выбрана верхняя карта, deck[i] = deck.pop() не будет безопасным, поэтому удалениеВерх выполняется в два этапа.

5 голосов
/ 13 марта 2016

В numpy есть функция random.permutation(), которая делает именно это для вас.Ваш код будет выглядеть как

from numpy.random import permutation

for i in permutation(1000):
    # do something with i
3 голосов
/ 13 февраля 2012

Используйте метод random.shuffle:

itrange = list(range(100))
random.shuffle(itrange)
for i in itrange:
    print i
2 голосов
/ 23 января 2019

Вот другой подход к итерации списка в случайном порядке.Это не изменяет исходный список в отличие от решений, использующих shuffle ()

lst=['a','b','c','d','e','f']
for value in sorted(lst,key=lambda _: random.random()):
    print value

или:

for value in random.sample(lst,len(lst)):
    print value
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...