我想更改下面的代码

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()

我得到了错误:

不支持+:'generator'和'generator'的操作数类型

如何在Python中连接两个生成器?


当前回答

假设我们有两个生成器(第1代和第2代),我们想要执行一些额外的计算,需要这两个生成器的结果。 我们可以通过map方法返回这种函数/计算的结果,该方法反过来返回一个生成器,我们可以循环使用它。

在这种情况下,函数/计算需要通过lambda函数实现。 棘手的部分是我们打算在映射及其lambda函数中做什么。

建议解决方案的一般形式:

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

其他回答

你也可以使用解包操作符*:

concat = (*gen1(), *gen2())

注意:对于“非惰性”迭代对象最有效。也可以用于不同类型的推导式。生成器concat的首选方式将来自@Uduse的答案

2020年更新:在Python 3和Python 2中都可以工作

import itertools

iterA = range(10,15)
iterB = range(15,20)
iterC = range(20,25)

第一个选项

for i in itertools.chain(iterA, iterB, iterC):
    print(i)

# 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

可选选项,在python 2.6中引入

for i in itertools.chain.from_iterable( [iterA, iterB, iterC] ):
    print(i)

# 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

Itertools.chain()是基本的。

Itertools.chain.from_iterable()很方便,如果你有一个包含可迭代对象的可迭代对象。例如,每个子目录的文件列表,如[["src/server.py", "src/readme.txt"], ["test/test.py"]]]。

简单的例子:

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

使用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代和第2代),我们想要执行一些额外的计算,需要这两个生成器的结果。 我们可以通过map方法返回这种函数/计算的结果,该方法反过来返回一个生成器,我们可以循环使用它。

在这种情况下,函数/计算需要通过lambda函数实现。 棘手的部分是我们打算在映射及其lambda函数中做什么。

建议解决方案的一般形式:

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