2016-08-16 49 views
0

Python中是否有可能產生一個循環中產生值的生成器,或者稱爲普通函數,並返回該循環的最終值?我嘗試設置一個標誌作爲參數,然後根據該標誌選擇屈服還是返回。但是,函數中關鍵字yield的存在將其自動轉換爲生成器,Python抱怨生成器中有return語句。Python中的混合發生器/函數

這裏這樣的功能的例子:

def function(generator=True): 
    a = 0 
    for i in range(10): 
     a = i 
     if generator: 
      yield a 
    if not generator: 
     return a 

這樣的功能會(利用它作爲優化殘留的功能,例如。)當在某些情況下,我需要的只是最終的結果是對我有用的,而在其他情況下,我需要每次迭代後的增量結果(例如,使用機器人的差分模型,使用每個新的速度命令更新機器人的姿態)。現在我有兩個功能,一個是收益率,另一個是收益率。那麼可以將這兩者結合起來嗎?

+0

重複? http://stackoverflow.com/questions/26595895/return-and-yield-in-the-same-function –

+1

創建一個迭代整個生成器並返回最後結果的包裝?這似乎是瘋狂的,相同的功能可以像一個發電機*和*正常功能;分裂這個責任。話雖如此,似乎甚至勉強迭代整個發電機的單個值。你不能直接計算最後的值嗎?*真的*分裂這兩個函數的責任? – deceze

+0

據我所知,這是不可能的,因爲來自機器人的數據代表週期性的馬達編碼器滴答聲(當達到65536時復位爲零)並且需要逐步計算姿態更新,所以它被稱爲「微分」模型所有。包裝仍然是另一個功能,所以我想知道是否可以融合。瘋狂並不總是一個壞的術語:) – Mehdi

回答

1

它仍然是一個生成器,甚至調用return。 反正我不會混合發電機/常規功能。

你可以在迭代器的頂部包裝一些東西,以防需要循環遍歷結果。

一個簡單的代碼,可以做你想做的:

last = None 
for last in function(): pass 

現在最後擁有你想要的值,你可以用它在你的代碼。

發電機內部的回報加入Python 3.3 而且這相當於StopIteration異常(值)

return expr in a generator causes StopIteration(expr) to be raised upon exit from the generator.

In a generator, the statement

return value is semantically equivalent to

raise StopIteration(value) except that, as currently, the exception cannot be caught by except clauses within the returning generator.

+0

即使在建議的問題中重複,人們說返回可以在一個生成器中調用,但在我的情況下,它會導致我的程序崩潰。 SyntaxError:在生成器中帶有參數的'return' – Mehdi

+0

似乎Python 3.3中添加了生成器中的「return」https://www.python.org/dev/peps/pep-0380/#use-of-stopiteration返回值 您使用的是哪個版本? – danielfranca

+0

似乎有道理,返回不允許在Python 2.7中有一個值,我正在使用它。 – Mehdi

1

,您仍需要遍歷它來獲得它的單值,但是你可以再次使用yield而不是return來完成此操作。

>>> def function(generator=True): 
...  a = 0 
...  for i in range(10): 
...   a = i 
...   if generator: 
...    yield a 
...  if not generator: 
...   yield a 
... 
>>> a = function() 
>>> print(*a) 
0 1 2 3 4 5 6 7 8 9 
>>> a = function(0) 
>>> print(a) 
<generator object function at 0x0000000001603240> 
>>> print(*a) 
9 
>>> a = function(0) 

注意,具有return發電機內部是在Python 2 SyntaxError,但不是Python 3的更換returnyield產生在2相同的結果和3

+0

而不是解包,你也可以直接調用'next':'val = next(function(False))'。 – Bakuriu

+0

@Bakuriu - 我認爲,但是用'*'去,因爲它更短,我很懶。 :P – TigerhawkT3