Last active
December 18, 2015 06:59
-
-
Save ncoghlan/5743523 to your computer and use it in GitHub Desktop.
Replicate 2.x arbitrary sorting logic in Python 3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MixedTypeKey: | |
"""Sort key for mixed type lists in Python 3 | |
>>> sorted([None, ..., 1, 1j, "", (), {}, []]) | |
Traceback (most recent call last): | |
File "<stdin>", line 1, in <module> | |
TypeError: unorderable types: ellipsis() < NoneType() | |
>>> sorted([None, ..., 1, 1j, "", (), {}, []], key=MixedTypeKey) | |
[None, Ellipsis, 1, 1j, '', (), {}, []] | |
""" | |
def __init__(self, k): | |
self._sort_key = k | |
self._type_name = self._get_fully_qualified_name(k) | |
def _get_fully_qualified_name(self, k): | |
k_type = type(k) | |
# Use __qualname__ if available, __name__ otherwise | |
try: | |
k_name = k_type.__qualname__ | |
except AttributeError: | |
k_name = k_type.__name__ | |
return k_type.__module__ + "." + k_name | |
def __lt__(self, other): | |
# Try standard sorting first | |
sort_key = self._sort_key | |
try: | |
other_sort_key = other._sort_key | |
except AttributeError: | |
other_sort_key = other | |
try: | |
return sort_key < other_sort_key | |
except TypeError: | |
pass | |
# If that fails, sort by the fully qualified type names | |
try: | |
other_type_name = other._type_name | |
except AttributeError: | |
other_type_name = self._get_fully_qualified_name(other) | |
return self._type_name < other_type_name |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment