没有“for”的列表理解[重复]
Posted
技术标签:
【中文标题】没有“for”的列表理解[重复]【英文标题】:List comprehension without 'for' [duplicate] 【发布时间】:2018-03-11 13:39:01 【问题描述】:在 Python 中处理列表时,我通常只想从列表中过滤掉项目。
numbers = [5, 1, 4, 2, 7, 4]
big_nums = [num for num in numbers if num > 2]
对我来说,这似乎是不必要的冗长。我必须在两个单独的语句 (num for num ...
) 中定义和使用 num,即使我没有对 num
进行任何操作。
我尝试了[num in numbers if num > 2]
,但是 python 用这个抛出了一个SyntaxError
。
在 Python 中有更简洁的方法吗?
编辑:
我的问题是是否有更好的方法来做我在 Python 中尝试做的事情。很多时候,Python 中有一个我不知道的构造,但它使我的代码更好、更易读。
我不是在问filter
和列表理解之间的性能权衡。我对列表理解没有任何问题,但在我了解列表理解之前,我对使用标准 for
循环构建列表也没有任何问题。
【问题讨论】:
这似乎是一个代码高尔夫问题,不是一个实用的问题,Python 代码是为了可读[num in numbers if num > 2]
使您看起来好像在尝试使用包含 in
表达式的三元表达式 (x if y else z
),而您只是忘记了 else 子句
注意:骗子会回答你的问题等等。一个简单的“列表理解替代”谷歌搜索会将其作为第一个结果。
FWIW,如果 numbers
是一维 Numpy 数组,你可以这样做 numbers[numbers>2]
“应该有一种——最好只有一种——明显的方法。虽然这种方法一开始可能并不明显,除非你是荷兰人。” ;)
【参考方案1】:
好吧,您可以使用filter
,它速度较慢且可读性差,但您不需要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
之外的其他数字类型,这也可以。
【讨论】:
很好地使用__lt__
! +1
而且可能更快,因为没有 lambda
可能从运营商导入lt
会更“pythonic”?
让-弗朗索瓦说的话。此外,您可以使用 splat 解包而不是调用 list
构造函数:[*filter((2).__lt__, numbers)]
。但我同意标准的列表组合方式更好,即使重复有点烦人。
@Chris_Rands 也许,因为直接调用 dunder 方法通常是不被接受的; OTOH,在某些情况下直接调用 dunder 方法是有意义的,恕我直言,这就是其中之一。但是,当然,仅使用 OP 抱怨的标准列表组合语法就更加 Pythonic。 ;)以上是关于没有“for”的列表理解[重复]的主要内容,如果未能解决你的问题,请参考以下文章
使用带有两个'for'工作的listcomp来压缩列表? [重复]