【问题标题】:Why am I getting the error "list index out of range"?为什么我收到错误“列表索引超出范围”?
【发布时间】:2020-05-07 15:34:53
【问题描述】:

我编写了一个程序,应该打印出从 0 到 100 的所有合数,但我不断收到错误“列表索引超出范围”

我能做些什么来解决它?

def isPrime(x):
    if x==0:
        return False
    if x==1 or x==2:
        return True
    for i in range(2, x):
        if x%i==0:
            return False
            break
        elif x%i==1:
            return True
        else:
            print("error")

i=0

num = list(range(100))

while i<100:
    if isPrime(num[i]==True):           #I get the error here
        del (num[i])
        i += 1
    else:
        i += 1

print(num)

【问题讨论】:

  • 1 不是质数。最小的素数是2。更多 x==1 测试到前一个案例。
  • 您正在使用del (num[i]) 间歇性地从列表中删除元素,因此大小将不再是100
  • 您应该在尝试使用之前测试您的isPrime 函数,它目前已损坏。因为它会为任何奇数返回True
  • 这是错误的:if isPrime(num[i]==True): 您将bool 作为参数传递给isPrime,这显然不会满足您的要求。您可能打算拥有if isPrime(num[i])==True:,但这是不好的形式。只需使用if isPrime(num[i]):已经bool。您无需通过将其与 True 进行比较来仔细检查。

标签: python list indexing


【解决方案1】:

因为如果您的条件为真,您将删除一个元素,但仍会增加i。将您的代码更改为以下内容:

def isPrime(x):
    if x==0:
        return False
    if x==1 or x==2:
        return True
    for i in range(2, x):
        if x%i==0:
            return False
    return True

i=0
lim = 100
num = list(range(lim))

while i<lim:
    if isPrime(num[i])==True:           #I get the error here
        del (num[i])
        lim -=1
    else:
        i += 1

print(num)

顺便说一句,您的代码包含一个错误if isPrime(num[i]==True),我已对其进行了更改。

输出:

[0, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 30, 32, 33, 34, 35, 36, 38, 39, 40, 42, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 60, 62, 63, 64, 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 98, 99]

由于您的isPrime 算法也不正确,因此我已更正。

【讨论】:

  • 您的输出缺少很多合数,第一个是 9。
  • @ThierryLathuille 这就是他的算法。我刚刚删除了错误。
  • @ThierryLathuille 现在我还更正了isPrime 算法。
  • @ThierryLathuille 顺便说一句,他只想知道为什么会收到错误消息,这也是问题的标题,而不是他的 isPrime 函数是否正确。因此,否决这个答案是没有意义的。
  • @ThierryLathuille 你的说法是错误的。它正在迭代所有元素。你测试过代码吗?只需打印num[i],您将看到所有数字都传递到isPrime 函数中,不仅是奇数,而且没有一个偶数被跳过。如果您保留对此代码正在执行的正确新元素的引用,则在迭代时删除列表中的元素并没有什么大的禁忌。请再次阅读代码。
【解决方案2】:

因为您在循环访问列表时正在编辑列表。在索引 74 处,该索引不再存在,因为列表的长度为 73。请注意,您的主要功能似乎无法按预期工作。

from math import sqrt
from itertools import count, islice

def isPrime(n): # Taken from https://stackoverflow.com/questions/4114167/checking-if-a-number-is-a-prime-number-in-python/27946768#27946768
    if n < 2:
        return False

    for number in islice(count(2), int(sqrt(n) - 1)):
        if n % number == 0:
            return False

    return True


num = list(range(100))
to_delete = []

for i in num:
    if isPrime(i):           #I get the error here
        to_delete.append(i)

final = [n for n in num if n not in to_delete]

print(final)

正确的输出:

[0, 1, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 30, 32, 33, 34, 35, 36, 38, 39, 40, 42, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 60, 62, 63, 64, 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 98, 99]

【讨论】:

  • 您从stackoverflow.com/a/27946768/550094 的最后一段代码中抄袭了该答案的整个第一部分,甚至没有给出归属,这在 SO 上是不可接受的。
  • @ThierryLathuille 抱歉没有意识到,只是表明他的主要功能无法正常工作。我会修改的,谢谢!
  • 请注意,最好直接构建要保留的值列表,而不是要删除的值列表...
猜你喜欢
  • 2020-10-11
  • 1970-01-01
  • 2023-02-22
  • 1970-01-01
  • 2014-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多