writable iterators?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Wed Jun 22 17:54:31 EDT 2011


On Wed, 22 Jun 2011 15:28:23 -0400, Neal Becker wrote:

> AFAICT, the python iterator concept only supports readable iterators,
> not write. Is this true?
> 
> for example:
> 
> for e in sequence:
>   do something that reads e
>   e = blah # will do nothing
> 
> I believe this is not a limitation on the for loop, but a limitation on
> the python iterator concept.  Is this correct?

Have you tried it? "e = blah" certainly does not "do nothing", regardless 
of whether you are in a for loop or not. It binds the name e to the value 
blah.

>>> seq = [1, 2]
>>> for e in seq:
...     print(e)
...     e = 42
...     print(e)
...
1
42
2
42


I *guess* that what you mean by "writable iterators" is that rebinding e 
should change seq in place, i.e. you would expect that seq should now 
equal [42, 42]. Is that what you mean? It's not clear.

Fortunately, that's not how it works, and far from being a "limitation", 
it would be *disastrous* if iterables worked that way. I can't imagine 
how many bugs would occur from people reassigning to the loop variable, 
forgetting that it had a side-effect of also reassigning to the iterable. 
Fortunately, Python is not that badly designed.

If you want to change the source iterable, you have to explicitly do so. 
Whether you can or not depends on the source:

* iterators are lazy sequences, and cannot be changed because there's 
nothing to change (they don't store their values anywhere, but calculate 
them one by one on demand and then immediately forget that value);

* immutable sequences, like tuples, are immutable and cannot be changed 
because that's what immutable means;

* mutable sequences like lists can be changed. The standard idiom for 
that is to use enumerate:

for i, e in enumerate(seq):
    seq[i] = e + 42



-- 
Steven



More information about the Python-list mailing list