嵌套发电机和产量来自?

时间:2018-01-20 20:39:39

标签: python python-3.x generator

我有一个嵌套对象Task.Run,并希望在每个子容器上应用某种类型的过滤器:

Task T = Task.Factory.StartNew(() => { });

保持嵌套结构但仅过滤偶数元素的函数如下所示:

a

但是我想创建一个等效的生成器,它使用一些形式嵌套a = [[1, 2], [3, 4, 5, 6], [7, 7, 8]] 来维护def nested_filter(obj): res = [] for sub_obj in obj: even = [i for i in sub_obj if i % 2 == 0] res.append(even) return res nested_filter(a) # [[2], [4, 6], [8]] 的嵌套结构。

为了说明,这正是我不想要的,因为它会使yield变平:

a

我的理解是aintroduced in Python 3.3可能允许嵌套保留传递对象的结构。但显然我误解了:

def nested_yield(obj):
    """Will flatten the nested structure of obj."""
    for sub_obj in obj:
        for i in sub_obj:
            if i % 2 == 0:
                yield i

list(nested_yield(a))
# [2, 4, 6, 8]

那么,有什么办法可以使用两个生成器函数(即不创建中间列表),这样调用生成器会给我这个:

yield from

1 个答案:

答案 0 :(得分:2)

您希望nested_generator返回一份子列表。在这种情况下,您无法在内层创建临时列表。

因此,您最好的选择是产生过滤后的列表:

>>> def nested_filter(L):
    for l in L:
        yield [i for i in l if i % 2 == 0]


>>> a = [[1, 2], [3, 4, 5, 6], [7, 7, 8]]
>>> list(nested_filter(a))
[[2], [4, 6], [8]]

如果要使用第二个生成器来过滤子列表,可以将返回的迭代器转换为列表,并将yield转换为:

>>> def generator_filter(L):
    for n in L:
        if n % 2 == 0:
            yield n


>>> def nested_filter(L):
    for l in L:
        yield list(generator_filter(l))


>>> a = [[1, 2], [3, 4, 5, 6], [7, 7, 8]]
>>> list(nested_generator(a))
[[2], [4, 6], [8]]