Skip to content

Instantly share code, notes, and snippets.

@ncoghlan
Last active December 18, 2015 06:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ncoghlan/5743523 to your computer and use it in GitHub Desktop.
Save ncoghlan/5743523 to your computer and use it in GitHub Desktop.
Replicate 2.x arbitrary sorting logic in Python 3
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