Reputation: 145
I have a piece of code like this:
items1 = ['col1', 'col2']
items2 = ['a', 'b']
items3 = [1, 2]
data = zip(items2, items3)
for col in items1:
print(col)
for d in data:
print(d)
and the output is:
col1
('a', 1)
('b', 2)
col2
It's like the for loop in 'data' works just once. My expected output was some:
col1
('a', 1)
('b', 2)
col2
('a', 1)
('b', 2)
It works if I invert the loops in the nested structure, like:
for d in data:
print(d)
for col in items1:
print(col)
whose output is:
('a', 1)
col1
col2
('b', 2)
col1
col2
printing out all the information but not preserving the order, as I would like to.
Thanks in advance for any suggestion and I am sorry in case the format of the question was not compliant with the site rules (this is my first question here).
Upvotes: 3
Views: 1883
Reputation: 11289
Worth noting that this was one of the big changes between Python 2 and Python 3. In Python 2, map
, zip
, range
, filter
, keys
, values
, items
all returned lists. In Python 3, they return iterators.
If you are used to Python 2, this can be confusing at first.
Upvotes: 0
Reputation: 5871
zip produces an iterator. You use it up once and it's gone. Instead you can store it into a container such as a list, so you can iterate over it as many times as you want.
items1 = ['col1', 'col2']
items2 = ['a', 'b']
items3 = [1, 2]
data = list(zip(items2, items3))
for col in items1:
print(col)
for d in data:
print(d)
Upvotes: 3
Reputation: 531325
Most (if not all) iterators can only be traversed once. The reason this seems confusing is that you are accustomed to iterating over lists, but lists are not iterators. They are iterable, because you can get an iterator for a list. A for
loop implicitly calls iter
on a list, but you can do so explicitly as well.
itr = iter([1,2,3]) # itr is a value of type list_iterator
# Fully consumes itr, outputting
#
# 1
# 2
# 3
for x in itr:
print(x)
# Produces no output, because there is nothing left in itr to iterate over
for x in itr:
print(x)
If you want to iterate over the result multiple times, you either need to call zip
each time,
for col in items1:
print(col)
data = zip(items2, items3)
for d in data:
print(d)
or create a list from the zip
object first.
data = list(zip(items2, items3))
for col in items1:
print(col)
for d in data:
print(d)
Upvotes: 4