递归过滤元组中的元组

时间:2019-01-10 15:43:10

标签: python recursion filter tuples

我正在尝试找出如何在元组中过滤元组 像这样:

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)))  

当元组中没有元组时,它可以工作,而且我不知道需要进行什么更改才能使其工作(我只能使用递归)。 有人有主意吗?

4 个答案:

答案 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()的好处是当您想支持多种类型,例如listset,然后您可以只传递以下类型的元组: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