简体   繁体   中英

Generators and Lists in Python

Be kind, I'm still learning python (but getting better). I've looked at the other posts regarding generators, and haven't found an answer to my specific question. Sorry, if I missed it.

So I am writing a method that acts as a generator. I can make it work, but not the way I want it to. I'm trying to understand generators.

If I write the following:

def genfunc(self):
    """
    self.some_lst is defined in __init__ as a list of tuples. e.g [(1,2),(2,3)]
    """
    yield (x for x in self.some_lst)

I get

Line 73: TypeError: '<invalid type>' does not support indexing

however, if I write it as:

def genfunc()
    """
    self.some_lst is defined in __init__ as a list of tuples. e.g [(1,2),(2,3)]
    """
    for x in self.some_lst:
        yield x

Everything works fine.

Two questions: 1. What am I fundamentally missing about generators? and 2. Is there a way to write this in one line as I tried (but failed) to do?

I know there are some SOers just waiting to help this newb out. Thanks in advance.

In Python2, you need to write

def genfunc():
    for x in self.some_lst:
        yield x

but in Python3 you could write

def genfunc():
    yield from self.some_lst

See PEP380 -- Syntax for Delegating to a Subgenerator .


yield (x for x in self.some_lst)

does not work since (x for x in self.some_lst) is an object -- a generator expression. So the yield expression merely yields that one object, not the items inside that generator expression.

You are mixing generator expressions with your generator.

yield yields whatever follows, and you have put a generator expression there. Just like a generator function , this produces a generator object:

>>> (x for x in some_lst)
<generator object <genexpr> at 0x100544aa0>

This is what you yielded.

Because you essentially yielded another generator, you couldn't index it, as it was not yielding the 2-value tuples you were expecting.

Since the generator expression itself produces a generator, you could just return that generator expression directly , without using yield :

def genfunc(self):
    """
    self.some_lst is defined in __init__ as a list of tuples. e.g [(1,2),(2,3)]
    """
    return (x for x in self.some_lst)

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