У python есть встроенная функция для чередования генераторов/последовательностей?
Я заметил, что itertools
не (как мне кажется) не имеет функции, способной перемежать элементы из нескольких других итерируемых объектов (в отличие от их zipping):
def leaf(*args): return (it.next() for it in cycle(imap(chain,args)))
tuple(leaf(['Johann', 'Sebastian', 'Bach'], repeat(' '))) => ('Johann', ' ', 'Sebastian', ' ', 'Bach', ' ')
(Изменить) Причина, о которой я прошу, заключается в том, что я хочу избежать ненужных вложений в zip/flatten.
Очевидно, что определение leaf
достаточно просто, но если есть предопределенная функция, которая делает то же самое, я бы предпочел использовать это или очень четкое выражение генератора. Есть ли такая встроенная функция, в itertools или в какой-либо другой хорошо известной библиотеке или подходящее идиоматическое выражение?
Изменить 2: возможно более четкое определение (с помощью пакета functional
):
from itertools import *
from functional import *
compose_mult = partial(reduce, compose)
leaf = compose_mult((partial(imap, next), cycle, partial(imap, chain), lambda *args: args))
Ответы
Ответ 2
Вы ищете встроенный zip
и itertools.chain.from_iterable
, чтобы сгладить результат:
>>> import itertools
>>> list(zip(['Johann', 'Sebastian', 'Bach'], itertools.repeat(' ')))
[('Johann', ' '), ('Sebastian', ' '), ('Bach', ' ')]
>>> list(itertools.chain.from_iterable(_))
['Johann', ' ', 'Sebastian', ' ', 'Bach', ' ']
Обратите внимание, что я использовал list
только для принудительного вывода. Используя стандартные itertools, альтернативные реализации для leaf
будут:
leaf = lambda *a: itertools.chain.from_iterable(itertools.izip(*a)) # Python 2.x
leaf = lambda *a: itertools.chain.from_iterable(zip(*a)) # Python 3.x