Reputation: 83
There is a quite simple code below:
data = "123456"
b = iter(data)
print(*b)
print(*zip(b, b))
def pairwise(iterable):
"s -> (s0, s1), (s2, s3), (s4, s5), ..."
a = iter(iterable)
return zip(a, a)
print(*pairwise(data))
The result is:
1 2 3 4 5 6
('1', '2') ('3', '4') ('5', '6')
However if we would comment out 4th string like this:
#print(*b)
The result will be:
('1', '2') ('3', '4') ('5', '6')
('1', '2') ('3', '4') ('5', '6')
Im a little bit confused since I never thought that * operator might change variables? What is going on here ? :)
Thanks in advance!
Upvotes: 2
Views: 84
Reputation: 20249
Any iteration done to an iterator changes the state of the iterator. This includes unrolling done by the *
operator. By the way, this is why zip(b,b)
doesn't get you ('1', '1') ('2', '2') ('3', '3') ('4', '4') ('5', '5') ('6', '6')
You would get the same effect if you did list(b)
, for instance:
>>> data = "123456"
>>> b = iter(data)
>>> list(b)
['1', '2', '3', '4', '5', '6']
>>> print(*zip(b, b))
>>> def pairwise(iterable):
... "s -> (s0, s1), (s2, s3), (s4, s5), ..."
... a = iter(iterable)
... return zip(a, a)
...
>>> print(*pairwise(data))
('1', '2') ('3', '4') ('5', '6')
>>> data = "123456"
>>> b = iter(data)
>>> print(*zip(b, b))
('1', '2') ('3', '4') ('5', '6')
>>> def pairwise(iterable):
... "s -> (s0, s1), (s2, s3), (s4, s5), ..."
... a = iter(iterable)
... return zip(a, a)
...
>>> print(*pairwise(data))
('1', '2') ('3', '4') ('5', '6')
If you want to avoid that, you could unroll it into a tuple (for instance) and just use that tuple:
>>> data = "123456"
>>> b = iter(data)
>>> b = tuple(b)
>>> print(*b)
1 2 3 4 5 6
>>> print(*zip(b, b))
('1', '1') ('2', '2') ('3', '3') ('4', '4') ('5', '5') ('6', '6')
>>> def pairwise(iterable):
... "s -> (s0, s1), (s2, s3), (s4, s5), ..."
... a = iter(iterable)
... return zip(a, a)
...
>>> print(*pairwise(data))
('1', '2') ('3', '4') ('5', '6')
>>> data = "123456"
>>> b = iter(data)
>>> b = tuple(b)
>>> print(*zip(b, b))
('1', '1') ('2', '2') ('3', '3') ('4', '4') ('5', '5') ('6', '6')
>>> def pairwise(iterable):
... "s -> (s0, s1), (s2, s3), (s4, s5), ..."
... a = iter(iterable)
... return zip(a, a)
...
>>> print(*pairwise(data))
('1', '2') ('3', '4') ('5', '6')
Notice that in these cases, zip(b,b)
does result in ('1', '1') ('2', '2') ('3', '3') ('4', '4') ('5', '5') ('6', '6')
.
Upvotes: 3