我正在尝试找出如何在元组中过滤元组 像这样:
input>>>filter_tree((1,2,3,4,(1,2,3)),lambda x:x%2==0)
output>>> ((2,4,(2))
这就是我走了多远:
def filter_tree(tree,f):
if type(tree)!=tuple:
return tree
return tuple(filter(f,tuple(filter_tree(node,f) for node in tree)))
当元组中没有元组时,它可以工作,而且我不知道需要进行什么更改才能使其工作(我只能使用递归)。 有人有主意吗?
答案 0 :(得分:2)
这是一个发电机解决方案,也可以使用:
def filter_nested_tuples(iterable, f):
"""filter elements from nested tuples from function f"""
for x in iterable:
if isinstance(x, tuple):
yield tuple(filter_nested_tuples(x, f))
elif f(x):
yield x
def is_even(x):
"""Indicates if number is even"""
return x % 2 == 0
tup = (1,2,3,4,(1,2,3))
print(tuple(filter_nested_tuples(tup, f=is_even)))
# (2, 4, (2,))
注意:与isinstance()
相比,使用type()
的好处是当您想支持多种类型,例如list
,set
,然后您可以只传递以下类型的元组:isinstance(x, (list, set, tuple))
。
答案 1 :(得分:1)
仅将过滤器函数直接应用于非元组元素,并且仅对元组元素执行递归:
def filter_tree(tree, f):
# conditional iteration over all child nodes / leaves
return tuple(elem for elem in tree if type(elem) != tuple and f(elem)) \
+ tuple(filter_tree(node, f) for node in tree if type(node) == tuple)
>>> filter_tree((1,2,3,4,(1,2,3)),lambda x:x%2==0)
(2, 4, (2,))
答案 2 :(得分:1)
我想这就是你想要的。
a = (1,2,3,(1,2,3,(1,2,3,4)))
def func(x):
return x%2==0
def foo(v):
ans = ()
for x in v:
if type(x)==tuple:
ans += (foo(x),)
elif func(x):
ans += (x,)
return ans
print(foo(a))
答案 3 :(得分:0)
保留输入递归结构的另一种单行解决方案:
def filter_tree(tree, filter_func):
return tuple(filter_tree(element, filter_func) if isinstance(element, tuple) else element for element in tree if isinstance(element, tuple) or filter_func(element))
测试
>>> print(filter_tree((0, 1, 2, (3, 4, (5, 6), 7), 8, 9, 10), lambda x: x % 2 == 0))
(0, 2, (4, (6,)), 8, 10)
>>>
大致等同于:
def filter_tree(tree, filter_func):
filtered_tree = tuple()
for element in tree:
if isinstance(element, tuple):
filtered_tree += (filter_tree(element, filter_func),)
elif filter_func(element):
filtered_tree += (element,)
return filtered_tree