[Tutor] iterators

Chris “Kwpolska” Warrick kwpolska at gmail.com
Sat Jan 18 10:22:20 CET 2014


On Sat, Jan 18, 2014 at 9:51 AM, Keith Winston <keithwins at gmail.com> wrote:
> I don't really get iterators. I saw an interesting example on
> Stackoverflow, something like
>
> with open('workfile', 'r') as f:
>     for a, b, c in zip(f, f, f):
> ....
>
> And this iterated through a, b, c assigned to 3 consecutive lines of
> the file as it iterates through the file. I can sort of pretend that
> makes sense, but then I realize that other things that I thought were
> iterators aren't (lists and the range function)... I finally succeeded
> in mocking this up with a generator:
>
> gen = (i for i in range(20))
> for t1, t2, t3 in zip(gen, gen, gen):
>     print(t1, t2, t3)

For Python 2, use xrange() instead to get an iterator.  In Python 3,
range() is already an iterator.

> So I'm a little more confident of this... though I guess there's some
> subtlety of how zip works there that's sort of interesting. Anyway,
> the real question is, where (why?) else do I encounter iterators,
> since my two favorite examples, aren't... and why aren't they, if I
> can iterate over them (can't I? Isn't that what I'm doing with "for
> item in list" or "for index in range(10)")?

range() actually returns a list.  Lists are not iterators, as next(L)
would’ve told you:

In [1]: next([1, 2])
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-8f9d1ea34edf> in <module>()
----> 1 next([1, 2])

TypeError: list object is not an iterator

You can, however, get an iterator of a list, by doing iter(L):

In [2]: iter([1, 2])
Out[2]: <listiterator at 0x2ef1dd0>

Moreover:

> The ``for`` statement is used to iterate over the elements of a
> sequence (such as a string, tuple or list) or other iterable object.
                                                    (from help('for'))

Basically, this is how `for i in X` works:

1. get an iterator by calling X.__iter__() (equivalent to iter(X))
2. assign `i` to X.next() (or X.__next__() in Python 3; equivalent to next(X))
3. if a `break` statement occurs anywhere, get out of the `for` block;
   elif StopIteration is raised, the `else` block is executed (if any)
                                 and then the program continues;
   else, go to step 2.

Here is a poor man’s pure-python re-implementation of `for`:
https://gist.github.com/Kwpolska/8488091

This should clear up most of your doubts.

-- 
Chris “Kwpolska” Warrick <http://kwpolska.tk>
PGP: 5EAAEA16
stop html mail | always bottom-post | only UTF-8 makes sense


More information about the Tutor mailing list