itération aléatoire en Python
quand vous voulez itérer séquentiellement sur une liste de nombres vous écrirez:
for i in range(1000):
# do something with i
mais que faire si vous voulez itérer sur la liste des nombres de la gamme (0..999) au hasard? Il y a un besoin (dans chaque itération) de choisir au hasard le nombre qui n'a pas été choisi dans une itération précédente et il y a un besoin d'itérer sur tous les nombres de la gamme (0..999).
savez-vous faire cela (smart)?
5 réponses
Vous pouvez utiliser random.shuffle()
, eh bien, shuffle une liste:
import random
r = list(range(1000))
random.shuffle(r)
for i in r:
# do something with i
soit dit en passant, dans de nombreux cas où vous utiliseriez un for
boucle sur une gamme d'entiers dans d'autres langages de programmation, vous pouvez décrire directement la "chose" que vous voulez itérer en Python.
Par exemple, si vous souhaitez utiliser les valeurs de i
pour accéder aux éléments d'une liste, vous devriez mieux shuffle directement la liste:
lst = [1970, 1991, 2012]
random.shuffle(lst)
for x in lst:
print x
NOTE: vous devez supporter l'avertissement suivant à l'esprit lors de l'utilisation de random.shuffle()
(prises à partir de la docs:
notez que pour des len(x) même assez petits, le nombre total de les permutations de x est plus grande que la période de la plupart des nombres aléatoires générateurs; ceci implique que la plupart des permutations d'une longue séquence peuvent ne jamais être généré.
les gens ratent souvent des occasions de modularisation. Vous pouvez définir une fonction pour encapsuler l'idée de "itérer au hasard":
def randomly(seq):
shuffled = list(seq)
random.shuffle(shuffled)
return iter(shuffled)
puis:
for i in randomly(range(1000)):
#.. we're good to go ..
Démonstration de Python et des générateurs de l' shuffle de Fisher–Yates.
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
vous générez seulement autant de nombres aléatoires que vous utilisez. Mais honnêtement, il est probablement pas économiser beaucoup, donc vous devriez généralement utiliser random.shuffle
.
Remarque: Si la première carte est choisie, deck[i] = deck.pop()
ne serait pas sûr, donc enlever le haut est fait en deux étapes.
Il existe une fonction random.permutation()
numpy
Cela fait exactement cela pour vous.
Votre code ressemblerait à
from numpy.random import permutation
for i in permutation(1000):
# do something with i
Utilisez le hasard.shuffle méthode:
itrange = list(range(100))
random.shuffle(itrange)
for i in itrange:
print i