54

random.randint(a, b)在我看来,返回范围内的整数[a, b]而不是[a, b-1]like总是很奇怪range(...)

这种明显的不一致有什么原因吗?

4

4 回答 4

89

我试图通过检查一些旧资料来了解这一点。我怀疑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.randint2.0、2.1、2.22.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 的文档字符串,听起来原因可能是一个简单的错误。

于 2010-04-02T20:08:31.093 回答
14

我想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)

于 2010-04-02T19:42:36.937 回答
9

这是推测,但“给我一个从 a 到 b 的随机数”的正常人类用法包括在内。考虑到 Python 作为一种更易于阅读的语言的一般哲学,以这种方式实现它是有道理的。

于 2010-04-02T20:25:14.813 回答
3

我不认为这是有原因的。但至少它是记录在案的。

于 2010-04-02T19:42:04.027 回答