¿Obtener un booleano aleatorio en python?

244

Estoy buscando la mejor manera (rápida y elegante) de obtener un booleano aleatorio en python (lanzar una moneda).

Por el momento estoy usando random.randint(0, 1)o random.getrandbits(1).

¿Hay mejores opciones que no conozco?

Xavier V.
fuente

Respuestas:

332

La respuesta de Adam es bastante rápida, pero descubrí que random.getrandbits(1)es bastante más rápida. Si realmente quieres un booleano en lugar de largo, entonces

bool(random.getrandbits(1))

sigue siendo aproximadamente el doble de rápido que random.choice([True, False])

Ambas soluciones necesitan import random

Si la máxima velocidad no es prioritaria, random.choicedefinitivamente se lee mejor

$ 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

Agregó este después de ver la respuesta 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
fuente
14
Si todo se trata de rendimiento, not not random.getrandbits(1))es más rápido que bool;)
Michał Bentkowski
11
Es probable que ni siquiera necesite convertir a un valor booleano, ya que 0/1 tiene los valores de verdad adecuados.
Adam Vandenberg
66
Puede acelerarlo aún más from random import getrandbitsevitando la búsqueda de atributos. :-)
poco
186
random.choice([True, False])

También funcionaría.

Adam Vandenberg
fuente
40

Encontró un método más rápido:

$ 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
fuente
3
random() > 0.5¡ya se evalúa como un bool que es aún más rápido!
John La Rooy
26
random() >= 0.5, de lo contrario, estarás un poco sesgado hacia False.
Simon Lindholm
17
random() < 0.5tiene más sentido ya que cambiar 0.5 a alguna otra probabilidad funciona como se esperaba
akxlr
9

me gusta

 np.random.rand() > .5
Maarten
fuente
8

Si desea generar un número de booleanos aleatorios, puede usar el módulo aleatorio de numpy. De la documentación

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

devolverá 10 enteros uniformes al azar en el intervalo abierto [0,2). La sizepalabra clave especifica el número de valores a generar.

Chris
fuente
Tenía curiosidad acerca de cómo la velocidad de este método se comportó en comparación con las respuestas, ya que esta opción no se incluyó en las comparaciones. Para generar un bool aleatorio (que es la pregunta), esto es mucho más lento, pero si desea generar muchos, esto se vuelve mucho más rápido: $ python -m timeit -s "from random import random" "random () <0.5" 10000000 bucles , mejor de 3: 0.0906 usec por ciclo
ojunk
2

Tenía curiosidad acerca de cómo la velocidad de la respuesta entumecida se desempeñó en comparación con las otras respuestas, ya que esto se dejó fuera de las comparaciones. Para generar un bool aleatorio, esto es mucho más lento, pero si desea generar muchos, esto se vuelve mucho más rápido:

$ 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
fuente
0

Una nueva versión de esta pregunta implicaría el uso de Faker con el que puede instalar fácilmente 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
fuente
14
Al menos debería explicar por qué cree que esta es una mejor solución, ya que implica descargar un paquete diferente y es más complicado.
Bzazz
2
No estoy de acuerdo con los votos negativos. Si está creando datos aleatorios, puede estar en una situación en la que Faker es una herramienta muy útil. La fake.boolean()sintaxis es limpia y fácil de asimilar para otros.
Jason McVetta
3
Independientemente de si el paquete es útil o no, la completa falta de explicación de por qué uno debería considerar esto hace que la respuesta sea inútil.
Apollys apoya a Monica el