0

这是一个很难解释的问题。我在玩 Python 的列表方法,尤其是del索引对象。我想创建一个简单的脚本,它会创建一个从 1 到 100 的整数列表,然后是一个 for 循环,它会从列表中删除奇数。

这是我写的脚本:

def main():
    num = list(range(1,101))
    print(num)
    for i in range(0,101):
        del num[i]
    print(num)
main()

似乎它会正常工作?我也是这么想的,直到我运行它。

我不知道为什么,但是当i传递给del num[i]索引时,数字本身翻了一番。

当我运行它时,我收到了IndexError: list assignment index out of range.

当我将参数从 更改range(0,101)为 时range(0,10),我发现它删除了从 1 到 20 的所有奇数。

换句话说,i在索引不应该翻倍的时候。我能得到一些关于这方面的信息吗?

4

5 回答 5

6

删除项目时列表的大小会减小。在大约 50 次循环迭代之后,列表中有大约 50 个项目,因此嵌套迭代尝试删除列表之外的某些内容。

这是一个模拟运行:

>>> a = [1, 2, 3, 4, 5]
>>> a
[1, 2, 3, 4, 5]
>>> del a[0]
>>> a
[2, 3, 4, 5]
>>> del a[1]
>>> a
[2, 4, 5]
>>> del a[2]
>>> a
[2, 4]
>>> del a[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
于 2015-08-17T19:32:41.673 回答
0

您遍历从 0 到 101 的范围,并在每次迭代时从num中删除一项,因此 num 的长度正在减少,您最终会得到一个IndexError

于 2015-08-17T19:36:01.567 回答
0

当您在 for 循环中使用关键字时,它会从您创建的原始列表中del完全删除该项目。num通过这样做,您的列表的长度会随着循环的每次迭代而变得越来越小。

这也解释了为什么它只删除奇数,因为每次删除后索引都会向下移动,从而允许偶数从程序的裂缝中溜走:

num = range(1, 5)  # num = [1, 2, 3, 4]
del num[0]  # results in num = [2, 3, 4]
del num [1]  # deletes 3, and num now = [2, 4]
etc. for a longer loop

要删除奇数,请考虑使用条件检查%2 == 0状态和list.remove()方法:

num = range(1, 101)
for i in num:
    if i % 2 != 0:
        num.remove(i)
print(num)

或 main() 函数中的列表理解:

return [x for x in num if x % 2 == 0]
于 2015-08-17T19:47:06.810 回答
0

这个问题与迭代同一个列表非常相似,通过下面的链接可以帮助您更好地理解这种情况mutatinglist

http://gsb-eng.com/why-python-list-mutation-is-not-a-good-idea/

于 2015-08-17T20:09:53.123 回答
0

对于第二个 for 循环,您应该使用总索引的一半,因为在第 50 次迭代时,将删除 50 个元素,因此列表的总索引减少到 50 ,因此在第 51 次迭代时,它显示 out of范围误差。

于 2021-05-06T13:03:58.443 回答