2010-07-09 14 views
99

我想下面的代碼如何在Python中連接兩個生成器?

for directory, dirs, files in os.walk(directory_1): 
    do_something() 

for directory, dirs, files in os.walk(directory_2): 
    do_something() 

更改此代碼:

for directory, dirs, files in os.walk(directory_1) + os.walk(directory_2): 
    do_something() 

我得到的錯誤:

unsupported operand type(s) for +: 'generator' and 'generator'

如何加入兩臺發電機在Python?

+1

我也像Python這樣的工作方式。得到完全一樣的錯誤! – 2013-08-28 21:46:05

回答

141

我認爲itertools.chain()應該這樣做。

+1

http://docs.python.org/library/itertools.html – reto 2010-07-09 08:30:57

+3

是的,這正是'chain()'是用於 – 2010-07-09 09:00:14

+16

當使用itertools.chain來連接兩個迭代時,就像問題一樣,但是在可迭代的(例如'chain(* imap(xrange,xrange(5)))')中的所有迭代中,您可能會遇到[Python bug#4806](http://bugs.python.org/issue4806)掩蓋迭代器中引發的任何TypeError,並導致一個令人困惑的錯誤消息。或者,在這種情況下,你可以使用'itertools.chain.from_iterable'(從Python 2.6開始),它直接將可迭代的iterables作爲參數:'chain.from_iterable(imap(xrange,xrange(5)))''。 – 2013-07-10 18:07:20

29

的代碼示例:

from itertools import chain 

def generator1(): 
    for item in 'abcdef': 
     yield item 

def generator2(): 
    for item in '123456': 
     yield item 

generator3 = chain(generator1(), generator2()) 
for item in generator3: 
    print item 
5

隨着itertools.chain.from_iterable你可以做這樣的事情:

def genny(start): 
    for x in range(start, start+3): 
    yield x 

y = [1, 2] 
ab = [o for o in itertools.chain.from_iterable(genny(x) for x in y)] 
print(ab) 
1

簡單的例子:

from itertools import chain 
x = iter([1,2,3])  #Create Generator Object (listiterator) 
y = iter([3,4,5])  #another one 
result = chain(x, y) #Chained x and y 
0

如果你想保留生成器分開,但仍然在迭代它們的同時,您可以使用zip():

注:迭代停止在兩臺發電機

例如較短的:

for (root1, dir1, files1), (root2, dir2, files2) in zip(os.walk(path1), os.walk(path2)): 

    for file in files1: 
     #do something with first list of files 

    for file in files2: 
     #do something with second list of files 
0

比方說,我們要發電機(Gen1和第2代),我們要進行一些額外的計算即需要兩者的結果。 我們可以通過映射方法返回這種函數/計算的結果,然後返回一個我們可以循環的生成器。

在這種情況下,函數/計算需要通過lambda函數來實現。 棘手的部分是我們在地圖和它的lambda函數中所做的目標。

提出的解決方案的一般形式爲:

def function(gen1,gen2): 
     for item in map(lambda x, y: do_somethin(x,y), gen1, gen2): 
      yield item 
+2

你應該考慮發佈一些有用的解釋,而不僅僅是代碼塊 – AK47 2017-11-06 00:21:45

1

在Python3 +你可以這樣做:

def concat(a, b): 
    yield from a 
    yield from b