2333 votes

Comment puis-je sélectionner de manière aléatoire un élément dans une liste ?

Supposons que je dispose de la liste suivante :

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

Quelle est la façon la plus simple de récupérer un élément au hasard dans cette liste ?

3 votes

Avant de poster une nouvelle réponse, pensez qu'il y a déjà plus de 10 réponses à cette question. Veillez à ce que votre réponse apporte des informations qui ne figurent pas parmi les réponses existantes.

0 votes

Une réponse en double est ici - stackoverflow.com/questions/9690009/

3379voto

Pēteris Caune Points 13662

Utilice random.choice() :

import random

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

Para sécurité cryptographique des choix aléatoires (par exemple, pour générer une phrase de passe à partir d'une liste de mots), utilisez secrets.choice() :

import secrets

foo = ['battery', 'correct', 'horse', 'staple']
print(secrets.choice(foo))

secrets est nouveau dans Python 3.6. Sur les versions plus anciennes de Python, vous pouvez utiliser la fonction random.SystemRandom classe :

import random

secure_random = random.SystemRandom()
print(secure_random.choice(foo))

5 votes

Est-ce que faire deux appels consécutifs de random.choice(foo) renvoie deux résultats différents ?

72 votes

@EduardoPignatelli Chaque choix est aléatoire, donc puede renvoie deux résultats différents, mais selon la graine de départ, ce n'est pas garanti. Si vous voulez sélectionner n éléments distincts pris au hasard dans une liste lst utiliser random.sample(lst, n)

10 votes

Sur une note connexe, Standard pseudo-random generators are not suitable for security/cryptographic purposes. réf.

191voto

Juampi Points 971

Si vous avez également besoin de l'index, utilisez random.randrange

from random import randrange
random_index = randrange(len(foo))
print(foo[random_index])

46voto

antitrust Points 4853

Je propose un script pour retirer des éléments pris au hasard d'une liste jusqu'à ce qu'elle soit vide :

Maintenir un set et retirer un élément pris au hasard (avec choice ) jusqu'à ce que la liste soit vide.

s=set(range(1,6))
import random

while len(s)>0:
  s.remove(random.choice(list(s)))
  print(s)

Trois courses donnent trois réponses différentes :

>>> 
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([])

24 votes

Ou vous pourriez juste random.shuffle el list une fois et soit l'itérer, soit l'ouvrir pour produire des résultats. Dans les deux cas, on obtiendrait un flux de "sélection aléatoire sans répétition" parfaitement adéquat, mais le caractère aléatoire serait introduit dès le début.

2 votes

Théoriquement, vous pouvez utiliser le pop() d'un ensemble pour retirer un élément arbitraire d'un ensemble et le retourner, mais ce n'est probablement pas assez aléatoire.

18voto

Janek Olszak Points 328

Si vous avez besoin de l'index, utilisez simplement :

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

choix.aléatoire fait de même :)

2 votes

@tc. En fait, il fait essentiellement la même chose. L'implémentation de random.choice(self, seq) es return seq[int(self.random() * len(seq))] .

2 votes

@wim C'est un peu décevant, mais la muy Ce qui est décevant, c'est que c'est aussi la définition de randrange() ce qui signifie par exemple random.SystemRandom().randrange(3<<51) présente un biais important. Soupir...

7 votes

@kevinsa5 En fin de compte, c'est parce qu'un float (un double IEEE) ne peut prendre qu'un nombre fini de valeurs dans [0,1). Random.random() génère sa sortie de la manière traditionnelle : choisir un entier aléatoire dans [0, 2**53) et diviser par 2**53 (53 est le nombre de bits dans un double). Donc random() renvoie 2**53 doubles équiprobables, et vous pouvez diviser ce nombre en N sorties uniquement si N est une puissance de 2. Le biais est faible pour les petits N, mais voir collections.Counter(random.SystemRandom().randrange(3<<51)%6 for i in range(100000)).most_common() . (La méthode Random.nextInt() de Java évite ce genre de biais).

10voto

Aedil Points 434
import random
random_item = random.choice(foo)

Une façon un peu plus pythique de le faire

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X