Python for-in-loop 停止对从 for-in-loop 创建的列表对象的迭代
Python for-in-loop stops iteration on list object created from for-in-loop
[来自第一个 Stack-o-flow Python 初学者的第一个问题]
我一直在尝试创建一个函数,将数字 1 附加到 10,然后在 python 列表对象中从 10 擦除到 1。
然而,我成功了,我遇到了 for-in 循环的奇怪行为。
以下是我所做的并取得了成功:
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()
将打印:
[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]
[]
但是,如果我将其 for 循环的第二部分 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()
将打印:
[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]
Length before passed: 10
Length BEFORE REMOVE: 10
Length AFTER REMOVE: 9
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Length BEFORE REMOVE: 9
Length AFTER REMOVE: 8
[1, 2, 3, 4, 5, 6, 7, 8]
Length BEFORE REMOVE: 8
Length AFTER REMOVE: 7
[1, 2, 3, 4, 5, 6, 7]
Length BEFORE REMOVE: 7
Length AFTER REMOVE: 6
[1, 2, 3, 4, 5, 6]
Length BEFORE REMOVE: 6
Length AFTER REMOVE: 5
[1, 2, 3, 4, 5] <---- And it stops here.
这是怎么回事?
为什么 python for 循环会在其完整循环之前停止?
非常感谢。
试试运行这个,马上就明白了
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]
在您的例子中,迭代停止是因为您从头开始迭代,但同时从末尾删除元素:
- 第一次迭代以 9 个元素结束,因此循环继续到第二个元素。
- 第二次迭代以 8 个元素结束,因此循环进行到第三个元素
- ...
- 第 5 次迭代以 5 个元素结束,没有第 6 个元素可继续,循环结束。
这就是为什么在迭代列表时改变列表通常是不可取的。
你 add 然后打印 10 次,你 remove 然后打印 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)
你得到了想要的输出。
这是因为您从头到尾迭代列表,并且总是删除最后一个元素。当 remove 方法更改列表和来自 python 的 for-in 循环考虑这种更改时,您迭代前五个 itens 并删除最后五个。
我的建议是这样做:
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()
[来自第一个 Stack-o-flow Python 初学者的第一个问题]
我一直在尝试创建一个函数,将数字 1 附加到 10,然后在 python 列表对象中从 10 擦除到 1。 然而,我成功了,我遇到了 for-in 循环的奇怪行为。
以下是我所做的并取得了成功:
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()
将打印:
[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]
[]
但是,如果我将其 for 循环的第二部分 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()
将打印:
[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]
Length before passed: 10
Length BEFORE REMOVE: 10
Length AFTER REMOVE: 9
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Length BEFORE REMOVE: 9
Length AFTER REMOVE: 8
[1, 2, 3, 4, 5, 6, 7, 8]
Length BEFORE REMOVE: 8
Length AFTER REMOVE: 7
[1, 2, 3, 4, 5, 6, 7]
Length BEFORE REMOVE: 7
Length AFTER REMOVE: 6
[1, 2, 3, 4, 5, 6]
Length BEFORE REMOVE: 6
Length AFTER REMOVE: 5
[1, 2, 3, 4, 5] <---- And it stops here.
这是怎么回事? 为什么 python for 循环会在其完整循环之前停止?
非常感谢。
试试运行这个,马上就明白了
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]
在您的例子中,迭代停止是因为您从头开始迭代,但同时从末尾删除元素:
- 第一次迭代以 9 个元素结束,因此循环继续到第二个元素。
- 第二次迭代以 8 个元素结束,因此循环进行到第三个元素
- ...
- 第 5 次迭代以 5 个元素结束,没有第 6 个元素可继续,循环结束。
这就是为什么在迭代列表时改变列表通常是不可取的。
你 add 然后打印 10 次,你 remove 然后打印 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)
你得到了想要的输出。
这是因为您从头到尾迭代列表,并且总是删除最后一个元素。当 remove 方法更改列表和来自 python 的 for-in 循环考虑这种更改时,您迭代前五个 itens 并删除最后五个。
我的建议是这样做:
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()