Je veux changer le code suivant
for directory, dirs, files in os.walk(directory_1):
do_something()
for directory, dirs, files in os.walk(directory_2):
do_something()
à ce code:
for directory, dirs, files in os.walk(directory_1) + os.walk(directory_2):
do_something()
Je reçois l'erreur:
type (s) d'opérande non pris en charge pour +: 'générateur' et 'générateur'
Comment joindre deux générateurs en Python?
Je pense que itertools.chain()
devrait le faire.
Un exemple de code:
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
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
En Python (3.5 ou supérieur), vous pouvez faire:
def concat(a, b):
yield from a
yield from b
Avec itertools.chain.from_iterable, vous pouvez faire des choses comme:
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)
Ici, il utilise une expression generator avec des for
s imbriqués:
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]
Disons que nous devons utiliser des générateurs (gen1 et gén2) et que nous souhaitons effectuer des calculs supplémentaires qui nécessitent le résultat des deux ..__ Nous pouvons renvoyer le résultat de cette fonction/calcul par la méthode de la carte, qui renvoie à son tour un générateur sur lequel on peut faire une boucle.
Dans ce scénario, la fonction/le calcul doit être implémenté via la fonction lambda . La partie délicate est ce que nous visons à faire à l’intérieur de la carte et de sa fonction lambda.
Forme générale de la solution proposée:
def function(gen1,gen2):
for item in map(lambda x, y: do_somethin(x,y), gen1, gen2):
yield item
Si vous voulez garder les générateurs séparés tout en les parcourant en même temps, vous pouvez utiliser Zip ():
NOTE: l'itération s'arrête au plus court des deux générateurs
Par exemple:
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
Toutes ces solutions compliquées ...
il suffit de faire:
for dir in director_1, directory_2:
for directory, dirs, files in os.walk(dir):
do_something()
Si vous voulez vraiment "rejoindre" les deux générateurs, alors faites:
for directory, dirs, files in
[x for osw in [os.walk(director_1), os.walk(director_2)]
for x in osw]:
do_something()