Generator
mattia
gervaz at gmail.com
Sun Mar 22 16:05:41 EDT 2009
Il Sun, 22 Mar 2009 16:52:02 +0000, R. David Murray ha scritto:
> mattia <gervaz at gmail.com> wrote:
>> Can you explain me this behaviour:
>>
>> >>> s = [1,2,3,4,5]
>> >>> g = (x for x in s)
>> >>> next(g)
>> 1
>> >>> s
>> [1, 2, 3, 4, 5]
>> >>> del s[0]
>> >>> s
>> [2, 3, 4, 5]
>> >>> next(g)
>> 3
>> >>>
>> >>>
>> Why next(g) doesn't give me 2?
>
> Think of it this way: the generator is exactly equivalent to the
> following generator function:
>
> def g(s):
> for x in s:
> yield x
>
> Now, if you look at the documentation for the 'for' statement, there is
> a big "warning" box that talks about what happens when you mutate an
> object that is being looped over:
>
> There is a subtlety when the sequence is being modified by the loop
> (this can only occur for mutable sequences, i.e. lists). An
> internal counter is used to keep track of which item is used next,
> and this is incremented on each iteration. When this counter has
> reached the length of the sequence the loop terminates. This means
> that if the suite deletes the current (or a previous) item from the
> sequence, the next item will be skipped (since it gets the index of
> the current item which has already been treated). Likewise, if the
> suite inserts an item in the sequence before the current item, the
> current item will be treated again the next time through the loop.
>
> As you can see, your case is covered explicitly there.
>
> If you want next(g) to yield 3, you'd have to do something like:
>
> g = (x for x in s[:])
>
> where s[:] makes a copy of s that is then iterated over.
Ok, thanks. Yes, I had the idea that a counter was used in order to
explain my problem. Now I know that my intuition was correct. Thanks.
More information about the Python-list
mailing list