Zdobądź losową wartość logiczną w pythonie?


244

Szukam najlepszego sposobu (szybkiego i eleganckiego), aby uzyskać losową wartość logiczną w pythonie (rzuć monetą).

W tej chwili używam random.randint(0, 1)lub random.getrandbits(1).

Czy są lepsze opcje, których nie jestem świadomy?

Odpowiedzi:


332

Odpowiedź Adama jest dość szybka, ale stwierdziłem, że random.getrandbits(1)jest znacznie szybsza. Jeśli naprawdę chcesz długo boolean

bool(random.getrandbits(1))

jest nadal około dwa razy szybszy niż random.choice([True, False])

Oba rozwiązania muszą import random

Jeśli najwyższa prędkość nie jest priorytetem, to random.choicezdecydowanie lepiej

$ 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

Dodałem ten po obejrzeniu odpowiedzi @ Pavela

$ python -m timeit -s "from random import random" "random() < 0.5"
10000000 loops, best of 3: 0.115 usec per loop

14
Jeśli zależy nam na wydajności, not not random.getrandbits(1))jest szybsza niż bool;)
Michał Bentkowski

11
Prawdopodobnie wcale nie musisz rzucać na boolean, ponieważ 0/1 ma prawidłowe wartości prawdy.
Adam Vandenberg

6
Możesz to przyspieszyć, from random import getrandbitsunikając wyszukiwania atrybutów. :-)
uprzejmie


40

Znaleziono szybszą metodę:

$ 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

3
random() > 0.5już ocenia na bool, który jest jeszcze szybszy!
John La Rooy,

26
random() >= 0.5, w przeciwnym razie będziesz trochę stronniczy w stosunku do False.
Simon Lindholm

17
random() < 0.5ma sens, gdy zmiana 0,5 na inne prawdopodobieństwo działa zgodnie z oczekiwaniami
akxlr,


8

Jeśli chcesz wygenerować liczbę losowych boolanów, możesz użyć losowego modułu numpy. Z dokumentacji

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

zwróci 10 losowych jednolitych liczb całkowitych w przedziale otwartym [0,2). Słowo sizekluczowe określa liczbę wartości do wygenerowania.


Byłem ciekawy, jak szybkość tej metody wypadła w porównaniu z odpowiedziami, ponieważ tej opcji nie uwzględniono w porównaniach. Aby wygenerować jeden losowy bool (co jest pytaniem), jest to znacznie wolniejsze, ale jeśli chcesz wygenerować wiele, to ten mecomes jest znacznie szybszy: $ python -m timeit -s "z losowego importu losowe" "random () <0,5" 10000000 pętli , najlepiej 3: 0,0906 usec na pętlę
ojunk

2

Byłem ciekawy, jak szybkość numpy odpowiedzi wypadła w porównaniu z innymi odpowiedziami, ponieważ nie uwzględniono tego w porównaniach. Aby wygenerować jeden losowy bool, jest to znacznie wolniejsze, ale jeśli chcesz wygenerować wiele, staje się to znacznie szybsze:

$ 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


0

Nowe podejście do tego pytania wymagałoby użycia Fakera, z którym można łatwo zainstalować 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)

14
Powinieneś przynajmniej wyjaśnić, dlaczego uważasz, że jest to lepsze rozwiązanie, biorąc pod uwagę, że wiąże się to z pobraniem innej paczki i jest bardziej nieporządne.
Bzazz

2
Nie zgadzam się z głosami negatywnymi. Jeśli tworzysz losowe dane, być może znajdziesz się w sytuacji, w której Faker jest bardzo przydatnym narzędziem. fake.boolean()Składnia jest czyste i proste, aby inni mogli grok.
Jason McVetta,

3
Niezależnie od tego, czy pakiet jest przydatny, całkowity brak wyjaśnień, dlaczego warto to rozważyć, sprawia, że ​​odpowiedź jest bezużyteczna.
Apollys wspiera Monikę
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.