公共列表索引超出范围问题,为什么?[复制]

Common List Index Out Of Range Issue, Why? [duplicate]

提问人:John Smith 提问时间:8/20/2023 更新时间:8/20/2023 访问量:54

问:

import scipy.special


s = [1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3,
     1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6, 1, 2, 1, 3, 1, 2, 1, 4,
     1, 2, 1, 3, 1, 2, 1, 5, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3,
     1, 2, 1, 7, 1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 5,
     1, 2, 1, 3, 1, 2, 1, 4, 1, 2, 1, 3, 1, 2, 1, 6, 1, 2, 1, 3,
     1, 2, 1, 4, 1]


r = []

for n in range(20):
 result = 1
 for k in range(n-1):
     result += (scipy.special.binom(n - 1, k) % 2) * r[s[n - k - 1]]
 r.append(result)


def binomial_transform(sequence):
    n = len(sequence)
    result = [0] * n
    
    for i in range(n):
        for j in range(i+1):
            result[i] += sequence[j] * scipy.special.binom(i, j)
    
    return result

sequence = r
binomial_result = binomial_transform(sequence)
print(binomial_result)

我试着玩结果开始的地方,0 而不是 1,尝试用 1 作为元素初始化 r 而不是空,尝试在范围 n-1 中而不是 k,在范围 n 中尝试 k.当列表 s 是 oeis 序列A000120时,代码工作完美,并且正如预期的那样,它产生了 oeis A101911。现在我把它从 A000120 更改为 A001511它说列表索引超出范围。这让我发疯了。如果我只是在 s 的前面添加另一个数字,它会编译而不会出错,但如果删除一个元素,就会出现错误。

python list math scipy 序列

评论

0赞 Mike 'Pomax' Kamermans 8/20/2023
如果它让你发疯,那就开始记录吧。您在第 17 行收到错误,因此:log 和该行之前。你会看到 是 2、是 0 和 2。那么:此时的尺寸是多少?当您尝试访问时,您会想象会发生什么.nknks[n - k - 1]rr[2]
0赞 John Smith 8/20/2023
呃,对不起,我不明白,你说的日志记录是什么意思?顺便说一句,真的很感谢快速的响应
0赞 Mike 'Pomax' Kamermans 8/20/2023
从字面上记录您正在使用的所有变量。 因为如果你不知道问题,你就无法解决问题:记录你的变量,开始理解问题。print(n, k, s[n - k - 1], len(r))
0赞 John Smith 8/20/2023
哦,好吧,这是有道理的,谢谢,我试试
1赞 Mike 'Pomax' Kamermans 8/20/2023
现在您知道问题所在了,向后工作:此时应该大于 2 个元素吗?然后查看循环中的代码,看看你在哪里成长,以及你是否做对了(因为如果事情出错,我们已经得到的结论是它不是)。它不应该更大吗?在这种情况下,请重新考虑应该访问哪个元素,而不是 .rrs[n - k - 1]

答:

-1赞 hpaulj 8/20/2023 #1

这个答案只是更明确地说明了一些评论的观察结果。

标记的重复项并不是特别有用,因为它侧重于对长度为 n 个项目的列表的时间编制索引的常见情况。这里的问题在于使用中间索引数组,该数组的值可能太大。nth

当我运行您的部分代码时,我得到:

In [2]: len(s)
Out[2]: 105
In [3]: r = []
   ...: 
   ...: for n in range(20):
   ...:  result = 1
   ...:  for k in range(n-1):
   ...:      result += (scipy.special.binom(n - 1, k) % 2) * r[s[n - k - 1]]
   ...:  r.append(result)
   ...: 
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[3], line 6
      4 result = 1
      5 for k in range(n-1):
----> 6     result += (scipy.special.binom(n - 1, k) % 2) * r[s[n - k - 1]]
      7 r.append(result)

显示屏突出显示表情。ipythonr[s[n - k - 1]]

让我们再试一次,用一些打印件:

In [5]: r = []
   ...: for n in range(20):
   ...:  result = 1
   ...:  for k in range(n-1):
   ...:      print(n,k, len(r), len(s),n-k-1)
   ...:      print(r[s[n - k - 1]])
   ...:      result += (scipy.special.binom(n - 1, k) % 2) * r[s[n - k - 1]]
   ...:  r.append(result)
   ...:  print(n,r)
   ...: 
0 [1]
1 [1, 1]
2 0 2 105 1
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[5], line 6
      4 for k in range(n-1):
      5     print(n,k, len(r), len(s),n-k-1)
----> 6     print(r[s[n - k - 1]])
      7     result += (scipy.special.binom(n - 1, k) % 2) * r[s[n - k - 1]]
      8 r.append(result)

IndexError: list index out of range

所以经过几个循环后,有 2 项。n=2r

n-k-1是 2-0-1=1。 是。 引发错误。我不知道你为什么选择元素作为索引。 从空开始,并随着每个追加而增长。但是,的值并没有以任何明显的方式与 的大小相关联。它们的范围从 1 到 7 看似随机。s[1]2r[2]srrsr

像解决这个问题这样的调整,但是以后呢?r[s[n - k - 1]-1]ns

尝试一下,它确实运行到 n=19,结果为:r

19 [1, 1, 2.0, 2.0, 5.0, 2.0, 4.0, 4.0, 10.0, 2.0, 4.0, 4.0, 10.0, 4.0, 8.0, 8.0, 23.0, 2.0, 4.0, 4.0]

同样,这取决于 的值。添加 后,索引范围从 。因此,如果循环中不是太早,它就会运行。但是在一无所知的情况下,这个修复看起来像一个笨拙。s-1r[0,6]6s