Skip to content

Instantly share code, notes, and snippets.

@xtream1101
Last active June 27, 2018 17:33
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 xtream1101/4a63ac943353c0111d74af58cab63ea3 to your computer and use it in GitHub Desktop.
Save xtream1101/4a63ac943353c0111d74af58cab63ea3 to your computer and use it in GitHub Desktop.
"""Sort a list of dicts using multiple keys
Also be able to have the different keys sort in different orders
"""
from pprint import pprint
unsorted_data_a = [{'title': 'Foo Beta',
'date': '2018-06-03',
'value': 5},
{'title': 'A Foo',
'date': '2018-06-01',
'value': 5},
{'title': 'Foo Delta',
'date': '2018-06-02',
'value': 1},
{'title': 'Foo',
'date': '2018-06-02',
'value': 5},
{'title': 'Foo Alpha',
'date': '2018-06-03',
'value': 5},
{'title': 'Foo Alpha',
'date': '2018-06-03',
'value': 3},
]
from operator import itemgetter
from functools import cmp_to_key
def multikeysort(items, columns):
comparers = [
((itemgetter(col[1:].strip()), -1) if col.startswith('-') else (itemgetter(col.strip()), 1))
for col in columns
]
def cmp(a, b):
return (a > b) - (a < b)
def comparer(left, right):
comparer_iter = (
cmp(fn(left), fn(right)) * mult
for fn, mult in comparers
)
return next((result for result in comparer_iter if result), 0)
return sorted(items, key=cmp_to_key(comparer))
# Tests
# Sort on date (desc), then title (asc), then value (asc)
sorted_test1 = multikeysort(unsorted_data_a, ['-date', 'title', 'value'])
pprint(sorted_test1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment