我最近回答了一个类似的问题,它归结为:不要修改您正在迭代的序列。
使用自定义迭代器(来自another answer of mine)显示发生了什么:
class CustomIterator(object):
def __init__(self, seq):
self.seq = seq
self.idx = 0
def __iter__(self):
return self
def __next__(self):
print('give next element:', self.idx)
for idx, item in enumerate(self.seq):
if idx == self.idx:
print(idx, '--->', item)
else:
print(idx, ' ', item)
try:
nxtitem = self.seq[self.idx]
except IndexError:
raise StopIteration
self.idx += 1
return nxtitem
next = __next__ # py2 compat
list_A = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
for i in CustomIterator(list_A):
print(list_A.pop())
if 'c' not in list_A:
break
哪些打印:
give next element: 0
0 ---> a
1 b
2 c
3 d
4 e
5 f
6 g
7 h
8 i
9 j
j
give next element: 1
0 a
1 ---> b
2 c
3 d
4 e
5 f
6 g
7 h
8 i
i
give next element: 2
0 a
1 b
2 ---> c
3 d
4 e
5 f
6 g
7 h
h
give next element: 3
0 a
1 b
2 c
3 ---> d
4 e
5 f
6 g
g
give next element: 4
0 a
1 b
2 c
3 d
4 ---> e
5 f
f
give next element: 5
0 a
1 b
2 c
3 d
4 e
所以它并没有因为break 而结束,而是因为它遍历了整个列表(或者更好:直到没有更多的项目!)。
另外'c' not in listA 是O(n) 操作,所以你的循环实际上是O(n**2)。为什么不直接找到'c' 的第一个索引,然后简单地迭代直到出现:
list_A = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
try:
c_index = list_A.index('c')
except ValueError:
# no 'c' in the list, probably should do something more useful here ...
pass
else:
for item in reversed(list_A[c_index:]): # print the items
print(item)
del list_A[c_index:] # remove the items from the list
打印(如预期):
j
i
h
g
f
e
d
c