任意嵌套列表的过滤函数

4
我无法将这个函数写成lambda表达式,因为存在双重条件语句。
def f(e):
    if not isinstance(e,list):
        if e >10:
            return e
    else:
        return filter(None,[f(y) for y in e])
my_list=[[1], [2,[3,12, [4,11,12]]], [5,6,13,14],[15]]

>>> f(my_list)
[[[12, [11, 12]]], [13, 14], [15]]

此外,编写过滤任意嵌套列表的函数时,什么是Pythonic方法


1
你想在e不是一个列表且e<=10的情况下返回None吗?除了双重条件之外,更为严重的是函数的递归性质。当函数没有名称可调用时,你打算如何进行递归? - Rory Daulton
7
用 Pythonic 的方式编写这样一个函数,不使用 lambda 表达式的形式。 - John Coleman
1
那么应该返回什么?函数总是会返回一些东西--如果没有遇到return语句,那么会返回None - Rory Daulton
你最终会得到一个非常难以阅读的函数。它必须是一个lambda吗? - Christian Dean
@RoryDaulton 我无法复现你的结果,我得到了一个列表 (使用Python2.7)。 - user2314737
显示剩余5条评论
2个回答

5
首先,如果将过滤或映射函数定义为常规函数通过def来提高可读性是没有问题的 - 请记住"可读性很重要,稀疏比密集好"。仅因为该语言中有内联lambda函数,并不意味着您必须将逻辑压缩到其中。
由于最终要构建任意列表深度的通用解决方案,因此可以通过map() + filter()递归应用过滤函数来删除None值:
def filter_function(e):
    if isinstance(e, list):
        return filter(None, map(filter_function, e))
    elif e > 10:
        return e

my_list = list(filter_function(my_list))  

请注意,在Python 3.x中需要使用list(),因为filter()不会返回列表

演示:

>>> my_list = [[1], [2, [3, 12, [4, 11, 12]]], [5, 6, 13, 14], [15]]
>>> 
>>> def filter_function(e):
...     if isinstance(e, list):
...         return filter(None, map(filter_function, e))
...     elif e > 10:
...         return e
... 
>>> 
>>> print(list(filter_function(my_list)))
[[[12, [11, 12]]], [13, 14], [15]]

2

好的,这不是最佳实践,但您可以创建一个lambda函数:使用括号来分组条件:

f = lambda e: filter(None, [f(y) for y in e]) if isinstance(e, list) else (e if e > 10 else None)

my_list = [[1], [2, [3, 12, [4, 11, 12]]], [5, 6, 13, 14], [15]]

>>> f(my_list)
[[[12, [11, 12]]], [13, 14], [15]]

针对Python 3用户:

f = lambda e: list(filter(None, [f(y) for y in e])) if isinstance(e, list) else (e if e > 10 else None)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接