我想更改下面的代码

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

其他回答

如果你想从一个已知目录之前和之后获取文件路径列表,你可以这样做:

for r,d,f in os.walk(current_dir):
    for dir in d:
        if dir =='after':
                after_dir = os.path.abspath(os.path.join(current_dir, dir))
                for r,d,f in os.walk(after_dir): 
                    after_flist.append([os.path.join(r,file)for file in f if file.endswith('json')])
                              
        elif dir =='before': 
                before_dir = os.path.abspath(os.path.join(current_dir, dir))
                for r,d,f in os.walk(before_dir):
                    before_flist.append([os.path.join(r,file)for file in f if file.endswith('json')])

我知道有更好的答案,这是我觉得简单的代码。

(免责声明:仅限Python 3 !)

与你想要的语法相似的是使用splat操作符展开两个生成器:

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

解释:

这有效地执行了将两个生成器的单层扁平化为3元组的n元组(来自os.walk),如下所示:

((directory1, dirs1, files1), (directory2, dirs2, files2), ...)

然后for循环遍历这个n元组。

当然,通过简单地用括号替换外括号,你可以得到一个3元组的列表,而不是3元组的n元组:

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

结果如下:

[(directory1, dirs1, files1), (directory2, dirs2, files2), ...]

Pro:

这种方法的优点是不需要导入任何东西,也不需要大量代码。

Con:

缺点是将两个生成器转储到一个集合中,然后遍历该集合,有效地进行了两次传递,可能会使用大量内存。

您可以将任何生成器放入列表中。虽然不能组合生成器,但可以组合列表。这样做的缺点是实际上在内存中创建了3个列表,但优点是可读性非常好,不需要导入,并且是单行习惯用法。

OP解决方案。

for directory, dirs, files in list(os.walk(directory_1)) + list(os.walk(directory_2)):
    do_something()
a = range(20)
b = range(10,99,3)
for v in list(a) + list(b):
    print(v) 

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

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

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

简单的例子:

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