Einen zufälligen Booleschen Wert in Python erhalten?

244

Ich suche nach dem besten Weg (schnell und elegant), um einen zufälligen Booleschen Wert in Python zu erhalten (Münze werfen).

Im Moment benutze ich random.randint(0, 1)oder random.getrandbits(1).

Gibt es bessere Möglichkeiten, die mir nicht bekannt sind?

Xavier V.
quelle

Antworten:

332

Adams Antwort ist ziemlich schnell, aber ich fand, dass random.getrandbits(1)das viel schneller ist. Wenn Sie wirklich einen Booleschen statt einen langen wollen, dann

bool(random.getrandbits(1))

ist immer noch etwa doppelt so schnell wie random.choice([True, False])

Beide Lösungen müssen import random

Wenn höchste Geschwindigkeit keine Priorität hat, random.choiceliest sich das definitiv besser

$ 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

Fügte dieses hinzu, nachdem ich @ Pavel's Antwort gesehen hatte

$ python -m timeit -s "from random import random" "random() < 0.5"
10000000 loops, best of 3: 0.115 usec per loop
John La Rooy
quelle
14
Wenn es um Leistung geht, not not random.getrandbits(1))ist das schneller als bool;)
Michał Bentkowski
11
Sie müssen wahrscheinlich überhaupt nicht in einen Booleschen Wert umwandeln, da 0/1 die richtigen Wahrheitswerte haben.
Adam Vandenberg
6
Sie können dies weiter beschleunigen, indem Sie from random import getrandbitsdie Attributsuche vermeiden. :-)
Kindall
186
random.choice([True, False])

würde auch funktionieren.

Adam Vandenberg
quelle
40

Eine schnellere Methode gefunden:

$ 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
quelle
3
random() > 0.5wertet sich schon zu einem Bool aus, der noch schneller ist!
John La Rooy
26
random() >= 0.5Andernfalls sind Sie ein bisschen voreingenommen in Richtung Falsch.
Simon Lindholm
17
random() < 0.5ist sinnvoller, da das Ändern von 0,5 auf eine andere Wahrscheinlichkeit wie erwartet funktioniert
akxlr
9

ich mag

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

Wenn Sie eine Anzahl von zufälligen Booleschen Werten generieren möchten, können Sie das Zufallsmodul von numpy verwenden. Aus der Dokumentation

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

gibt 10 zufällige einheitliche ganze Zahlen im offenen Intervall zurück [0,2]. Das sizeSchlüsselwort gibt die Anzahl der zu generierenden Werte an.

Chris
quelle
Ich war gespannt, wie sich die Geschwindigkeit dieser Methode gegenüber den Antworten verhält, da diese Option in den Vergleichen nicht berücksichtigt wurde. Um einen zufälligen Bool zu generieren (was die Frage ist), ist dies viel langsamer, aber wenn Sie viele generieren möchten, ist dies viel schneller: $ python -m timeit -s "aus zufälligen zufälligen Import" "random () <0,5" 10000000 Schleifen , best of 3: 0.0906 usec per loop
ojunk
2

Ich war neugierig, wie sich die Geschwindigkeit der numpy Antwort gegenüber den anderen Antworten verhält, da dies in den Vergleichen nicht berücksichtigt wurde. Um einen zufälligen Bool zu generieren, ist dies viel langsamer, aber wenn Sie viele generieren möchten, wird dies viel schneller:

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

Eine neue Sichtweise auf diese Frage würde die Verwendung von Faker beinhalten, mit dem Sie einfach installieren können 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
quelle
14
Sie sollten zumindest erklären, warum Sie dies für eine bessere Lösung halten, wenn man bedenkt, dass ein anderes Paket heruntergeladen wird und es unordentlicher ist.
Bzazz
2
Ich bin mit den Abstimmungen nicht einverstanden. Wenn Sie zufällige Daten erstellen, befinden Sie sich möglicherweise in einer Situation, in der Faker ein sehr nützliches Werkzeug ist. Die fake.boolean()Syntax ist sauber und für andere leicht zu verstehen.
Jason McVetta
3
Unabhängig davon, ob das Paket nützlich ist oder nicht, macht das völlige Fehlen einer Erklärung, warum man dies in Betracht ziehen sollte, die Antwort unbrauchbar.
Apollys unterstützt Monica