Python:用于展平包含另一个生成器的生成器的函数

时间:2012-07-16 11:12:28

标签: python python-3.x generator

我想知道如何编写python函数,它可以展平生成器,生成另一个生成器或迭代(也可以产生另一个生成器/迭代......可能是无限的)。

以下是示例:

gen(gen(1,2,3), gen(4,5,6), [7,8,9], [gen(10,11,12), gen(13,14,15)])

注意:gen - 表示生成器对象,gen之后的括号内的内容是将生成gen的数据。

“扁平化”后的预期结果: gen(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)

扁平功能也需要返回发电机! (因为否则,先前使用的发电机将毫无意义)。

请注意,我使用的是python 3。

谢谢!

2 个答案:

答案 0 :(得分:13)

最简单的方法是递归展平功能。假设您想要下降到除字符串之外的每个可迭代项,您可以这样做:

def flatten(it):
    for x in it:
        if (isinstance(x, collections.Iterable) and
            not isinstance(x, str)):
            for y in flatten(x):
                yield y
        else:
            yield x

从Python 3.3开始,您也可以编写

def flatten(it):
    for x in it:
        if (isinstance(x, collections.Iterable) and
            not isinstance(x, str)):
            yield from flatten(x)
        else:
            yield x

答案 1 :(得分:0)

非递归方法本质上是使用堆栈展开递归方法:

def flatten(it):
    stack = []
    it = iter(it)
    while True:
        try:
            x = next(it)
        except StopIteration:
            if stack:
                it = stack.pop()
                continue
            else:
                return
        if isinstance(x, collections.Iterable) and not isinstance(x, str):
            stack.append(it)
            it = iter(x)
        else:
            yield x