Why does
zip(*[xrange(5)]*2)
give [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]
but
zip(*[iter(xrange(5))]*2)
give [(0, 1), (2, 3)]
?
I always though that generator were iterators, so iter
on a generator was a no-op.
For example,
list(iter(xrange(5)))
[0, 1, 2, 3, 4]
is the same as
list(xrange(5))
[0, 1, 2, 3, 4]
(The same is true for Python 3, but with list(zip(
and range
.)
Theres a difference between an iterable and an iterator. You can use iter(x)
to build an iterator for any given iterable x
. An iterator encapsulates the state of an iteration, while an iterable is something you can create a new iterator from.
xrange()
is an iterable, but not an iterator. You can create multiple iterators for a single xrange()
object, and each of it has its own position.
The zip()
function implicitly calls iter()
on each of its arguments. For zip(*[xrange(5)]*2)
, this will create two iterators for the same xrange()
objects, each with its own iteration state. For zip(*[iter(xrange(5))]*2)
, you are already passing in the same iterator twice. Calling iter()
on an iterator simply returns the iterator itself, so that you end up with only a single iterator in this case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With