Obtenez un booléen aléatoire en python?

244

Je cherche la meilleure façon (rapide et élégante) d'obtenir un booléen aléatoire en python (lancer une pièce).

Pour le moment, j'utilise random.randint(0, 1)ou random.getrandbits(1).

Y a-t-il de meilleurs choix que je ne connais pas?

Xavier V.
la source

Réponses:

332

La réponse d'Adam est assez rapide, mais j'ai trouvé que random.getrandbits(1)c'était beaucoup plus rapide. Si vous voulez vraiment un booléen au lieu d'un long alors

bool(random.getrandbits(1))

est toujours environ deux fois plus rapide que random.choice([True, False])

Les deux solutions doivent import random

Si la vitesse maximale n'est pas prioritaire, alors la random.choicelecture est meilleure

$ python -m timeit -s "import random" "random.choice([True, False])"
1000000 loops, best of 3: 0.904 usec per loop
$ python -m timeit -s "import random" "random.choice((True, False))" 
1000000 loops, best of 3: 0.846 usec per loop
$ python -m timeit -s "import random" "random.getrandbits(1)"
1000000 loops, best of 3: 0.286 usec per loop
$ python -m timeit -s "import random" "bool(random.getrandbits(1))"
1000000 loops, best of 3: 0.441 usec per loop
$ python -m timeit -s "import random" "not random.getrandbits(1)"
1000000 loops, best of 3: 0.308 usec per loop
$ python -m timeit -s "from random import getrandbits" "not getrandbits(1)"
1000000 loops, best of 3: 0.262 usec per loop  # not takes about 20us of this

Ajouté celui-ci après avoir vu la réponse de @ Pavel

$ python -m timeit -s "from random import random" "random() < 0.5"
10000000 loops, best of 3: 0.115 usec per loop
John La Rooy
la source
14
Si nous sommes tous not not random.getrandbits(1))bool
axés
11
Vous n'avez probablement même pas besoin de lancer un booléen, car 0/1 a les valeurs de vérité appropriées.
Adam Vandenberg
6
Vous pouvez l'accélérer davantage en from random import getrandbitsévitant la recherche d'attributs. :-)
kindall
186
random.choice([True, False])

fonctionnerait également.

Adam Vandenberg
la source
40

Trouvé une méthode plus rapide:

$ python -m timeit -s "from random import getrandbits" "not getrandbits(1)"
10000000 loops, best of 3: 0.222 usec per loop
$ python -m timeit -s "from random import random" "True if random() > 0.5 else False"
10000000 loops, best of 3: 0.0786 usec per loop
$ python -m timeit -s "from random import random" "random() > 0.5"
10000000 loops, best of 3: 0.0579 usec per loop
Pavel Radchenko
la source
3
random() > 0.5évalue déjà à un bool qui est encore plus rapide!
John La Rooy
26
random() >= 0.5, sinon vous serez un peu biaisé vers Faux.
Simon Lindholm
17
random() < 0.5est plus logique car le changement de 0,5 à une autre probabilité fonctionne comme prévu
akxlr
9

J'aime

 np.random.rand() > .5
Maarten
la source
8

Si vous souhaitez générer un certain nombre de booléens aléatoires, vous pouvez utiliser le module aléatoire de numpy. De la documentation

np.random.randint(2, size=10)

renverra 10 entiers uniformes aléatoires dans l'intervalle ouvert [0,2). Le sizemot-clé spécifie le nombre de valeurs à générer.

Chris
la source
J'étais curieux de savoir comment la vitesse de cette méthode a fonctionné par rapport aux réponses puisque cette option a été omise des comparaisons. Pour générer un booléen aléatoire (ce qui est la question), c'est beaucoup plus lent, mais si vous vouliez en générer plusieurs, cela devient beaucoup plus rapide: $ python -m timeit -s "from random import random" "random () <0.5" 10000000 boucles , meilleur de 3: 0,0906 usec par boucle
ojunk
2

J'étais curieux de savoir comment la vitesse de la réponse numpy a fonctionné par rapport aux autres réponses, car cela n'a pas été pris en compte dans les comparaisons. Pour générer un bool aléatoire, c'est beaucoup plus lent, mais si vous vouliez en générer plusieurs, cela devient beaucoup plus rapide:

$ python -m timeit -s "from random import random" "random() < 0.5"
10000000 loops, best of 3: 0.0906 usec per loop
$ python -m timeit -s "import numpy as np" "np.random.randint(2, size=1)"
100000 loops, best of 3: 4.65 usec per loop

$ python -m timeit -s "from random import random" "test = [random() < 0.5 for i in range(1000000)]"
10 loops, best of 3: 118 msec per loop
$ python -m timeit -s "import numpy as np" "test = np.random.randint(2, size=1000000)"
100 loops, best of 3: 6.31 msec per loop
ojunk
la source
0

Une nouvelle approche de cette question impliquerait l'utilisation de Faker avec lequel vous pouvez facilement installer pip.

from faker import Factory

#----------------------------------------------------------------------
def create_values(fake):
    """"""
    print fake.boolean(chance_of_getting_true=50) # True
    print fake.random_int(min=0, max=1) # 1

if __name__ == "__main__":
    fake = Factory.create()
    create_values(fake)
Althea
la source
14
Vous devriez au moins expliquer pourquoi vous pensez que c'est une meilleure solution, étant donné qu'elle implique le téléchargement d'un package différent et qu'elle est plus compliquée.
Bzazz
2
Je ne suis pas d'accord avec les votes négatifs. Si vous créez des données aléatoires, vous pourriez bien être dans une situation où Faker est un outil très utile. La fake.boolean()syntaxe est propre et facile à comprendre pour les autres.
Jason McVetta
3
Indépendamment de l'utilité ou non du paquet, l'absence totale d'explication sur la raison pour laquelle il convient d'en tenir compte rend la réponse inutile.
Apollys prend en charge Monica