How does Python sort a list of sets?

2020-02-13 04:16发布

问题:

Python sorts lists of tuples by looking at the elements of the tuples, in order. Since sets are unordered, how does Python sort a list of sets?

Edit: The question and accepted answer in this post are more general and the document given is very in-depth. My question is not a duplicate.

回答1:

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.



回答2:

Sets are partially ordered, so

the output of the list.sort() method is undefined for lists of sets.

https://docs.python.org/3/library/stdtypes.html#set



回答3:

The __le__ operator on sets define the partial ordering "subset". Therefore the sorted order is undefined.

{3} < {5} is false, but so is {5} < {3} so the sort algorithm will usually not rearrange them.

Citation from Python3 documentaton about sets:

The subset and equality comparisons do not generalize to a total ordering function. For example, any two nonempty disjoint sets are not equal and are not subsets of each other, so all of the following return False: a<b, a==b, or a>b.

Since sets only define partial ordering (subset relationships), the output of the list.sort() method is undefined for lists of sets.