Which maximum does Python pick in the case of a tie?
Solution 1:
It picks the first element it sees. See the documentation for max()
:
If multiple items are maximal, the function returns the first one encountered. This is consistent with other sort-stability preserving tools such as
sorted(iterable, key=keyfunc, reverse=True)[0]
andheapq.nlargest(1, iterable, key=keyfunc)
.
In the source code this is implemented in ./Python/bltinmodule.c
by builtin_max
, which wraps the more general min_max
function.
min_max
will iterate through the values and use PyObject_RichCompareBool
to see if they are greater than the current value. If so, the greater value replaces it. Equal values will be skipped over.
The result is that the first maximum will be chosen in the case of a tie.
Solution 2:
From empirical testing, it appears that max()
and min()
on a list will return the first in the list that matches the max()
/min()
in the event of a tie:
>>> test = [(1, "a"), (1, "b"), (2, "c"), (2, "d")]
>>> max(test, key=lambda x: x[0])
(2, 'c')
>>> test = [(1, "a"), (1, "b"), (2, "d"), (2, "c")]
>>> max(test, key=lambda x: x[0])
(2, 'd')
>>> min(test, key=lambda x: x[0])
(1, 'a')
>>> test = [(1, "b"), (1, "a"), (2, "d"), (2, "c")]
>>> min(test, key=lambda x: x[0])
(1, 'b')
And Jeremy's excellent sleuthing confirms that this is indeed the case.
Solution 3:
For Python 3, the behavior of max()
in the case of ties is no longer just an implementation detail as detailed in the other answers. The feature is now guaranteed, as the Python 3 docs explicitly state:
If multiple items are maximal, the function returns the first one encountered. This is consistent with other sort-stability preserving tools such as
sorted(iterable, key=keyfunc, reverse=True)[0]
andheapq.nlargest(1, iterable, key=keyfunc)
.
Solution 4:
Your question somewhat leads to a note. When sorting a data structure, there is often a desire to keep relative order of objects that are considered equal for the purposes of comparison. This would be known as a stable sort.
If you absolutely needed this feature, you could do a sort()
, which will be stable and then have knowledge of the order relative to the original list.
As per python itself, I don't believe that you get any guarantee of which element you will get when you call max()
. Other answers are giving the cpython answer, but other implementations (IronPython, Jython) could function differently.