web-dev-qa-db-ja.com

Pythonで2つのジェネレーターを結合するには?

次のコードを変更したい

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で2つのジェネレーターを結合するには?

148
Homer Xing

itertools.chain() でやるべきだと思う。

196
Philipp

コードの例:

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
53
Cesio

簡単な例:

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
23
user1767754

Python(3.5以降)では次のことができます。

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

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)
9
andrew pate

ここでは、ネストされたforsで generator expression を使用しています。

a = range(3)
b = range(5)
ab = (i for it in (a, b) for i in it)
assert list(ab) == [0, 1, 2, 0, 1, 2, 3, 4]
5
Alexey

ジェネレーター(gen1とgen 2)が必要で、両方の結果を必要とする追加の計算を実行するとします。このような関数/計算の結果をmapメソッドを介して返すことができます。mapメソッドは、ループできるジェネレーターを返します。

このシナリオでは、関数/計算はラムダ関数を介して実装する必要があります。トリッキーな部分は、マップとそのラムダ関数内で行うことです。

提案されたソリューションの一般的な形式:

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

これらすべての複雑なソリューション...

ただやる:

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

両方のジェネレーターを本当に「結合」したい場合は、次のようにします。

for directory, dirs, files in 
        [x for osw in [os.walk(director_1), os.walk(director_2)] 
               for x in osw]:
    do_something()
0
Camion

ジェネレーターを分離したまま、同時にそれらを繰り返したい場合は、Zip()を使用できます。

注:反復は2つのジェネレーターの短い方で停止します

例えば:

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
DivideByZero