Ответ 1
Я думаю, itertools.chain()
должен сделать это.
Я хочу изменить следующий код
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?
Я думаю, itertools.chain()
должен сделать это.
Пример кода:
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
В Python (3.5 или выше) вы можете сделать:
def concat(a, b):
yield from a
yield from b
С помощью 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)
Здесь используется генераторное выражение с вложенными 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]
Если вы хотите, чтобы генераторы разделяли, но все же повторяли их, вы можете использовать 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
Предположим, что мы имеем генераторы (gen1 и gen 2), и мы хотим выполнить некоторый дополнительный расчет, который требует результата обоих. Мы можем вернуть результат такой функции/вычисления с помощью метода карты, который, в свою очередь, возвращает генератор, на который мы можем контактировать.
В этом случае функция/вычисление необходимо реализовать с помощью лямбда-функции. Сложная часть - это то, что мы стремимся делать внутри карты и ее лямбда-функции.
Общая форма предлагаемого решения:
def function(gen1,gen2):
for item in map(lambda x, y: do_somethin(x,y), gen1, gen2):
yield item
Можно также использовать оператор распаковки *
:
concat = (*gen1(), *gen2())
ПРИМЕЧАНИЕ. Наиболее эффективно работает для "не ленивых" итераций. Может также использоваться с различными видами понимания. Предпочтительный способ для генератора concat будет из ответа от @Uduse
Все эти сложные решения...
просто сделайте:
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()