Skip to content
Advertisement

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]. I want to find maximum value within the negative values in my_list. For this, I am using the following code max(my_list, key = lambda x: x<0), but it gives me -5. Can you please explain me the logic?

Advertisement

Answer

Yes, you CAN do this by a single line with max function. I explain it below.

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. It will loop through the values of the list and then it applies the lambda function (named key) on each value. So all of the values will be mapped to the result of the lambda function. Then it performs the max function on these results.

So when you have key=lambda x: x<0 this will return True or False as x<0 is a boolean expression. So the result list would be like [False, False, False, True, True, True]. These False and True values are processed as 0 and 1 values for the max function.

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.

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. 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(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:

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. (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.)

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.

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.

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. So this is more efficient.

Advertisement