为什么我会收到“索引超出范围错误”的提示?

5
我是Python的初学者,我正在编写一些代码,可以从列表中随机选择一个字母,打印它,然后从列表中删除它,以免再次选择。这个循环通过while循环重复执行。
import random

list = ["a", "b", "c", "d", "e", "f", "g", "h" , "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]

yn = "y"

while yn == "y":
 npat = random.randint(0, 25)
 print(list[npat])
 del list[npat]
 yn = input("Again?: ")

代码运行良好,但有时会随机选取的数显示超出索引范围。

IndexError: list index out of range

在我看来,它应该可以正常工作,但是存在一个问题。有人能找出来吗?

4个回答

7
每次你使用del list[npat],列表就会变短。最终random.randint(0, 25)会给你一个越界的索引。
无关:使用list作为变量名很糟糕,因为你掩盖了内置的list

5

首先,不要将列表命名为list。给它取一个其他的名字。

问题在于每次获取一个字母后,你都会删除该字母。因此,如果列表是[1,2,3],当我获取到3时,3 就被删除了。

这样一来,该列表就只剩下 2 个元素。早些时候,list[2] 是可以工作的。但现在,由于 3 被删除了,list[2] 不再存在。

要么移除删除功能,要么设置一个变量,每次选中一个字母时该变量递减,并使用该变量获取随机数:

import random

lista = ["a", "b", "c", "d", "e", "f", "g", "h" , "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]

yn = "y"
max = 25

while yn == "y":
 npat = random.randint(0, max)
 print(npat)
 print(lista[npat])
 del lista[npat]
 max = max - 1
 yn = input("Again?: ")

“max” 也是一个可调用对象,你知道的。 :) - Chris Wesseling
谢谢,我现在感觉很蠢。我告诉过你我是新手。你的方法很有用,我简直不敢相信我没有发现我的错误。再次感谢! - Hashim Bin Talha
没问题!如果这个有用,请标记为正确! - Ismail Hafeez
@HashimBinTalha 不要觉得自己愚蠢。你问了一个非常好的问题。不要低估这需要的技能。很少有初学者知道如何写出像这样优秀的问题! - Chris Wesseling

2
< p > lista的大小在改变,具体来说,每次迭代它的长度都会减少1。这就是为什么你会得到一个IndexError。< /p> < p > 在循环之前使用random.shuffle,并从列表末尾取出字母,然后你就不需要担心索引了。这样做更简单,目的清晰:随机打印一个字母,不重复,直到所有字母都用完。< /p>
import random

letters = ["a", "b", "c", "d", "e", "f", "g", "h" , "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]
random.shuffle(letters)

yn = "y"

while yn == "y" and letters:
    print(letters.pop())
    yn = input("Again?: ")

1
最佳答案。 :) 我花了几分钟更长时间编写相同的内容。也许是因为我在导入字符串后写了 letters = list(ascii_letters[:26])) :) - Chris Wesseling
好的,我更喜欢使用 letters 这个名称而不是 lista。从 string.ascii_letters 构建 list 比显式地从小写字母表构建要好得多。 - Michael Ruth

0
每次删除一个元素,列表的大小都会减小。因此,在生成介于(0,25)之间的随机数时,有可能生成一个大于列表大小的数字。 因此,不要将大小固定为(0,25),而应将其改为(0,len(lista)-1)。这样做就可以正常工作了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接