不使用'for'的列表推导式

5
通常在 Python 中,当我使用列表时,我最终想要的是从列表中过滤出特定的项目。
numbers = [5, 1, 4, 2, 7, 4]
big_nums = [num for num in numbers if num > 2]

对我来说,这似乎过于冗长了。我必须在两个独立的语句中定义和使用num(num for num ...),即使我没有对num进行任何操作。
我尝试了[num in numbers if num > 2],但是Python会抛出一个SyntaxError
在Python中是否有更简洁的方法来做到这一点?
编辑:
我的问题是在Python中是否有更好的方法来完成我想要做的事情。在Python中有很多时候,我不知道某个构造方式,但它可以使我的代码更好、更易读。
我不是在问filter和列表推导之间的性能权衡。我没有使用列表推导之前,用标准的for循环构建列表也没有问题。

2
这似乎是一个编码竞赛问题,而不是实际问题,Python代码应该易读。 - Chris_Rands
1
"[num in numbers if num > 2]" 看起来像是你试图使用一个三元表达式(x if y else z),其中包含一个 in 表达式,而你只是忘记了 else 子句。 - Edward Minnix
1
注意:重复问题将回答您的问题以及更多内容。一个简单的“列表推导式替代方案”谷歌搜索会把它作为第一个结果呈现出来。 - cs95
3
如果numbers是一个一维的Numpy数组,你可以通过numbers[numbers>2]来获取大于2的元素。FWIW,这句话的意思是提供一个参考,仅供参考,不必全盘接受。 - PM 2Ring
1
应该有一种——最好只有一种——明显的方法来做到这一点。虽然除非你是荷兰人,否则这种方式可能一开始并不明显。 ;) - PM 2Ring
显示剩余4条评论
1个回答

9

好的,你可以使用filter,它比较慢且可读性不如for,但是你不需要使用for

list(filter(lambda x: x > 2, numbers))

或者:

list(filter((2).__lt__, numbers))

然而,仅使用类似这样的魔法方法是脆弱的,只有列表中只包含整数时才能工作。正如Chris_Rands所指出的那样,通常使用operator.lt

from functools import partial
from operator import lt
list(filter(partial(lt, 2), numbers))

如果列表中包含除 int 外的其他数字类型,那也同样适用。


6
很好地使用了__lt__!+1 - Ajax1234
3
可能更快,因为没有 Lambda。 - Jean-François Fabre
1
可能从operator导入lt更符合Python风格? - Chris_Rands
1
Jean-François所说的话。此外,您可以使用splat unpacking而不是调用list构造函数:[*filter((2).__lt__, numbers)]。但我同意标准列表推导式的方式更好,即使重复有点烦人。 - PM 2Ring
3
也许因为直接调用Dunder方法通常是不被看好的;另一方面,有些情况下直接调用Dunder方法是有意义的,在我看来这就是其中之一。但当然,更符合Python风格的做法是使用OP所抱怨的标准列表推导式语法。;) 注:OTOH指的是“On The Other Hand”,IMHO指的是“In My Humble Opinion”。 - PM 2Ring

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