我很难理解《用Python自动化无聊的东西》一书中的魔术8球程序。该程序基本上在一个列表中有一堆消息,然后使用 random.randint 方法随机选择其中一条消息。代码如下:
import random
messages = ['It is certain',
'It is decidedly so',
'Yes definitely',
'Reply hazy try again',
'Ask again later',
'Concentrate and ask again',
'My reply is no',
'Outlook not so good',
'Very doubtful']
print(messages[random.randint(0, len(messages) - 1)])
如您所见,该程序相当简单。我的问题是关于最后一行。他为什么要从消息长度中减去 1?random.randint 方法不应该从所有消息中选择一些东西,而不仅仅是一些。有 9 条消息,但减去一条意味着只有 8 条消息通过 random.randint 方法。有人可以解释一下为什么他从消息长度中减去 1 吗?
提前感谢您的回复!
Python 索引从 0 开始,而不是 1。 如果列表中有 9 个条目,则需要一个介于 0-8 之间的随机整数。
messages
是一个列表。列表的索引从 0 到 n-1,其中 n 是列表中的元素数,这也是 length
函数返回的长度。但是,您实际上不需要担心这一点,因为您可以使用
print(random.choice(messages))
这将产生与random.choice
从列表中选择随机元素相同的结果。
假设您有一个包含 3 个对象的列表,并且您想要打印列表的第 3 个元素。
>>> s = [1,2,3]
>>> print(s[3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
这会导致索引超出范围错误,因为列表中的元素是从零开始计数的,而不是从 1 开始计数的。
但是如果你检查列表的长度,它会说这个列表有 3 个元素。
>>> s = [1,2,3]
>>> print(len(s))
3
当您在 random.randint(0,len(s))
中传递列表的 len 值时,范围变为 4 (0-3( 而不是 3 (0-2(。
为了解决这个问题,我们将镜头减去一random.randint(0,len(s)-1)
,使范围为 3 (0-2(。
现在 randint 无法选择数字 3 并将其传递给列表索引,因此不再有错误。
"random.randint 方法不应该从所有消息中选择一些东西,而不仅仅是一些。
random.randint 方法对列表一无所知。如果我们看一下 randint 的文档:
random.randint(a, b(
返回一个随机整数 N,使得 a <= N <= b。
因此,如果我们做 random.randint(1, 3(,它会给我们 1、2 或 3。
要获得从 0 到 9 的随机数,我们将按照您所说的进行操作,只需从 0 到 len(messages( 执行 random.randint,然后使用该数字从列表中获取随机索引。问题是你的列表是 9 个项目,所以索引从 0 到 8(最后一项是消息[8](。这称为基于 0 的索引。最后一个索引的位置始终等于长度减去 1。所以这就是为什么我们要做负一。我只是想澄清和扩展这一点,因为您描述的某些内容不太准确。
print(messages[random.randint(0, len(messages( - 1(](
0 是列表的第一个索引,-1 是列表的最后一个索引。这行代码从第一个(0 - 在本例中为"确定"(和最后一个(-1 - 在本例中为"非常可疑"(之间的列表中打印一个随机索引。我很业余,但我确定我昨天在书中读到了这个。
书中说"这种方法的好处是,您可以轻松地在消息列表中添加和删除字符串,而无需更改其他代码行。