在Python中评估所有嵌套生成器

时间:2017-03-23 22:05:53

标签: python generator

我可以使用这样的递归函数创建一组嵌套的迭代器:

def rprint(n):
    for i in range(n):
        print('n = %d' % n)
        yield rprint(n-1)         

然后,对于一个简单的例子,我可以手动评估嵌套生成器。

>>> p3 = rprint(3)
>>> p3
<generator object rprint at 0x1043b7048>
>>> p2_0 = next(p3)
>>> p2_1 = next(p3)
>>> p2_2 = next(p3)
n = 3
n = 3
n = 3
>>> next(p3) # will raise an error
StopIteration
>>> p1_0_0 = next(p2_0)
>>> p1_0_1 = next(p2_0)
n = 2
n = 2
>>> next(p2_0)# will raise an error
StopIteration
>>> p0_0_0_0 = next(p1_0_0)
n = 1
>>> next(p1_0_0)# will raise an error
StopIteration
>>> p0_0_1_0 = next(p1_0_1)
n = 1
>>> next(p1_0_1)# will raise an error
StopIteration

这样做如下......

>>> p1_1_0 = next(p2_1)
>>> p1_1_1 = next(p2_1)
n = 2
n = 2
>>> next(p2_1)# will raise an error
StopIteration

......等等。

如何以n中的rprint的任何值自动执行此操作? 我对创建中间生成器的变量引用不感兴趣(正如我在示例中所做的那样来说明对象结构)。

3 个答案:

答案 0 :(得分:5)

虽然可以这样做,但使用生成器纯粹用于副作用这样做是一件非常奇怪的事情,你可能想重新考虑你的设计。那说:

def do_the_thing_you_want(generator):
    # Call list on the generator to force all side effects before running
    # subgenerators, as done in the question.
    for subgenerator in list(generator):
        do_the_thing_you_want(subgenerator)

答案 1 :(得分:2)

通过递归展平您的发电机&#34;深度优先&#34;:

def flatten(nested):
    for sublist in nested:
        for element in flatten(sublist):
            yield element

产量

n = 3
n = 2
n = 1
n = 2
n = 1
n = 3
n = 2
n = 1
n = 2
n = 1
n = 3
n = 2
n = 1
n = 2
n = 1

答案 2 :(得分:2)

不完全确定您想要的是什么,但以下代码会展平您的嵌套生成器:

def rprint(n):
    for i in range(n):
        print('n = %d' % n)
        yield rprint(n-1)

def flatten(nested):
    for j in nested:
        if hasattr(j, '__iter__') or hasattr(j, '__getitem__'):
            yield from flatten(j)
        else:
            yield j

list(flatten(rprint(3)))

打印:

# n = 3
# n = 2
# n = 1
# n = 2
# n = 1
# n = 3
# n = 2
# n = 1
# n = 2
# n = 1
# n = 3
# n = 2
# n = 1
# n = 2
# n = 1