Reputation: 122082
I have a function that yields 2 parts of a list:
>>> x = [1,2,3,4,5,6]
>>> def fold(ls):
... for i in range(0,2):
... yield x[:i]
... yield x[i:]
...
I understand that it still returns as 1 generator although there're more than 1 yield in the function:
>>> fold(x)
<generator object fold at 0x13f9320>
>>> t1, t2 = fold(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: too many values to unpack
To access them, I have could:
>>> for i in fold(x):
... print i
...
[]
[1, 2, 3, 4, 5, 6]
[1]
[2, 3, 4, 5, 6]
I want to perform different operation on these two, so i would need some sort of access like this:
>>> for i in fold(x):
... t1, t2 = i
... print t1, t2 # because
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ValueError: need more than 0 values to unpack
I could use some tricks on the odd/even-ness of the yields and do the following but is there any other way?
>>> for i,j in enumerate(fold(x)):
... if i & 0x1:
... print 't1', j
... else:
... print 't2', j
...
t2 []
t1 [1, 2, 3, 4, 5, 6]
t2 [1]
t1 [2, 3, 4, 5, 6]
Upvotes: 2
Views: 3157
Reputation: 31260
If you can't change the original generator as in freakish' answer, there is an easy way to make a generator that yields items from any iterable in pairs.
def pairwise(iterable):
"""Yield items from iterable two at a time. If the number of items in iterable is
odd, the last one is never yielded."""
iterator = iter(iterable)
while True:
# Use the fact that .next() raises StopIteration when done, as we
# need to raise that too
yield iterator.next(), iterator.next()
Now you can do
for t1, t2 in pairwise(fold(x)):
Upvotes: 2
Reputation: 56477
Just yield a tuple:
yield x[:i], x[i:]
Then you can do:
for i in fold(x):
t1, t2 = i
or even better
for t1, t2 in fold(x):
...
Side note: the first ValueError comes from the fact that you are trying to unpack a generator. No matter what the generator is you will always get this exception if number of variables on the left side is different then the number of items the generator will yield. This is a coincidence, but what you were looking for is probably something like this:
t1, t2 = list(fold(x))[0]
Upvotes: 5