Obter um booleano aleatório em python?

244

Estou procurando a melhor maneira (rápida e elegante) de obter um booleano aleatório em python (jogar uma moeda).

No momento estou usando random.randint(0, 1)ou random.getrandbits(1).

Existem melhores opções que eu não conheço?

Xavier V.
fonte

Respostas:

332

A resposta de Adam é bastante rápida, mas eu achei random.getrandbits(1)muito mais rápido. Se você realmente quer um booleano em vez de um longo,

bool(random.getrandbits(1))

ainda é duas vezes mais rápido que random.choice([True, False])

Ambas as soluções precisam import random

Se a velocidade máxima não é prioritária, então random.choicedefinitivamente é melhor ler

$ 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

Adicionado este após ver a resposta 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
fonte
14
Se estamos todos sobre o desempenho, not not random.getrandbits(1))é mais rápido do que bool;)
Michał Bentkowski
11
Você provavelmente nem precisa converter para um booleano, pois 0/1 tem os valores de verdade adequados.
Adam Vandenberg
6
Você pode acelerar ainda mais fazendo isso from random import getrandbitspara evitar a pesquisa de atributo. :-)
kindall
186
random.choice([True, False])

também funcionaria.

Adam Vandenberg
fonte
40

Encontrou um método mais 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
fonte
3
random() > 0.5já avalia para um bool que é ainda mais rápido!
John La Rooy
26
random() >= 0.5, caso contrário, você será um pouco inclinado para False.
Simon Lindholm
17
random() < 0.5faz mais sentido como mudar 0,5 a algumas outras obras de probabilidade como esperado
akxlr
9

Eu gosto

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

Se você deseja gerar um número aleatório de booleanos, pode usar o módulo aleatório do numpy. A partir da documentação

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

retornará 10 inteiros uniformes aleatórios no intervalo aberto [0,2). A sizepalavra-chave especifica o número de valores a serem gerados.

Chris
fonte
Fiquei curioso para saber como a velocidade desse método se compara às respostas, pois essa opção foi deixada de fora das comparações. Para gerar um bool aleatório (que é a questão), isso é muito mais lento, mas se você quiser gerar muitos, esses mecomas são muito mais rápidos: $ python -m timeit -s "from random import random" "random () <0.5" 10000000 loops , best of 3: 0.0906 usec por loop
ojunk 8/08/18
2

Fiquei curioso para saber como a velocidade da resposta entorpecida se compara às outras respostas, uma vez que isso foi deixado de fora das comparações. Para gerar um bool aleatório, isso é muito mais lento, mas se você quiser gerar muitos, isso se torna muito mais 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
fonte
1

Você pode usar a biblioteca Faker , que é usada principalmente para testes, mas é capaz de fornecer uma variedade de dados falsos.

Instale: https://pypi.org/project/Faker/

>>> from faker import Faker
>>> fake = Faker()
>>> fake.pybool()
True
Partiban
fonte
0

Uma nova visão sobre essa questão envolveria o uso do Faker, com o qual você pode instalar facilmente 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
fonte
14
Você deve pelo menos explicar por que acha que essa é uma solução melhor, considerando que envolve o download de um pacote diferente e é mais confuso.
Bzazz
2
Eu discordo dos votos negativos. Se você estiver criando dados aleatórios, pode estar em uma situação em que o Faker é uma ferramenta muito útil. A fake.boolean()sintaxe é limpa e fácil para os outros entenderem.
Jason McVetta
3
Independentemente de o pacote ser ou não útil, a completa falta de explicação sobre por que alguém deve considerar isso torna a resposta inútil.
Apollys suporta Monica