Python Iterables struggling using map() built-in

Chris Angelico rosuav at gmail.com
Sun Dec 7 13:22:08 EST 2014


On Mon, Dec 8, 2014 at 2:29 AM, Ned Batchelder <ned at nedbatchelder.com> wrote:
> 3. The only operation supported on iterators is next().  You cannot start
> them over, you cannot ask if there will be more values, you cannot find out
> how many values there will be, you can't ask what the last value was, etc.
> By supporting only one operation, they allow the broadest possible set of
> implementations.

Technically, this is one of only two operations *guaranteed to be*
supported on iterators (the other being that `iter(iterator) is
iterator`). There are plenty of iterators which do more than that, but
all iterators are guaranteed to support next() and nothing more. (For
instance, a generator object is an iterator, and it supports a lot
more operations.)

> 5. The "for NAME in EXPR" construct is equivalent to this:
>
>     expr_iter = iter(EXPR)
>     try:
>         while True:
>             NAME = next(expr_iter)
>             ..DO_SOMETHING..
>     except StopIteration:
>         pass

Small subtlety: The body of the for block is _not_ guarded by the
try/except. It's more like this:

expr_iter = iter(EXPR)
while True:
    try: NAME = next(expr_iter)
    except StopIteration: break
    ..DO_SOMETHING..

> NOTE: THIS EXAMPLE IS HORRIBLE.  This code is crazy-confusing, and should
> never have been used as an example of iteration. It layers at least three
> iterations on top of each other, making it very difficult to see what is
> going on.  It uses "while iters" where "while True" would do exactly the
> same thing (iters will never be false).

There's one way for iters to be false, and that's if you give it no
arguments at all. I've only just noticed this now, as I responded
earlier with a suggestion to try passing it no args, which won't work
because of that (or at least, won't work in Py2; in Py3, iters will
indeed never be false, unless you use list() to coalesce the map).
This is something which definitely ought to have been given a comment.
Or, more usefully, a guarding 'if' before the loop, rather than
needlessly checking at every iteration - if you want an infinite loop
guarded by a precondition, write it as such so the subsequent reader
can see that that's your intention.

ChrisA



More information about the Python-list mailing list