关于魔术 8 球程序的问题,其中包含来自 Automate the Boring Stuff with Python 的



我很难理解《用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 - 在本例中为"非常可疑"(之间的列表中打印一个随机索引。我很业余,但我确定我昨天在书中读到了这个。

书中说"这种方法的好处是,您可以轻松地在消息列表中添加和删除字符串,而无需更改其他代码行。

最新更新