What is the correct use of "key" in the min() function?

Question:

I have a question about the min() function in Python. I am confused about the use of the "key" option in min(). Could someone explain how key works in min(), especially in relation to a lambda function?

For example:

lst = [10, -5, 20, 1]
min(lst, key=lambda x: x > 0)

As far as I understand, this expression should find the minimum element in the list lst that is greater than zero. However, it returns -5 instead of 1, which is the minimum element of lst that is greater than zero. Can someone explain why this happens and how I should correctly use key in the min() function?

Asked By: Jose Angel

||

Answers:

For definition of min() kindly refer official doc

The key argument in Python’s min() function specifies a one-argument function that is used to extract a comparison key from each element in the iterable. The minimum element is selected based on the key, not on the original elements themselves.

The solution to your query:

min(lst, key=lambda x: x if x > 0 else float('inf'))

float('inf') is a special floating-point value in Python that represents positive infinity.

This lambda function returns x if x is greater than 0, and positive infinity (float('inf')) otherwise. This ensures that the min() function only considers elements greater than zero when finding the minimum element. The output will 1 in your case.

Answered By: Muhammad Saqlain

Your key function key=lambda x: x > 0 just evaluates to a Boolean. You can see this you you write it out in a loop:

lst = [10, -5, 20, 1]
for item in lst:
    print(item > 0)

Booleans are subclasses of integers, so the conversion is easy:

lst = [10, -5, 20, 1]
for item in lst:
    print(int(item > 0))

Guess what; -5 is the only value that returns False (0) so that’s the result you get as the minimum (that was your key).

You could filter this list but, really, you’d just be better re-building it with positive elements and then using min() without a key, to be clear on what you’re doing:

lst = [10, -5, 20, 1]
lst = [item for item in lst if item > 0]
print(min(lst))
Answered By: roganjosh

According to [Python.Docs]: Built-in Functions – min(lst, key=lambda):

The key argument specifies a one-argument ordering function like that used for list.sort().

Then, from [Python.Docs]: Built-in Functions – sort(*, key=None, reverse=False):

key specifies a function of one argument that is used to extract a comparison key from each list element (for example, key=str.lower). The key corresponding to each item in the list is calculated once and then used for the entire sorting process. The default value of None means that list items are sorted directly without calculating a separate key value.

So, you can look at the the key function as a transformation of an element in the iterable, and the comparison is done on the iterable resulted by applying the function to every element in the original iterable.
That generates a result (from the 2nd (hash) iterable), and the corresponding element from the 1st iterable is returned.

>>> l = [10, -5, 20, 1]
>>>
>>> min(lst, key=abs)
1
>>> # The above expression is equivalent to:
>>> min((abs(e) for e in lst))
1
>>> min(l + [0], key=abs)
0
>>>
>>> # Another example
>>> min(lst, key=lambda arg: -abs(arg))
20
Answered By: CristiFati
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.