Вопрос по yield, python, loops, generator, for-loop – Зациклить два генератора вместе

17

У меня два генератора говорят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() возвращает так много значений. Хранение их в списке истощит память, чтоПоэтому я использую генераторы.

Есть ли способ зациклить оба генератора одновременно?

Ваш Ответ

3   ответа
26

Вы былипочти там. В 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); нет необходимости использовать понимание списка там.

Чисто академически, еслиA() дает 1,2,3 иB() дает 4,5,6 это производит,,,,a,b = (1,4)(1,5)(1,6)(2,4)(2,5) ...?(3,6) Adam Smith
@adsmith: это не так. Он производит,(1, 4)(2, 5) а также(3, 6), Вы думаете о.itertools.product() Martijn Pieters
0

сгенерированных в список кортежей, так что вы можете использовать так, как вы хотите:

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

Звучит так, как вы хотите:itertools.izip

from itertools import izip

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

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

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

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

Обратите внимание, что в Python 3 'базовыйzip это как Python 2.xitertools.izip

в этом случае оба списка должны иметь одинаковое количество элементов, а если во втором списке больше элементов, он не будет напечатан Ciasto piekarz
@san, чтобы быть конкретным, какой бы аргумент ни был длиннее, он будет обрезан до длины самого короткого. Если вам нужно обработать пары, это необходимо. Если вы хотите получить как можно больше предметов, есть[i]zip_longestхотя, если один из ваших аргументов, например, У бесконечно длинного генератора у вас будут проблемы. jonrsharpe

Похожие вопросы