How does for-loop actually work in python

冷暖自知 提交于 2020-06-17 09:43:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!