Regardless of what's in a list, the elements' __lt__
methods are the only comparison methods consulted. For sets, a < b
means "a
is a proper subset of b
", which isn't enough to define a total order. That's why the result is, in general, undefined. It may be any permutation of the original list consistent with which pairs of list elements the implementation happens to apply __lt__
to.
If, for every pair of sets in the list, one is in fact a proper subset of the other, then the list will be sorted from smallest (cardinality) set to largest. Otherwise little can be said. For example:
>>> sorted([{5, 6}, {3, 4}, {5}, {3}]) # nothing changes
[{5, 6}, {3, 4}, {5}, {3}]
What happens is a consequence of undefined implementation details. Since I wrote list.sort()
, I know what happens in this case, but it's not guaranteed to always work this way:
First the implementation asks "is {3, 4} < {5, 6}
?". No, so the order of the first two elements is consistent with being sorted already. It next asks "is {5} < {3, 4}
?". No, so the first three elements appear to be already sorted. Finally it asks "is {3} < {5}
?". No again, so the original list's entire order is consistent with being already sorted, and nothing changes.
A future implementation may, e.g., ask "is {5} < {5, 6}
?" at some point, and since "yes" decide {5}
needs to appear before {5, 6}
. So the result is simply not defined.