Python Iterables struggling using map() built-in

Chris Angelico rosuav at gmail.com
Sun Dec 7 06:29:35 EST 2014


On Sun, Dec 7, 2014 at 3:44 AM, Ivan Evstegneev <webmailgroups at gmail.com> wrote:
> (quoting from the book)
> Because this code uses iter and next, it works on any type of iterable. Note
> that there
> is no reason to catch the StopIteration raised by the next(it) inside the
> comprehension
> here when any one of the arguments’ iterators is exhausted—allowing it to
> pass ends
> this generator function and has the same effect that a return statement
> would.

I'd just like to point out something here that's about to change. In
future versions of Python (starting with 3.5 with a governing
directive, and always happening in 3.7), it *will* be important to
catch the StopIteration. You can read more about it in PEP 479:

https://www.python.org/dev/peps/pep-0479/

By the way, your email would have been far better sent as plain text.
It's a bit messy here.

>>>> k= myzip(1, 2, 3, 4)
>
>>>> next(k)
>
>
>
> I got this result:
>
>
>
> Traceback (most recent call last):
>
>   File "<pyshell#73>", line 1, in <module>
>
>     next(k)
>
>   File "<pyshell#65>", line 2, in myzip
>
>     iters = list(map(iter, args))
>
> TypeError: 'int' object is not iterable

We'll get back to this later.

> 1.     >>> L = [1, 2, 3, 4]
>>>> iter(L) is L
>
> False --->  According to the “theory” it’s OK, because list doesn’t have
> self iterators.

That's because L is a list, not an iterator. A list is iterable, but
since you can iterate over it more than once, it returns a separate
list_iterator whenever you call iter() on it.

>>>> S = 'spam'
>
>>>> iter(S) is S
>
> False  --->        Same about strings

Again, strings are iterable, they are not iterators.

>>>>L = [1, 2, 3, 4]
>
>>>> k = iter(L)

That's calling iter on L

>             >>> list(map(iter, L))

That's calling iter on *every element of* L.

> 2.     Why strings are allowed “to become” an iterators(self-iterators)?
> Maybe because of files(reading from file) ?

Because a string is a sequence of characters. You can iterate over a
string to work with its characters.

> Why the infinite loop would be there and why should list() to make it
> finite?  o_0

If you play around with it, you'll see why the infinite loop happens.
Actually, even simpler: try calling that zip function with no
arguments, and see what happens.

I would suggest not trying to rewrite zip(), but develop your own
iterator workings, in order to better understand what's going on. In
fact, you can completely avoid map(), using only a longhand form of
generator expression; and if you do that, you can easily switch in a
list comprehension and see exactly what it's doing.

But regardless of the above, I suggest reading through the section
"Explanation of generators, iterators, and StopIteration" in PEP 479.
It explains some important concepts which are best kept separate in
your head, as conflating them will only confuse.

ChrisA



More information about the Python-list mailing list