2017-08-10 33 views
0

我想實現我自己的itertools.compress版本,問題是我偶然發現了返回類型。我的意思是這兩個函數都返回一個迭代器,但我認爲第二個函數不被視爲生成器函數,因爲裏面沒有yield語句。所以我的問題是,這兩個實現是否相同?`return iterator`和`iterator`產生的區別

def compress (seq, selectors): 
    from operator import itemgetter 
    fst = itemgetter (0) 
    snd = itemgetter (1) 
    yield from map (fst, filter (snd, zip (seq, selectors))) 

def compress (seq, selectors): 
    from operator import itemgetter 
    fst = itemgetter (0) 
    snd = itemgetter (1) 
    return map (fst, filter (snd, zip (seq, selectors))) 

回答

3

不太。

yield from seq相當於for i in seq: yield i

這意味着你的第一實施是一個發生器,從地圖()的結果產生的每個項目,而第二個實現返回地圖對象。

1

儘管它們看起來非常相似,甚至與結果一起輸出,但它們並不相同。

看一下這些基本代碼示例,映射strrange(100)

def do_yield_from(): 
    yield from map(str, range(100)) 


def do_return(): 
    return map(str, range(100)) 

print(do_yield_from()) 
print(do_return()) 

>>> <class 'generator'> 
>>> <class 'map'> 

第一功能是一個generator,從do_yield_from得到的結果和

for r in range(100): yield str(r) 

第二函數返回一個縮短的版本map的一個實例,它是iterator而不是generator

由於第一功能是一個generatoryield fromdo_return

import timeit 
print(timeit.timeit(do_yield_from)) 
>>> 0.53931242968009 

print(timeit.timeit(do_return)) 
>>> 1.467075402143485 
2

所以我的問題是更好的性能,是這兩種實現相同呢?

根本不是。

yield fromreturn是兩個不同的不同的句法結構。

yield from是在PEP380中引入的語法。它被稱爲發電機代表團From the documentation

PEP 380添加了yield from表達式,允許生成器將其部分操作委託給另一個生成器。這允許包含yield的代碼段被分解並放置在另一個生成器中。此外,允許子生成器返回一個值,並將該值提供給委託生成器。

return但是具有完全不同的行爲。 From the documentation

返回可能只出現在語義上嵌套在函數定義中,而不是在嵌套類定義中。

如果存在表達式列表,則對其進行評估,否則替換爲無。

return將表達式列表(或None)當前的函數調用作爲返回值。

基本上yield from <iter>是equivlent到for element in <iter>: yield element,而return將簡單地返回一個值。 就你而言,我相信yield from就是你要找的。您希望yield迭代器的值爲map,而不是return迭代器本身。