在Python中如何获取随机布尔值?

369

我正在寻找在Python中获取随机布尔值(像掷硬币一样)的最佳方法(快速且简洁)。

目前我使用的是 random.randint(0, 1)random.getrandbits(1)

是否有更好的选择我不知道呢?


6
这是一个关于获取随机布尔值的各种选项性能的好问题,但我感觉在所有基准测试的噪音中迷失了方向,事实上,在一百万次迭代中,最佳表现者与最差表现者之间仅相差不到一秒钟。如果你来到这里是为了加速应用程序,那么你可能应该先考虑其他选项。 - Ian McLaird
10个回答

493

Adam的答案非常快,但我发现random.getrandbits(1)要快得多。如果您真的想要一个布尔值而不是一个长整型,则

import random
bool(random.getrandbits(1))

相比于random.choice([True, False]),它仍然快大约两倍。

这两种解决方案都需要import random

如果速度不是最重要的因素,那么random.choice肯定更易读。

请注意,由于属性查找,random.choice()比只有choice()(在from random import choice之后)慢。

$ python3 --version
Python 3.9.7
$ python3 -m timeit -s "from random import choice" "choice([True, False])"
1000000 loops, best of 5: 376 nsec per loop
$ python3 -m timeit -s "from random import choice" "choice((True, False))"
1000000 loops, best of 5: 352 nsec per loop
$ python3 -m timeit -s "from random import getrandbits" "getrandbits(1)"
10000000 loops, best of 5: 33.7 nsec per loop
$ python3 -m timeit -s "from random import getrandbits" "bool(getrandbits(1))"
5000000 loops, best of 5: 89.5 nsec per loop
$ python3 -m timeit -s "from random import getrandbits" "not getrandbits(1)"
5000000 loops, best of 5: 46.3 nsec per loop
$ python3 -m timeit -s "from random import random" "random() < 0.5"
5000000 loops, best of 5: 46.4 nsec per loop

30
如果我们追求性能,not not random.getrandbits(1))bool更快 ;) - Michał Bentkowski
17
你可能根本不需要转换成布尔类型,因为0/1具有正确的真值。 - Adam Vandenberg
14
你可以通过使用from random import getrandbits来避免属性查找,从而进一步加快速度。 :-) - kindall
2
实际上,缺失的属性查找似乎是 random() < 0.5 最快的原因。当使用 from random import getrandbits 时,getrandbitsrandom() < 0.5 更快。 - jl005

272
import random
random.choice([True, False])

也可以工作。


我需要导入一些库吗? - hola
3
只是“随机”。它是标准库的一部分 - castis
1
确实 - 这里大部分其他答案使用的是相同的“random”。 - Karl Knechtel

56

找到了更快的方法:

$ 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

6
random() > 0.5的运算结果已经是bool类型,速度更快! - John La Rooy
32
如果 random() >= 0.5,否则你会稍微偏向 False - Simon Lindholm
29
random() < 0.5中的0.5改为其他概率值,可以按预期运作。 - akxlr
改为 random() < 0.5,感谢 @SimonLindholm 和 @akxlr。 - Pavel Radchenko
如果random() > 0.5,则为True,否则为False。啊啊啊啊啊!!!!!我的眼睛。 - Eric Duminil

13

我喜欢

 np.random.rand() > .5

13
如果您想生成多个随机布尔值,可以使用NumPy的随机模块。参见官方文档
np.random.randint(2, size=10)

将在开区间 [0,2) 中返回 10 个随机均匀整数。关键字 size 指定要生成的值的数量。


我很好奇这种方法的速度与答案相比如何表现,因为这个选项被排除在比较之外。要生成一个随机布尔值(即问题),这样做会慢得多,但如果你想生成很多,那么这样做就会快得多:$ python -m timeit -s "from random import random" "random() < 0.5" 10000000 次循环,3 次取最优结果:每次循环耗时 0.0906 微秒 - ojunk

6
你可以使用 Faker库,它主要用于测试,但可以提供各种虚假数据。
安装:https://pypi.org/project/Faker/
>>> from faker import Faker
>>> fake = Faker()
>>> fake.pybool()
True

4

我好奇numpy的速度表现如何,因为这个在比较中被省略了。生成一个随机布尔值会慢得多,但如果你想生成很多布尔值,那么速度就会变得更快:

$ 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

3

你可以尝试这个方法,它会生成一个随机数组,其中包含 true 和 false:

a=[bool(i) for i in np.array(np.random.randint(0,2,10))]

输出结果是:[True, True, True, True, True, False, True, False, True, False]


2

这个问题的新解决方法涉及使用 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)

17
考虑到这种解决方法需要下载不同的软件包且较为麻烦,所以你至少应该解释一下为什么认为这是更好的解决方案。 - Martino
3
我不同意这些反对票。如果你正在创建随机数据,Faker可能是一个非常有用的工具。fake.boolean()语法干净易懂,其他人也很容易理解。 - Jason McVetta
4
无论这个包是否有用,完全缺乏解释为什么应该考虑它使得答案毫无意义。 - Apollys supports Monica

0
以下方法也适用于此目的:
import random
random.choice([0, 1])

或者

import random
random.choice(range(2))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接