random.randint(a, b)
在我看来,返回范围内的整数[a, b]
而不是[a, b-1]
like总是很奇怪range(...)
。
这种明显的不一致有什么原因吗?
我试图通过检查一些旧资料来了解这一点。我怀疑这randint
是在 Python 的长整数之前实现的:这意味着如果你想要一个包含 的随机数INT_MAX
,你需要调用random.randrange(0, INT_MAX + 1)
它会溢出并导致参数为(0, 0)
或(0, INT_MIN)
依赖。
然而,即使追溯到Python 1.5.2 的源代码,Lib/whrandom.py
我们看到:
#
# Get a random integer in the range [a, b] including both end points.
# (Deprecated; use randrange below.)
#
def randint(self, a, b):
return self.randrange(a, b+1)
whrandom.randint
在2.0、2.1、2.2和2.3中继续被弃用;但在2.1中被标记为弃用,尽管在2.2中不再被标记为弃用。random.randint
此外,random.py
从 2.1 版开始,在 的文档字符串中首先要注意random.randint
:
def randrange(self, start, stop=None, step=1, int=int, default=None):
"""Choose a random item from range(start, stop[, step]).
This fixes the problem with randint() which includes the
endpoint; in Python this is usually not what you want.
Do not supply the 'int' and 'default' arguments.
"""
唯一比这更早的可用源是0.9.1 source,据我所知,randint
当时还没有实现。
因此,我得出结论,在这一点上只有 Guido 自己知道randint
包含端点的原因;鉴于 Python 2.1 的文档字符串,听起来原因可能是一个简单的错误。
我想random.randint
这只是实现此功能的第一次尝试。看来 Python 开发者也觉得这是个问题,这就是为什么在 v1.5.2 中他们添加了另一个方法randrange具有更多标准参数:
random.randrange([start], stop[, step])
从范围(开始,停止,步骤)中返回一个随机选择的元素。这等效于choice(range(start, stop, step)),但实际上并不构建范围对象。
您可以使用randrange
而不是randint
避免令人惊讶的人。
另一方面,在问题被表述为“在 1 到 6 之间选择一个随机数”的许多情况下,使用它可能更自然,randint(1, 6)
而不是写作randrange(1, 7)
or randrange(min, max + 1)
。
这是推测,但“给我一个从 a 到 b 的随机数”的正常人类用法包括在内。考虑到 Python 作为一种更易于阅读的语言的一般哲学,以这种方式实现它是有道理的。
我不认为这是有原因的。但至少它是记录在案的。