2014-07-07 41 views
0

要善良,我還在學Python(但是越來越好)。我看過關於發電機的其他文章,並沒有找到我的具體問題的答案。對不起,如果我錯過了。Python中的生成器和列表

所以我寫了一個方法,作爲一個生成器。我可以讓它工作,但不是我想要的。我試圖理解發電機。

如果我寫了以下內容:

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) 

我得到

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

但是,如果我把它寫爲:

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 

,一切工作正常。

有兩個問題:1.我基本上對發電機缺少什麼?和2.是否有辦法在我嘗試(但失敗)的時候將它寫在一行中?

我知道有一些SOers只是在等待這個newb出來。提前致謝。

回答

3

您正在混合發電機表達式與您的發電機。

yield會產生以下任何內容,並且您已經在其中放置了生成器表達式。就像一臺發電機功能,這將產生一個生成器對象:

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

這是你得到了什麼。

因爲你基本上已經產生了另一個生成器,所以你不能對它進行索引,因爲它不會產生你期望的2值元組。

由於發電機表達式本身產生了發電機,你可以只返回發生器表達直接,而無需使用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) 
+0

你們搖滾!非常感謝你! – PerryDaPlatypus

3

在Python2,你需要寫

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

但Python3你可以寫

def genfunc(): 
    yield from self.some_lst 

PEP380 -- Syntax for Delegating to a Subgenerator


yield (x for x in self.some_lst) 

因爲(x for x in self.some_lst)不起作用是一個對象 - 發電機表達。因此yield表達式只產生一個對象,而不是該生成器表達式中的項目。

+0

謝謝你,我的困惑來自於一個事實,即「打印最大(X爲X在範圍內(10))的作品,我猜這是產量,會產生差異。 – PerryDaPlatypus

+0

@ user3641109:這也是一個生成器表達式;'max()'遍歷它。 –

+0

@ user3641109:'max(x對於範圍(10)中的x)'相當於'max((x對於範圍(10)中的x))''。所以'max'被應用於一個生成器表達式。一些運算符,如'max'和'sum' [允許省略生成器表達式的括號](http://stackoverflow.com/questions/4799459/why-can-you-omit-the-surrounding-parentheses - 用於發電機式的Python-時-PASSI)。 – unutbu