我想更改下面的代码

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中连接两个生成器?


当前回答

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

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

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

其他回答

在Python(3.5或更高版本)中,您可以执行以下操作:

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

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

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

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

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

如果你只需要做一次,不希望再导入一个模块,有一个简单的解决方案…

只做:

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

如果你真的想“联接”两个生成器,那么做:

for directory, dirs, files in (
        x for osw in [os.walk(directory_1), os.walk(directory_2)] 
               for x in osw
        ):
    do_something()

如果你想保持生成器的分离,但仍然在同一时间遍历它们,你可以使用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

这里使用了一个带有嵌套for的生成器表达式:

range_a = range(3)
range_b = range(5)
result = (item
    for one_range in (range_a, range_b)
    for item in one_range)
assert list(result) == [0, 1, 2, 0, 1, 2, 3, 4]

for…在…从左到右求值。for之后的标识符建立一个新变量。而one_range在下面用于…在…,来自第二个的项用于“final”赋值表达式,该表达式只有一个(在最开始)。