Как объединить два генератора в Python? - PullRequest
143 голосов
/ 09 июля 2010

Я хочу изменить следующий код

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()

Я получаю ошибку:

неподдерживаемые типы операндов для +: «генератор» и «генератор»

Как объединить два генератора в Python?

Ответы [ 9 ]

193 голосов
/ 09 июля 2010

Я думаю itertools.chain() должно это сделать.

51 голосов
/ 01 апреля 2015

Пример кода:

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
22 голосов
/ 23 июля 2017

Простой пример:

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
19 голосов
/ 01 декабря 2017

В Python (3.5 или выше) вы можете сделать:

def concat(a, b):
    yield from a
    yield from b
8 голосов
/ 15 января 2016

С помощью 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)
6 голосов
/ 30 апреля 2018

Здесь используется выражение генератора с вложенным for 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]
1 голос
/ 06 ноября 2017

Допустим, нам нужны генераторы (gen1 и gen 2), и мы хотим выполнить некоторые дополнительные вычисления, которые требуют результата обоих.Мы можем вернуть результат такой функции / вычисления через метод map, который, в свою очередь, возвращает генератор, на котором мы можем зацикливаться.

В этом сценарии функция / расчет должны быть реализованы с помощью лямбда-функции.Сложная часть - это то, что мы стремимся сделать внутри карты и ее лямбда-функции.

Общая форма предлагаемого решения:

def function(gen1,gen2):
        for item in map(lambda x, y: do_somethin(x,y), gen1, gen2):
            yield item
1 голос
/ 10 августа 2017

Если вы хотите сохранить генераторы отдельно, но при этом перебирать их одновременно, вы можете использовать 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
0 голосов
/ 05 февраля 2019

Все эти сложные решения ...

просто сделайте:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...