简体   繁体   English

最大(*args,关键=...)。 如何修改键以获取某些值?

[英]max(*args, key = ... ). How to modify key to get just certain values?

I am a bit confused with max(*args, key =..) function. Imagine I have a following list: my_list = [2, 3, 4, -5, -2, -1] .我对max(*args, key =..) function 有点困惑。假设我有以下列表: my_list = [2, 3, 4, -5, -2, -1] I want to find maximum value within the negative values in my_list.我想在 my_list 的负值中找到最大值。 For this, I am using the following code max(my_list, key = lambda x: x<0) , but it gives me -5 .为此,我使用以下代码max(my_list, key = lambda x: x<0) ,但它给了我-5 Can you please explain me the logic?你能解释一下逻辑吗?

What you are doing when calling max(my_list, key = lambda x: x<0) is saying: "which value in the list is largest, but compare the value of the result for the expression (x<0) for each element instead of the element's value."你在调用max(my_list, key = lambda x: x<0)时说的是:“列表中的哪个值最大,但是比较每个元素的表达式 (x<0) 的结果值元素的价值。” Therefore, the max operator basically sees the list as [False, False, False, True, True, True] when deciding which is biggest and in python this is equivalent to [0, 0, 0, 1, 1, 1] .因此, max运算符在决定哪个最大时基本上将列表视为[False, False, False, True, True, True] ,在 python 中,这等同于[0, 0, 0, 1, 1, 1] max returns the first maximum element it sees, which corresponds to -5. max返回它看到的第一个最大元素,对应于 -5。

You likely want to filter the list to only negative values first, then call max on the result您可能希望首先将列表过滤为仅负值,然后对结果调用max

While I wouldn't use max alone for this, you could , with an appropriate key function that doesn't collapse multiple values:虽然我不会为此单独使用max ,但您可以使用不折叠多个值的适当key function:

max(my_list, key=lambda x: -float('inf') if x > 0 else x)

This causes all positive values to compare as if they were negative infinity, which cannot be the largest value in a list that contains any non-positive values.这会导致所有正值进行比较,就好像它们是负无穷大一样,负无穷大不能是包含任何非正值的列表中的最大值。

(If all the values are all positive, you'll need to adapt this in some way, because it will still return the first value in the list: no successive value is bigger. Unless requested, I consider that beyond the scope of the question as currently stated.) (如果所有值都是正数,您需要以某种方式对此进行调整,因为它仍将返回列表中的第一个值:没有连续的值更大。除非有要求,否则我认为超出了问题的 scope如目前所述。)

Yes, you CAN do this by a single line with max function. I explain it below.是的,您可以通过一行max function 来完成此操作。我将在下面进行解释。

And ALSO there is a better way than list comprehension that I explained in the end.还有一种比我最后解释的列表理解更好的方法。

Reason of your problem:你的问题原因:

This is how the max function works if you have provided the key parameter.如果您提供了 key 参数,这就是 max function 的工作原理。 It will loop through the values of the list and then it applies the lambda function (named key ) on each value.它将遍历列表的值,然后对每个值应用 lambda function(名为key )。 So all of the values will be mapped to the result of the lambda function. Then it performs the max function on these results.所以所有的值都将映射到 lambda function 的结果。然后它对这些结果执行max function。

So when you have key=lambda x: x<0 this will return True or False as x<0 is a boolean expression.所以当你有key=lambda x: x<0这将返回TrueFalse因为x<0是一个 boolean 表达式。 So the result list would be like [False, False, False, True, True, True] .所以结果列表就像[False, False, False, True, True, True] These False and True values are processed as 0 and 1 values for the max function.这些FalseTrue值被处理为最大 function 的01值。

The max function gets [0, 0, 0, 1, 1, 1] and it finds the first one that is the maximum number in the list (number 1) that is the first 1 in the list that corresponds to number -5 in the original list. max function 得到[0, 0, 0, 1, 1, 1]并且它找到第一个是列表中最大数字的第一个(数字 1),即列表中对应于数字 -5 的第一个1原始列表。

Solution:解决方案:

There are multiple ways to find the maximum negative number like using a for loop or list comprehension or even combining filter and max .有多种方法可以找到最大负数,例如使用 for 循环或列表理解,甚至组合filtermax But, to understand the max function and it's parameters better I show you the way you can do the thing you want (find the maximum negative number) by the max function.但是,为了更好地理解max function 及其参数,我向您展示了如何通过max function 执行您想要的操作(找到最大负数)。

max(my_list, key = lambda x: min(my_list) if x>=0 else x)

This code will find the maximum negative number.此代码将找到最大负数。

How does this code work?这段代码是如何工作的?

The provided lambda expression will map all the number as this:提供的 lambda 表达式将 map 所有数字如下:

If the number is positive we replace it's value for the max function as the minimum number so it will never be chosen as the maximum negative number.如果数字是数,我们将其最大值 function 的值替换为最小值,因此它永远不会被选为最大负数。 (We could do this by removing all the negative number by filter but I decided to do all the job just with lambda to show you the way.) (我们可以通过filter删除所有负数来完成此操作,但我决定只使用 lambda 来完成所有工作以向您展示方法。)

If the number is negative it will keep it's own value.如果数字是负数,它将保持它自己的价值。 So for your example that the list is my_list = [2, 3, 4, -5, -2, -1] it will create [-5, -5, -5, -5, -2, -1] and then it will perform the max function on this list that it will find the -1 number that is what you want.所以对于你的例子,列表是my_list = [2, 3, 4, -5, -2, -1]它将创建[-5, -5, -5, -5, -2, -1]然后它将在此列表上执行max function,它将找到您想要的-1数字。

I wish it could help you understand how to find the maximum negative number just by the max function and the way maximum function works.我希望它可以帮助您了解如何仅通过max function 找到最大负数以及最大值 function 的工作方式。

NOTE: This code is not optimal.注意:此代码不是最佳的。 Because every time it computes the minimum value.因为每次它计算最小值。 This code is only for learning purposes.此代码仅用于学习目的。

Best way to do this最好的方法

I believe a better code is this:我相信更好的代码是这样的:

max((num for num in my_list if num<0))

Note that this is not list comprehension.请注意,这不是列表理解。 It is better than list comprehension .比列表理解更好 Instead it creates a generator that only process one value at a time.相反,它创建了一个一次只处理一个值的生成器 This is better that list comprehension because list comprehension creates the whole list at once and then send it to the max function. But this code process each value at a time and don't fill the memory with a big list.这比列表理解更好,因为列表理解会立即创建整个列表,然后将其发送到最大值 function。但是这段代码一次处理每个值,并且不会用大列表填充 memory。 So this is more efficient.所以这样效率更高。

I would use a list comprehension to filter out the positive values and then find the maximum.我会使用列表理解来过滤掉正值,然后找到最大值。

max([i for i in my_list if i < 0]) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM