Python for-in-loop停止从for-in-loop创建的列表对象的迭代

时间:2019-01-06 13:13:17

标签: python python-3.x iteration for-in-loop

[第一个Stack-o-flow Python初学者的第一个问题]

我一直在尝试创建一个将数字1附加到10,然后在python列表对象中从10擦除到1的函数。 但是,我成功了,遇到了for-in循环的怪异行为。

以下是我的成功案例:

this.props.posts

将打印:

def a():
    li = []

    for i in range(1,11):
        li.append(i)
        print(li)

    for n in range(1,11):
        li.remove(li[-1])
        print(li)

a()

但是,如果我将其for循环[1] [1, 2] [1, 2, 3] [1, 2, 3, 4] [1, 2, 3, 4, 5] [1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6, 7] [1, 2, 3, 4, 5, 6, 7, 8] [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8] [1, 2, 3, 4, 5, 6, 7] [1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5] [1, 2, 3, 4] [1, 2, 3] [1, 2] [1] [] 的第二部分更改为range(1,11),则迭代将停止,如下所示。

li

会打印:

def a():
    li = []

    for i in range(1,11):
        li.append(i)
        print(li)

    for n in li:         <-------------- THIS PART
        li.remove(li[-1])
        print(li)

a()

因此,我检查了对象[1] [1, 2] [1, 2, 3] [1, 2, 3, 4] [1, 2, 3, 4, 5] [1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6, 7] [1, 2, 3, 4, 5, 6, 7, 8] [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 8] [1, 2, 3, 4, 5, 6, 7] [1, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5] 的长度。

li

会打印:

def a():
    li = []
    for i in range(1,11):
        li.append(i)
        print(li)

    print("Length before passed: ", len(li))

    for n in li: <------------ THIS
        print("Length BEFORE REMOVE: ", len(li))

        li.remove(li[-1])

        print("Length AFTER REMOVE: ", len(li))
        print(li)
a()

这是怎么回事? 为什么python for循环会在其整个周期之前停止?

非常感谢您。

4 个答案:

答案 0 :(得分:5)

在您的情况下,迭代会停止,因为您从头开始进行迭代,但是同时要从尾部删除元素:

  • 第一次迭代以9个元素结束,因此循环进行到第二个元素。
  • 第2次迭代以8个元素结束,因此循环进行到第3个元素
  • ...
  • 第5次迭代以5个元素结束,没有第6个元素可以继续进行,循环结束。

这就是为什么通常不建议在迭代列表时对其进行变异。

答案 1 :(得分:4)

尝试运行此命令,您会立即理解

def a():
    li = []

    for i in range(1,11):
        li.append(i)
        print(li)

    for n in li:
        print(n)
        li.remove(li[-1])
        print(li)

a()

通过删除元素会发生这种情况:

[1]
[1, 2]
[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
1
[1, 2, 3, 4, 5, 6, 7, 8, 9]
2
[1, 2, 3, 4, 5, 6, 7, 8]
3
[1, 2, 3, 4, 5, 6, 7]
4
[1, 2, 3, 4, 5, 6]
5
[1, 2, 3, 4, 5]

答案 2 :(得分:0)

添加然后打印10次,您删除然后打印10次-简化:

a = []
a.append(1)
print(a)         # [1]
a.pop()
print(a)         # []

以空列表开始并添加后打印-以空列表停止并打印。

第二个代码部分的问题是:您在迭代时修改了可迭代对象-通常这是一个坏主意。


如果您更改:

def a():
    li = []

    for i in range(1,11):
        li.append(i)
        print(li)

    while(li):
        li.pop()  # same but easier - removes last element without params
        if(li):   # test if non empty
            print(li)

或优化:

    for _ in  range(len(li)-1): # one less so it stops bevore removing the last elem
        li.pop()
        print(li)

您将获得所需的输出。

答案 3 :(得分:0)

这是因为您要从头到尾迭代列表,并且始终删除最后一个元素。当remove方法更改列表,并且python中的for-in循环考虑到此更改时,您将迭代五个前itens并删除最后五个init。

我的建议是做这样的事情:

def a():
  li = []

  for i in range(1,11):
    li.append(i)
    print(li)

  print("Length before passed: ", len(li))

  # Remove the last item while has items
  while len(li):
    li.pop()