Python 如何让过滤器与带多个参数的 lambda 一起使用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4391043/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get filter to work with a lambda taking multiple arguments?
提问by sidhshar
Using Python, am finding it difficult to get filter() to work with lambda for cases where more than 1 argument needs to be passed as is the case in the following snippet:
使用 Python,我发现在需要传递 1 个以上参数的情况下,很难让 filter() 与 lambda 一起使用,如下面的代码片段所示:
max_validation = lambda x,y,z: x < y < z
sequence1 = [1,4,8]
filter(max_validation, sequence1)
It raises the following error:
它引发以下错误:
TypeError: <lambda>() takes exactly 3 arguments (1 given)
Please suggest as to what am doing wrong here.
请建议我在这里做错了什么。
采纳答案by Wesley
It's a little bit difficult to figure out exactly what you're trying to do. I'm going to interpret your question, then provide an answer. If this is not correct, please modify your question or comment on this answer.
确切地弄清楚您要做什么有点困难。我将解释您的问题,然后提供答案。如果这不正确,请修改您的问题或对此答案发表评论。
Question
题
I have sequences that are exactly three elements long. Here's one:
我有正好三个元素长的序列。这是一个:
sequence1 = [1, 4, 8]
I want to ensure that the first element is less than the second element, which should in turn be less than the third element. I've written the following function to do so:
我想确保第一个元素小于第二个元素,而第二个元素又应该小于第三个元素。为此,我编写了以下函数:
max_validation = lambda x, y, z: x < y < z
How do I apply this using filter? Using filter(max_validation, sequence1)doesn't work.
我如何应用这个使用filter?使用filter(max_validation, sequence1)不起作用。
Answer
回答
Filter applies your function to each element of the provided iterable, picking it if the function returns Trueand discarding it if the function returns False.
Filter 将您的函数应用于提供的可迭代对象的每个元素,如果函数返回则选择它,如果函数返回则True丢弃它False。
In your case, filterfirst looks at the value 1. It tries to pass that into your function. Your function expects three arguments, and only one is provided, so this fails.
在您的情况下,filter首先查看 value 1。它试图将其传递到您的函数中。您的函数需要三个参数,但只提供了一个,因此失败。
You need to make two changes. First, put your three-element sequence into a list or other sequence.
您需要进行两项更改。首先,将您的三元素序列放入列表或其他序列中。
sequences = [[1, 4, 8], [2, 3, 9], [3, 2, 3]]
max_validation = lambda x: x[0] < x[1] < x[2] and len(x) == 3
I've added two other sequences to test. Because sequencesis a list of a list, each list gets passed to your test function. Even if you're testing just one sequence, you should use [[1, 4, 8]]so that the entire sequence to test gets passed into your function.
我添加了另外两个序列进行测试。因为sequences是一个列表的列表,所以每个列表都会传递给您的测试函数。即使您只测试一个序列,也应该使用,[[1, 4, 8]]以便将要测试的整个序列传递到您的函数中。
I've also modified max_validationso that it accepts just one argument: the list to test. I've also added and len(x) == 3to ensure that the sequences are only 3 elements in length
我还进行了修改max_validation,使其只接受一个参数:要测试的列表。我还添加and len(x) == 3了确保序列只有 3 个元素的长度
回答by Ignacio Vazquez-Abrams
The function passed to filter()only gets a single argument passed to it, which is the current element in the iterable being iterated.. If you need something fancier than that then filter()won't do.
传递给的函数filter()只得到一个传递给它的参数,它是被迭代的可迭代对象中的当前元素filter()。
回答by user225312
I hope you are aware of?
我希望你知道吗?
>>> max([1, 4, 8])
8
filter() takes a single argument. In your case, it will take 1. Then 4. Then 8.
filter() 接受一个参数。在您的情况下,需要 1。然后是 4。然后是 8。
回答by Tyler Eaves
It's possible to do this using a closure:
可以使用闭包来做到这一点:
>>> def foo(a,b):
... def bar(c):
... return a+b+c
... return bar
...
>>> x = foo(1,2)
>>> x(3)
6
>>> y = foo(100,0)
>>> y(1)
101
>>> x(1)
4
回答by userdj
Straight from the docs of Python Filters
直接来自Python 过滤器的文档
Note that filter(function, iterable)is equivalent to [item for item in iterable if function(item)] if function is not None and [item for item in iterable if item] if function is None.
注意filter(function, iterable)等价于 [item for item in iterable if function(item)] if function is not None 和 [item for item in iterable if item] if function is None。
So, you can just process single arguments with Python filters. That effectively means you cannot use filters for the your example. You would have to write custom-code for the same.
因此,您可以使用 Python 过滤器处理单个参数。这实际上意味着您不能在示例中使用过滤器。您必须为此编写自定义代码。
回答by wiswit
I think all others didn't get the point. the error message is for lambda function not for the filter. You should rather call it this way:
我认为所有其他人都没有明白这一点。错误消息是针对 lambda 函数的,而不是针对过滤器的。你应该这样称呼它:
filter(max_validation, *sequence1)
add a star on the list transform it into three arguments, then it will work.
在列表上添加一颗星,将其转换为三个参数,然后它就会起作用。
回答by walkingpendulum
This would work for sequences of any length:
这适用于任何长度的序列:
all(x < y for x, y in zip(seq, seq[1:]))
What does there happens?
会发生什么?
For sequence 1, 2, 3... you take sequences 1, 2, 3... and 2, 3, 4... and zip them together to sequence (1, 2), (2, 3), ... Then you check if statement 'x < y' holds for every pair.
对于序列 1, 2, 3... 你取序列 1, 2, 3... 和 2, 3, 4... 并将它们压缩到序列 (1, 2), (2, 3), .. . 然后你检查语句 'x < y' 是否对每一对都成立。
And this will work for any associative rule you want to check.
这适用于您要检查的任何关联规则。
Useful links:
有用的链接:
回答by Supratim
You could change
你可以改变
max_validation = lambda x,y,z: x < y < z
to
到
max_validation = lambda (x,y,z): x < y < z
回答by WaveRider
I'm in agreement with both @walkingpendulum and @Wesley, depending on the interpretation of the actual problem statement. So parsing through the ambiguity in the problem statement: If you're sequentially comparing one item to its previous value in an iterable object, a lambda expression is overkill, just use a list comprehension:
我同意@walkingpendulum 和@Wesley,这取决于对实际问题陈述的解释。所以解析问题陈述中的歧义:如果你在一个可迭代对象中依次比较一个项目和它之前的值,一个 lambda 表达式是矫枉过正的,只需使用列表理解:
[1 if i < i+1 else 0 for i in sequence1]
If you're comparing objects, then just compare them -- a lambda expression wouldn't work firstly because you're only passing one argument where the lambda expression you defined you're passing three and lambda is generally applied across an iterable object. To compare objects, there are simple constructs for that:
如果您正在比较对象,那么只需比较它们 - 一个 lambda 表达式首先不起作用,因为您只传递一个参数,而您定义的 lambda 表达式将传递三个参数,而 lambda 通常应用于可迭代对象。为了比较对象,有一些简单的构造:
sequence1 == some_other_sequence
and
和
x, y, z = 1, 2, 3
x < y < z
And lastly, if you want to apply a lambda expression to an iterable object, map can get you there: (arbitrary lambda function)
最后,如果您想将 lambda 表达式应用于可迭代对象,map 可以帮助您实现:(任意 lambda 函数)
map(lambda x: x > 1, sequence1)
Otherwise @walkingpendulum and @Wesley cover the other interpretations
否则@walkingpendulum 和@Wesley 涵盖其他解释

