簡體   English   中英

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

在第一次迭代之后,您已將count增加到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]

簡單的解決方案

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 因此,在第一次迭代之后,您的代碼將嘗試訪問元素3,這超出了ist的大小

讓我們將其簡化為MCVE:

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

在第一次迭代中, count0因此“問題”行將有效為:

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

由於signature是3個項目的列表,因此可以。 現在在第二次迭代中, count1因此該行將有效地變為:

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

由於signature只有3個項目,因此沒有signature[3]對象-您的索引為OutOfRange。

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)

您每次都在增加計數器的值,但您要在簽名列表中附加新值。 因此簽名的len僅保留3,並且當代碼嘗試獲取簽名列表的第4個元素時,拋出此錯誤。

對原始代碼進行一些小的修改很有效:

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]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM