问题
I used to thought that for-loop in python work like this
it first makes an iterator by doing iter(iterable)
then does next(that_new_iterator_object)
and when it raises StopIteration then for-loop ends and goes to else block (if provided)
but here it is working differently
>>> a = [1,2,3,4,5,6,7,8,9]
>>> for i in a:
del a[-1]
print(i)
1
2
3
4
5
where are the other numbers 6,7,8,9 the new iterator object that for-loop creates and variable a is different
回答1:
The for loop works just as you described. However, here is how a list iterator works, roughly:
class ListIterator:
def __init__(self, lst):
self.lst = lst
self.idx = 0
def __iter__(self):
return self
def __next__(self):
if self.idx >= len(self.lst):
raise StopIteration
else:
val = self.lst[self.idx]
self.idx += 1
return val
IOW, the iterator depends on the list, which you are modifying.
So observe:
>>> class ListIterator:
... def __init__(self, lst):
... self.lst = lst
... self.idx = 0
... def __iter__(self):
... return self
... def __next__(self):
... if self.idx >= len(self.lst):
... raise StopIteration
... else:
... val = self.lst[self.idx]
... self.idx += 1
... return val
...
>>> a = list(range(10))
>>> iterator = ListIterator(a)
>>> for x in iterator:
... print(x)
... del a[-1]
...
0
1
2
3
4
>>>
回答2:
The iterator object holds a reference to the list, it doesn't copy it to iterate over.
You're shortening the list on each iteration, the iterator quits when it runs out at 5 items.
(That said, mutating an iterable while iterating over it is not a good practice; dicts will outright complain if you do that.)
回答3:
That is roughly how a for-loop works. You can rewrite it like that to prove to yourself that the behaviour is the same:
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for_iter = iter(a)
>>> while True:
... try:
... i = next(for_iter)
... del a[-1]
... print(i)
... except StopIteration:
... break
...
1
2
3
4
5
>>>
iter(a) doesn't hold its own references to all of the elements in a, just to the list itself.
来源:https://stackoverflow.com/questions/61446972/how-does-for-loop-actually-work-in-python