Just now I saw a quiz on this page:
>>> x, y = ???
>>> min(x, y) == min(y, x)
False
The example answer is
x, y = {0}, {1}
From the documentation I know that:
min(iterable[, key=func]) -> value
min(a, b, c, ...[, key=func]) -> valueWith a single iterable argument, return its smallest item.
With two or more arguments, return the smallest argument.
But why is min({0},{1})={0}
and min({1},{0})={1}
?
I also tried a few others:
min({0,2},1) # 1
min(1,{0,2}) # 1
min({1},[2,3]) # [2,3]
min([2,3],1) # 1
The comparison operators <
, <=
, >=
, and >
check whether one set is a strict subset, subset, superset, or strict superset of another, respectively.
{0}
and {1}
are False
for all of these, so the result depends on the check order and operator.
The key point here is, the two sets are not subsets of each other, so both are False
for <
even though they are not equal:
>>> {0} < {1}
False
>>> {0} > {1}
False
>>> {0} == {1}
False
So which one is smaller? The fact that sets don't provide strict weak ordering means there's no correct answer.
min
is implemented roughly like this:
def min(*args):
least = args[0]
for arg in args:
if arg < least:
least = arg
return least
The way the comparison operators work for sets break one of the assumptions that this implicitly makes: that for every pair of objects, either they are equal, or a < b
or b < a
. Neither {0}
nor {1}
compare less than one another, so min
gives you inconsistent answers.
The other results you see are because of the rules for how Python defines an order for mixed types. A set
and an int
aren't comparable - neither of those types defines a rule for comparing to the other. This leads Python 2 to apply a rule called "arbitrary but consistent order" - one of the types is chosen to be the "lower" type, and it will remain the lower type for the lifetime of the program. In practice, it will be the same across all code you run, because it is implemented by comparing the type names alphabetically - but in theory, that could change.
The "arbitrary but consistent order" rule has been dumped from Python 3, because the only effect it really had was to mask bugs. When there is no defined rule for finding an order, Python now tells you so:
>>> 1 < {0}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() < set()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With