Недавно, читая Python "Functional Programming HOWTO" , я наткнулся на упомянутые там test_generators. py
стандартный модуль, в котором я нашел следующий генератор:
# conjoin is a simple backtracking generator, named in honor of Icon's
# "conjunction" control structure. Pass a list of no-argument functions
# that return iterable objects. Easiest to explain by example: assume the
# function list [x, y, z] is passed. Then conjoin acts like:
#
# def g():
# values = [None] * 3
# for values[0] in x():
# for values[1] in y():
# for values[2] in z():
# yield values
#
# So some 3-lists of values *may* be generated, each time we successfully
# get into the innermost loop. If an iterator fails (is exhausted) before
# then, it "backtracks" to get the next value from the nearest enclosing
# iterator (the one "to the left"), and starts all over again at the next
# slot (pumps a fresh iterator). Of course this is most useful when the
# iterators have side-effects, so that which values *can* be generated at
# each slot depend on the values iterated at previous slots.
def simple_conjoin(gs):
values = [None] * len(gs)
def gen(i):
if i >= len(gs):
yield values
else:
for values[i] in gs[i]():
for x in gen(i+1):
yield x
for x in gen(0):
yield x
Мне потребовалось время, чтобы понять, как он работает. Он использует изменяемый список значений
для хранения полученных результатов итераторов, а итератор N + 1 возвращает значения
, которые проходят через всю цепочку итераторов.
Когда я наткнулся на этот код, читая о функциональном программировании, я начал думать, можно ли переписать этот конджайн-генератор, используя функциональное программирование (используя функции из модуля itertools
).
Существует множество подпрограмм, написанных в функциональном стиле (просто взгляните на конец этой статьи в разделе «Рецепты»).
Но, к сожалению, я не нашел никакого решения.
Итак , возможно ли написать этот конджайн-генератор, используя функциональное программирование, используя только модуль itertools
?
Спасибо