Python: 列表索引在 while/for 循环内超出范围

Python: List index out of range inside while/for loop

我想做一个Tribonacci序列。 (每个新项目都是该列表中前三个项目的总和。)但是每当我使用 while/for 循环时,它都会显示列表索引超出范围错误。有人能找出这段代码有什么问题吗?

def tribonacci(signature, n):
    count = 0
    newlist = []
    while (len(newlist)<=n):
        newitem = signature[count]+signature[count+1]+signature[count+2]
        newlist.append(newitem)
        count = count+1
    print signature + newlist
tribonacci([1,1,1], 5)

在上面的代码中,我的预期输出是 [1,1,1,3,5,9,17,31]

Traceback (most recent call last):
File "C:\Users\Vasanth\Desktop\sample.py", line 9, in <module>
tribonacci([1,1,1], 5)
File "C:\Users\Vasanth\Desktop\sample.py", line 5, in tribonacci
newitem = signature[count]+signature[count+1]+signature[count+2]
IndexError: list index out of range

简单的解决方案

def tri(original_sig, n):
    sig = original_sig.copy()
    for i in range(n):
        sig.append(sum(sig[i:i+3]))
    return sig

在您的代码中,您将新值附加到 newlist,而不是 signature。因此,在第一次迭代后,您的代码将尝试访问超出 ist

大小的元素 3

第一次迭代后,您已将计数增加到 1,但未以任何方式更新 signature。它包含 3 个项目,因此 count + 2 将尝试索引超出其边界的列表。

相反,您可以只对将新结果附加到的列表的最后 3 项求和:

In [20]: def tribonacci(signature, n):
    ...:     result = list(signature)
    ...:     for _ in range(n):
    ...:         result.append(sum(result[-3:]))
    ...:     return result

或者,如果使用 Python 3 并希望创建一个生成器:

In [34]: from collections import deque
    ...: 
    ...: def tribonacci(signature, n):
    ...:     state = deque(signature, maxlen=3)
    ...:     yield from state
    ...:     
    ...:     for _ in range(n):
    ...:         next_value = sum(state)
    ...:         yield next_value
    ...:         state.append(next_value)
    ...: 

In [35]: tribonacci([1,1,1], 5)
Out[35]: <generator object tribonacci at 0x7f6ae11ef990>

In [36]: list(_)
Out[36]: [1, 1, 1, 3, 5, 9, 17, 31]

让我们将其简化为 MCVE:

signature = [1, 1, 1]
count = 0
while True:
    newitem = signature[count] + signature[count+1] + signature[count+2]
    count = count+1

在第一次迭代中,count0 因此 "problem" 行将有效地成为:

    newitem = signature[0] + signature[1] + signature[2]

因为 signature 是一个 3 项列表,这没问题。现在在第二次迭代中,count1 所以这一行将有效地变成:

    newitem = signature[1] + signature[2] + signature[3]

由于 signature 只有 3 个项目,因此没有 signature[3] 对象 - 您的索引超出范围。

item = [1,1,1]
for i in range(5):
    new = item[i]+item[i+1]+item[i+2]
    item.append(new)
print item
def tribonacci(signature, n):
    count = 0
    newlist = []
    while (len(newlist)<=n):
        newitem = signature[count]+signature[count+1]+signature[count+2]
        newlist.append(newitem)
        count = count+1
        signature.append(newitem)
    print signature
tribonacci([1,1,1], 5)

You were increasing value of counter every time but you were appending new value to signature list. so len of signature remains only 3 and when code tried to get signature list's 4th element it thrown this error.

有问题的原始代码的小修改效果很好:

def tribonacci(signature, n):
    count = 0
    newlist = signature             # change here..
    while (len(newlist)<=(n+3)):    # here..
        newitem = signature[count]+signature[count+1]+signature[count+2]
        newlist.append(newitem)
        count = count+1
    print(newlist)                  # and here.

测试:

tribonacci([1,1,1], 5)
tribonacci([2,2,2], 5)

输出:

[1, 1, 1, 3, 5, 9, 17, 31, 57]
[2, 2, 2, 6, 10, 18, 34, 62, 114]

编辑:如评论中所述,原发送列表将在此处修改。

如果要保留原始列表:

def tribonacci(signature, n):
    count = 0
    newlist = signature.copy()      # get a copy of original list
    while (len(newlist)<=(n+3)):    
        newitem = newlist[count]+newlist[count+1]+newlist[count+2] # use newlist rather than signature
        newlist.append(newitem)
        count = count+1
    print(newlist)

测试:

a = [1,1,1]
tribonacci(a, 5)
print(a)

b = [2,2,2]
tribonacci(b, 5)
print(b)

输出:

[1, 1, 1, 3, 5, 9, 17, 31, 57]
[1, 1, 1]
[2, 2, 2, 6, 10, 18, 34, 62, 114]
[2, 2, 2]