从Python列表中过滤元素?

时间:2010-04-16 20:37:40

标签: python list list-comprehension

我想从列表列表中过滤元素,并使用lambda迭代每个元素的元素。例如,给出列表:

a = [[1,2,3],[4,5,6]]

假设我只想保留列表总和大于N的元素。我试着写:

filter(lambda x, y, z: x + y + z >= N, a)

但是我收到了错误:

 <lambda>() takes exactly 3 arguments (1 given)

如何在将每个元素的值分配给x,y和z时进行迭代?像zip一样的东西,但对于任意长的列表。

感谢,

P.S。我知道我可以使用:filter(lambda x:sum(x)...,a)写这个,但这不是重点,想象这些不是数字而是任意元素,我想将它们的值赋给变量名。< / p>

7 个答案:

答案 0 :(得分:31)

当我们使用其他技术时,将lambdafilter一起使用是有点傻。

在这种情况下,我可能会以这种方式解决特定问题(或使用等效的生成器表达式)

>>> a = [[1, 2, 3], [4, 5, 6]]
>>> [item for item in a if sum(item) > 10]
[[4, 5, 6]]

或者,如果我需要打开包装,比如

>>> [(x, y, z) for x, y, z in a if (x + y) ** z > 30]
[(4, 5, 6)]

如果我真的需要一个函数,我可以使用参数元组解包(在Python 3.x中删除,顺便说一下,因为人们不会使用它):lambda (x, y, z): x + y + z需要一个元组并解压缩它的三个项目为xyz。 (请注意,您也可以在def中使用它,即:def f((x, y, z)): return x + y + z。)

当然,您可以在所有Python版本中使用赋值样式解包(def f(item): x, y, z = item; return x + y + z)和索引(lambda item: item[0] + item[1] + item[2])。

答案 1 :(得分:10)

您可以通过给lambda一个元组作为其参数来明确命名子列表元素(假设它们总是固定数量):

>>> a = [[1,2,3],[4,5,6]]
>>> N = 10
>>> filter(lambda (i, j, k): i + j + k > N, a)
[[4, 5, 6]]

如果您按照尝试指定“lambda i,j,k”,则表示lambda将接收三个参数。但是过滤器会给lambda的每个元素,即一次一个子列表(因此你得到的错误)。通过将括号中的参数括在lambda中,你说lambda将接收一个参数,但你也在命名它的每个组件。

答案 2 :(得分:1)

您可以执行类似

的操作
>>> a=[[1,2,3],[4,5,6]]
>>> filter(lambda (x,y,z),: x+y+z>6, a)
[[4, 5, 6]]

使用解构语法。

答案 3 :(得分:0)

尝试这样的事情:

filter(lambda a: a[0] + a[1] + a[2] >= N, a)

答案 4 :(得分:0)

使用函数而不是lambda,然后使用myVar = a[0]

答案 5 :(得分:0)

这个怎么样?

filter(lambda b : reduce(lambda x, y : x + y, b) >= N, a)

这不是回答问题,我知道,但它适用于任意长的列表和任意长的子列表,并支持在reduce()下运行的任何操作。

答案 6 :(得分:0)

好的,显然你知道你可以使用sum。你想要做的目标似乎有点模糊,但我认为可选的参数语法可能会帮助你,或者至少给你一些灵感。如果在参数之前放置*,它会创建一个包含所有自身和所有剩余参数的元组。如果您在其前面放置**,则会收到字典。

要看到这个:

def print_test(a,b,c,*d):
    print a
    print b
    print c
    print d

print_test(1,2,3,4,5,6)

打印

1
2
3
(4, 5, 6)

您也可以将此语法与lambda一起使用。

就像我说的那样,我不确定你想要做什么,但听起来这可能会有所帮助。我不认为你可以在没有一些黑客的情况下在lambda中获得局部变量赋值,但也许你可以使用它来以某种方式将值赋值给变量。

编辑:啊,我现在明白你在寻找什么。我想你想要:

lambda (a, b, c): a+b+c > N
相关问题