It has always seemed strange to me that random.randint(a, b)
would return an integer in the range [a, b]
, instead of [a, b-1]
like range(...)
.
对我来说,那种随随便便的感觉总是很奇怪。randint(a, b)会返回一个范围内的整数[a, b],而不是像[a, b-1]那样的范围(…)。
Is there any reason for this apparent inconsistency?
这种明显的不一致有什么原因吗?
4 个解决方案
#1
65
I tried to get to the bottom of this by examining some old sources. I suspected that randint
was implemented before Python's long integer: meaning that if you wanted a random number that included INT_MAX
, you would have needed to call random.randrange(0, INT_MAX + 1)
which would have overflowed and resulted in arguments of (0, 0)
or (0, INT_MIN)
depending.
我试图通过查阅一些旧资料来弄清楚事情的真相。我怀疑randint是在Python的长整数之前实现的:这意味着如果您想要一个包含INT_MAX的随机数,您需要调用random。randrange(0, INT_MAX + 1)可能会溢出并导致(0,0)或(0,INT_MIN)依赖的参数。
However, looking as far back as even the Python 1.5.2 sources, in Lib/whrandom.py
we see:
然而,甚至可以追溯到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
was continued to be deprecated in 2.0, 2.1, 2.2, and 2.3; but random.randint
was marked as deprecated in 2.1, although no longer marked as deprecated in 2.2.
whrandom。在2.0、2.1、2.2和2.3中,randint继续被弃用;但是随机的。randint在2.1中被标记为已弃用,尽管在2.2中不再标记为已弃用。
Also, random.py
from version 2.1 is the first to note in random.randint
's docstring:
同时,随机的。第一个注意到的是来自2.1版的py。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.
"""
The only available source older than that is the 0.9.1 source, and as far as I can tell, randint
was not implemented at that point.
唯一可用的数据源是0.9.1源代码,据我所知,randint在那时还没有实现。
Thus, I conclude that the reasoning for randint
including the endpoint is known to only Guido himself at this point; given the docstring from Python 2.1, it sounds like the reason may have been a simple mistake.
因此,我的结论是,randint包括端点的推理在这一点上只有Guido自己知道;考虑到Python 2.1中的docstring,其原因似乎是一个简单的错误。
#2
10
I guess random.randint
was just the first attempt at implementing this feature. It seems that the Python developers also felt that this was a problem, which is why in v1.5.2 they added another method randrange with more standard parameters:
我猜是随机的。randint只是第一次尝试实现这个特性。似乎Python开发人员也认为这是一个问题,这就是为什么在v1.5.2中,他们添加了另一个方法randrange和更多的标准参数:
random.randrange([start], stop[, step])
Return a randomly selected element from range(start, stop, step). This is equivalent to choice(range(start, stop, step)), but doesn’t actually build a range object.
从范围(开始、停止、步骤)返回随机选择的元素。这相当于选择(range(start、stop、step)),但实际上并不构建range对象。
You can use randrange
instead of randint
to avoid surprising people.
你可以使用randrange而不是randint来避免让人惊讶。
On the other hand, in many situations where the problem is phrased as 'choose a random number between 1 and 6' it might be more natural to use randint(1, 6)
instead of writing randrange(1, 7)
or randrange(min, max + 1)
.
另一方面,在很多情况下,如果问题是“在1和6之间选择一个随机数”,那么使用randint(1,6)而不是写randrange(1,7)或randrange(min, max + 1)可能更自然。
#3
6
This is speculation, but normal human usage of 'give me a random number from a to b' is inclusive. Implementing it that way sort of makes sense, given Python's general philosophy of being a more human-readable language.
这是推测,但正常的人类使用“给我一个随机数从a到b”是包含的。以这种方式实现它是有意义的,考虑到Python作为一种更易于阅读的语言的一般哲学。
#4
3
I don't think there's a reason for that. But at least it's documented.
我不认为这是有原因的。但至少有记载。
#1
65
I tried to get to the bottom of this by examining some old sources. I suspected that randint
was implemented before Python's long integer: meaning that if you wanted a random number that included INT_MAX
, you would have needed to call random.randrange(0, INT_MAX + 1)
which would have overflowed and resulted in arguments of (0, 0)
or (0, INT_MIN)
depending.
我试图通过查阅一些旧资料来弄清楚事情的真相。我怀疑randint是在Python的长整数之前实现的:这意味着如果您想要一个包含INT_MAX的随机数,您需要调用random。randrange(0, INT_MAX + 1)可能会溢出并导致(0,0)或(0,INT_MIN)依赖的参数。
However, looking as far back as even the Python 1.5.2 sources, in Lib/whrandom.py
we see:
然而,甚至可以追溯到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
was continued to be deprecated in 2.0, 2.1, 2.2, and 2.3; but random.randint
was marked as deprecated in 2.1, although no longer marked as deprecated in 2.2.
whrandom。在2.0、2.1、2.2和2.3中,randint继续被弃用;但是随机的。randint在2.1中被标记为已弃用,尽管在2.2中不再标记为已弃用。
Also, random.py
from version 2.1 is the first to note in random.randint
's docstring:
同时,随机的。第一个注意到的是来自2.1版的py。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.
"""
The only available source older than that is the 0.9.1 source, and as far as I can tell, randint
was not implemented at that point.
唯一可用的数据源是0.9.1源代码,据我所知,randint在那时还没有实现。
Thus, I conclude that the reasoning for randint
including the endpoint is known to only Guido himself at this point; given the docstring from Python 2.1, it sounds like the reason may have been a simple mistake.
因此,我的结论是,randint包括端点的推理在这一点上只有Guido自己知道;考虑到Python 2.1中的docstring,其原因似乎是一个简单的错误。
#2
10
I guess random.randint
was just the first attempt at implementing this feature. It seems that the Python developers also felt that this was a problem, which is why in v1.5.2 they added another method randrange with more standard parameters:
我猜是随机的。randint只是第一次尝试实现这个特性。似乎Python开发人员也认为这是一个问题,这就是为什么在v1.5.2中,他们添加了另一个方法randrange和更多的标准参数:
random.randrange([start], stop[, step])
Return a randomly selected element from range(start, stop, step). This is equivalent to choice(range(start, stop, step)), but doesn’t actually build a range object.
从范围(开始、停止、步骤)返回随机选择的元素。这相当于选择(range(start、stop、step)),但实际上并不构建range对象。
You can use randrange
instead of randint
to avoid surprising people.
你可以使用randrange而不是randint来避免让人惊讶。
On the other hand, in many situations where the problem is phrased as 'choose a random number between 1 and 6' it might be more natural to use randint(1, 6)
instead of writing randrange(1, 7)
or randrange(min, max + 1)
.
另一方面,在很多情况下,如果问题是“在1和6之间选择一个随机数”,那么使用randint(1,6)而不是写randrange(1,7)或randrange(min, max + 1)可能更自然。
#3
6
This is speculation, but normal human usage of 'give me a random number from a to b' is inclusive. Implementing it that way sort of makes sense, given Python's general philosophy of being a more human-readable language.
这是推测,但正常的人类使用“给我一个随机数从a到b”是包含的。以这种方式实现它是有意义的,考虑到Python作为一种更易于阅读的语言的一般哲学。
#4
3
I don't think there's a reason for that. But at least it's documented.
我不认为这是有原因的。但至少有记载。