简体   繁体   中英

Iteration on nested list and generators and yield

I was looking at creating a simple generator to sum the values of two list with nested values. Using from stack this answer https://stackoverflow.com/a/17014386/461887 and this answer What does the "yield" keyword do in Python?

So I created 2 lists

a = ([1, 2], [2, 3])

b = ([3, 4], [5, 6])

created a generator which errored.

In [10]: def sumNest(item1, item2):
    ...:     try:
    ...:         for i in iter(item1):
    ...:             for j in iter(item2):
    ...:                 yield i + j
    ...:     except TypeError:
    ...:         yield item
    ...:         

I can create it without error but it doesn't work(in the way I expect).

In [14]: def sumNest(item1, item2):
    ...:     try:
    ...:         for i in iter(item1):
    ...:             for j in iter(item2):
    ...:                 k = (i + j)
    ...:                 yield k
    ...:     except TypeError:
    ...:         yield item
    ...:         

Result of my use expecting the summed output.

In [17]: sumNest(a, b)
Out[17]: <generator object sumNest at 0x7f313e6e74b0>

In [18]: answer = sumNest(a, b)

In [19]: answer
Out[19]: <generator object sumNest at 0x7f313e6e7230>

In [20]: print answer
<generator object sumNest at 0x7f313e6e7230>

In [21]: answer(a, b)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-21-badcb4bdaf5d> in <module>()
----> 1 answer(a, b)

TypeError: 'generator' object is not callable

Which led me to go back a bit and get this result where instead of addition of lists as expected I ended up with concatentation.

a = ([1, 2], [2, 3])

b = ([3, 4], [5, 6])

for i in a:
    ...:     for j in b:
    ...:         print(i + j)
    ...:         
[1, 2, 3, 4]
[1, 2, 5, 6]
[2, 3, 3, 4]
[2, 3, 5, 6]

Now thats a nice result, but not again expected(addition expected) so a result like:

([4, 6], [7, 9])

What is it that I am not getting about iteration, lists and yeild that I need to?

A generator object needs to be looped over :

for summed in sumNest(a, b):
    print summed

Alternatively, you can use the next() function on a generator to get one value from it.

Your first example had a syntax error, because you misspelled yield . Your exception handler tries to yield item , but the function doesnt actually define that name.

Note that neither of your solutions flattens the lists, you are still 'summing' tuples.

Working example:

>>> a = ([1, 2], [2, 3])
>>> b = ([3, 4], [5, 6])
>>> def summedProduct(iter1, iter2):
...     for i in iter(iter1):
...         for j in iter(iter2):
...             yield i + j
... 
>>> for summed in summedProduct(a, b):
...     print summed
... 
[1, 2, 3, 4]
[1, 2, 5, 6]
[2, 3, 3, 4]
[2, 3, 5, 6]

If instead you wanted to flatten the lists, flatten them first , then zip() the flattened results together to sum:

def summedNested(nested1, nested2):
    flattened1 = (v for nested in nested1 for v in nested)
    flattened2 = (v for nested in nested2 for v in nested)
    for i, j in zip(flattened1, flattened2):
        yield i + j

Demo:

>>> def summedNested(nested1, nested2):
...     flattened1 = (v for nested in nested1 for v in nested)
...     flattened2 = (v for nested in nested2 for v in nested)
...     for i, j in zip(flattened1, flattened2):
...         yield i + j
... 
>>> for summed in summedNested(a, b):
...     print summed
... 
4
6
7
9

answer是生成器对象,您可以从中生成(生成)列表:

result = list(answer)

Simply calling a generator will give you a generator object. You need to iterate it or use next function with it, to get the values. For example,

next(sumNest(a, b))

would have worked for you. Or iterating with a loop

for item in sumNext(a, b):
    print item

For example

def sumNest(item1, item2):
  try:
      for i in iter(item1):
          for j in iter(item2):
              k = (i + j)
              yield k
  except TypeError:
      yield item1

print next(sumNest([1, 2], [3, 4]))
print
for item in sumNest([1, 2], [3, 4]):
    print item,

Output

4

4 5 5 6

And when you say, I created 2 lists

a = ([1, 2], [2, 3])
b = ([3, 4], [5, 6])

you created tuples not lists .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM