索引错误:列出索引超出范围 - 当它显然不是时



非常直接的随机密码生成程序。

我正在生成8个唯一的随机数,将这些数字分配给一个变量,并使用该变量从alpha列表中打印出一个唯一的字符。

问题是我得到了一个";IndexError:列表索引超出范围";在运行程序的某些时候出错。我仔细检查了一下,它所说的超出范围的数字完全在范围内,因为它们要么是3,要么是55,等等。我认为IndexError只会弹出阿尔法列表(例如阿尔法[c5](,而不是实际的数字列表。

我错过了什么?请温柔一点,我是编程新手。如果这是个愚蠢的问题,我很抱歉。

from random import random, sample
alpha = ['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','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','0','1','2','3','4','5','6','7','8','9']
nums = sample(range(0,63),8)
print(nums)
c1 = nums[0]
c2 = nums[1]
c3 = nums[2]
c4 = nums[3]
c5 = nums[4]
c6 = nums[5]
c7 = nums[6]
c8 = nums[7]
print(alpha[c1],alpha[c2],alpha[c3],alpha[c4],alpha[c5],alpha[c6],
alpha[c7],alpha[c8],end='')

63应该是一个62,标准的一次性错误。简单修复:nums = sample(range(0, len(alpha)), 8)(或者更简洁地说,nums = sample(range(len(alpha)), 8)(。

您将使用甚至更为简洁的一行实现您的结果:print(sample(alpha, 8)),它可以直接对元素进行采样,而不需要范围。

查看random.sample的文档,了解更多使用技巧。https://docs.python.org/3/library/random.html#functions-对于整数

nums = sample(range(0,63),8)

这意味着:选择range中0到63之间的8个值(不包括0和63(,然后使用这些值将其索引到alpha中。

这是不必要的复杂。直接采样alpha

letters = sample(alpha, 8)

这就是该方法的工作原理。range没有什么神奇之处。它不是语言语法的一部分,也不会导致任何函数或语言结构以特殊方式表现。它只是另一个对象。random.sample的要点是,您从序列(从概念上讲,它按定义的顺序包含多个值(开始,然后获得它的一些元素。range是一个序列。但列表或字符串也是如此。

通过尝试指定长度,只会增加复杂性和错误源。没有理由做这样的索引。


但要回答提出的实际问题/担忧:

有些时候我正在运行程序

当然,是的。您正在随机选取值,并且几乎所有值都是有效的。

我仔细检查了一下,它说的超出范围的数字完全在范围内

否;没有导致问题的数字在范围内。如果它们超出范围,那么在尝试使用它进行索引后,您将无法看到该值,因为问题会首先发生。

除非您在使用值进行索引之前检查了所有值(您的print语句显然没有这样做(,并且一直等到您运行了发生错误的程序,并且在运行时看到,所有值都是有效的,否则您没有任何证据表明";这些值在"范围"内;。

你对";它所说的数字超出了范围";因为你不知道它说的是哪个数字超出了范围。您不知道这一点的原因是错误消息没有说明导致问题的值。(在我看来,这是Python内置程序的一个缺点;当您尝试使用dict并获得KeyError时,确实向您显示了类似的信息。(

您可以通过使用try块来包装每次索引尝试来找到答案:

try:
print(f'the first letter is {alpha[c1]}')
except IndexError:
print(f'c1 is equal to {c1}, which is not a valid index for alpha')

但正如你所能想象的,这很快就会变得非常乏味。最好不要像这样寻找bug,以一种一开始就不会有这样bug的方式编写代码

如果有一种简单的方法可以避免索引,请不要使用索引。

我认为IndexError只会为alpha列表(例如alpha[c5](弹出,而不是实际的nums列表。

正确。nums有8个元素,因为它是如何通过random.sample创建的。您得到的元素0到7(包括0到7(都是有效的索引。这些数字是硬编码的,不会失败。

CCD_ 19等中的结果值是随机决定的。它们可能会随机失效。

您可以使用alpha的len来代替您的范围

nums = sample(range(0, len(alpha)), 8)

最新更新