代码之家  ›  专栏  ›  技术社区  ›  Vasanth Prabakar

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

  •  0
  • Vasanth Prabakar  · 技术社区  · 7 年前

    我想做一个Tribonaci序列。(每个新项目都是该列表中前三个项目的总和。)但每当我使用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
    
    6 回复  |  直到 7 年前
        1
  •  3
  •   Ilja Everilä    7 年前

    在第一次迭代之后,您将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]
    
        2
  •  2
  •   bruno desthuilliers    7 年前

    让我们将其简化为MCVE:

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

    在第一次迭代中, count 0 因此,“问题”线将有效地是:

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

    自从 signature 是一个3项列表,这是确定的。现在在第二次迭代中, 计数 1 因此,这条线实际上将成为:

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

    自从 签名 只有3件长,没有 signature[3] 对象-索引超出范围。

        3
  •  2
  •   dangee1705    7 年前

    简单解决方案

    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的大小

        4
  •  0
  •   rnso    7 年前

    对所讨论的原始代码进行少量修改,效果良好:

    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]
    
        5
  •  0
  •   alseether IndiumSoftware    7 年前
    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)
    

    您每次都在增加计数器的值,但却在向签名列表添加新值。 所以签名的长度只剩下3个 当代码试图获取签名列表的第4个元素时,抛出了这个错误。

        6
  •  0
  •   Edson Menegatti    7 年前
    item = [1,1,1]
    for i in range(5):
        new = item[i]+item[i+1]+item[i+2]
        item.append(new)
    print item