我想更改下面的代码

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


当前回答

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

其他回答

使用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)

Itertools.chain()应该做到这一点。它接受多个可迭代对象,并逐个产生结果,大致相当于:

def chain(*iterables):
    for it in iterables:
        for element in it:
            yield element

使用的例子:

from itertools import chain

g = (c for c in 'ABC')  # Dummy generator, just for example
c = chain(g, 'DEF')  # Chain the generator and a string
for item in c:
    print(item)

输出:

A
B
C
D
E
F

我想说的是,正如用户“wjandrea”的评论所建议的那样,最好的解决方案是

def concat_generators(*gens):
    for gen in gens:
        yield from gen

它不会改变返回的类型,并且是真正的python类型。

代码示例:

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

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

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

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