【发布时间】:2020-04-25 01:39:35
【问题描述】:
在 Python 中有两种明显的方法可以生成从 0 到 9 的随机数字。可以生成一个介于 0 和 1 之间的随机浮点数,乘以 10,然后向下舍入。或者,可以使用random.randint 方法。
import random
def random_digit_1():
return int(10 * random.random())
def random_digit_2():
return random.randint(0, 9)
我很好奇如果生成一个介于 0 和 1 之间的随机数并保留 最后一个位会发生什么。我并不一定期望分布是均匀的,但我发现结果非常令人惊讶。
from random import random, seed
from collections import Counter
seed(0)
counts = Counter(int(str(random())[-1]) for _ in range(1_000_000))
print(counts)
输出:
Counter({1: 84206,
5: 130245,
3: 119433,
6: 129835,
8: 101488,
2: 100861,
9: 84796,
4: 129088,
7: 120048})
直方图如下所示。请注意,不会出现 0,因为尾随零被截断。但是谁能解释为什么数字 4、5 和 6 比其他数字更常见?我用了 Python 3.6.10,但 Python 3.8.0a4 中的结果相似。
【问题讨论】:
-
这与在 Python 中计算浮点数的字符串表示的方式有关。见docs.python.org/3/tutorial/floatingpoint.html。如果您使用十分位(小数点后的第一位)而不是最后一位,您会得到更均匀的结果。
-
我们以二进制表示形式存储浮点数(因为我们的内存也是二进制的)。
str将其转换为 base-10,这必然会导致问题。例如1 位浮点尾数b0 -> 1.0和b1 -> 1.5。 “最后一位”将始终为0或5。 -
random.randrange(10)更明显,恕我直言。random.randint(在后台调用random.randrange)是后来添加到random模块的,适用于不了解 Python 中范围如何工作的人。 ;) -
@PM2Ring:
randrange实际上排在第二位,因为他们认为randint接口是一个错误。 -
@user2357112supportsMonica 哦,好的。我站得更正了。我确信 randrange 是第一名,但我的记忆力不如以前了。 ;)