Отримати випадковий булевий у python?


244

Я шукаю найкращий спосіб (швидкий та елегантний), щоб отримати випадкову булеву в пітоні (перевернути монету).

На даний момент я використовую random.randint(0, 1)або random.getrandbits(1).

Чи є кращий вибір, про який я не знаю?

Відповіді:


332

Відповідь Адама досить швидка, але я виявив, що random.getrandbits(1)це набагато швидше. Якщо ви дійсно хочете булевого, а не довгого

bool(random.getrandbits(1))

все ще приблизно вдвічі швидше random.choice([True, False])

Обидва рішення потрібно import random

Якщо максимальна швидкість не є пріоритетною, то, random.choiceбезумовно, читається краще

$ 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

Додав цей, побачивши відповідь @ Павла

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

14
Якщо ми все про продуктивність, not not random.getrandbits(1))то швидше, ніж bool;)
Michał Bentkowski

11
Вам, швидше за все, навіть не потрібно переходити до булевого значення, оскільки значення 0/1 мають відповідні значення істини.
Адам Ванденберг

6
Ви можете пришвидшити це ще більше, from random import getrandbitsуникаючи пошуку атрибутів. :-)
kindall


40

Знайшов більш швидкий метод:

$ 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.5вже оцінює до булінгу, який ще швидше!
Джон Ла Рой

26
random() >= 0.5, інакше ти будеш крихітним упередженим відношенням до False.
Саймон Ліндгольм

17
random() < 0.5має більше сенсу, оскільки зміна 0,5 на якусь іншу ймовірність працює так, як очікувалося
akxlr


8

Якщо ви хочете генерувати кількість випадкових булів, ви можете використовувати випадковий модуль numpy. З документації

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

поверне 10 випадкових рівномірних цілих чисел у відкритому інтервалі [0,2). У sizeключовому слові визначає число значень для генерації.


Мені було цікаво, як швидкість цього методу реагує на відповіді, оскільки цей варіант залишився поза порівнянь. Для генерації одного випадкового bool (це питання) це набагато повільніше, але якщо ви хотіли генерувати багато, це виходить набагато швидше: $ python -m timeit -s "з випадкового імпорту випадкового" "random () <0,5" 10000000 циклів , кращий з 3: 0,0906 Usec за цикл
оюнк

2

Мені було цікаво, як швидкість оніміння відповіді по відношенню до інших відповідей, оскільки це залишилося поза порівняннями. Згенерувати один випадковий буль це набагато повільніше, але якщо ви хотіли генерувати багато, то це стає набагато швидше:

$ 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

Нове рішення цього питання передбачає використання Faker, який ви можете легко встановити 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
Вам слід принаймні пояснити, чому ви вважаєте, що це краще рішення, вважаючи, що воно передбачає завантаження іншого пакету і є більш швидким.
Бзазз

2
Я не погоджуюся з протилежними заявами. Якщо ви створюєте випадкові дані, ви можете потрапити в ситуацію, коли Faker - дуже корисний інструмент. fake.boolean()Синтаксис є чистим і легким для інших звертали увагу.
Jason McVetta

3
Незалежно від того, корисний пакет чи ні, повна відсутність пояснень, чому слід вважати це, робить відповідь марною.
Аполіс підтримує Моніку
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.