I have an nested object, a
, and want to apply some type of filter on each of its sub-containers:
a = [[1, 2], [3, 4, 5, 6], [7, 7, 8]]
A function to keep the nested structure but filter to only even elements would look like:
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]]
But I would like to create an equivalent generator that uses some form a nested yield
to maintain the nested structure of a
.
This, for illustration, is exactly what I do not want because it flattens a
:
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]
My understanding was that yield from
, introduced in Python 3.3 , might allow for nesting that retains the structure of the passed object. But apparently I am misinterpreting:
def gen1(obj):
for sub_obj in obj:
yield from gen2(sub_obj)
def gen2(sub_obj):
for i in sub_obj:
if i % 2 == 0:
yield i
list(gen1(a))
# [2, 4, 6, 8]
So, is there any way I can use two generator functions (ie not create intermediate lists) so that calling the generator would give me this:
list(nested_generator(a))
# [[2], [4, 6], [8]]
You want your nested_generator
to return a list of sublists. In this case, you cannot get around creating temporary lists at the inner level.
So, your best option is to yield the filtered list:
>>> 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]]
If you want to use a second generator to filter your sub-list, you can convert the iterator returned to a list and yield
that as well:
>>> 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]]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.