Функция Conjoin, выполненная в функциональном стиле

Недавно, читая 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 ?

Спасибо

5
задан Michael J. Barber 17 August 2011 в 14:47
поделиться