Соедините два генератора вместе

У меня есть два генератора: A() и B(). Я хочу перебирать оба генератора вместе. Что-то вроде:

for a,b in A(),B():    # I know this is wrong
    #do processing on a and b

Один из способов - сохранить результаты как функций в списках, так и затем перебрать объединенный список. Что-то вроде этого:

resA = [a for a in A()]
resB = [b for b in B()]
for a,b in zip(resA, resB):
    #do stuff

Если вам интересно, тогда да, обе функции дают равное количество значений.

Но я не могу использовать этот подход, потому что A()/B() возвращает столько значений. Хранение их в списке исчерпало память, поэтому я использую генераторы.

Можно ли каким-либо образом перекрыть оба генератора?

Ответы

Ответ 1

Ты был почти там. В Python 3 просто передайте генераторы на zip():
for a, b in zip(A(), B()):

zip() принимает любые итеративные, а не только списки. Он будет потреблять генераторы один за другим.

В Python 2 используйте itertools.izip():

from itertools import izip

for a, b in izip(A(), B()):

В стороне, превращение генератора в список так же просто, как list(generator); нет необходимости использовать там понимание списка.

Ответ 2

Похоже, что вы хотите itertools.izip:

from itertools import izip

for a, b in izip(A(), B()):

Из документов:

Как zip(), за исключением того, что он возвращает итератор вместо списка.

Таким образом, вы никогда не создаете list, либо из A(), B(), либо izip().

Обратите внимание, что в Python 3 basic zip похож на Python 2.x itertools.izip.

Ответ 3

Вы можете использовать zip-функцию для преобразования двух списков, сгенерированных в список кортежей, так что вы можете использовать так, как хотите:

for a,b in zip(A(), B()):
    pass