Skip to content Skip to sidebar Skip to footer

Sort A Dictionary With Custom Sorting Function

I have some JSON data I read from a file using json.load(data_file) { 'unused_account':{ 'logins': 0, 'date_added': 150 }, 'unused_account2':{ 'logins': 0, '

Solution 1:

I'm going to assume you know that dictionaries are unordered and that you want to sort either the values, or the key-value pairs. The following examples sort the values.

Your comparison function already works, provided you fix the loigns typo in the last if:

>>> sorted(sample.itervalues(), cmp=compare))
[{'logins': 0, 'date_added': 150}, {'logins': 0, 'date_added': 100}, {'logins': 500, 'date_added': 400, 'date_used': 500}, {'logins': 500, 'date_added': 300, 'date_used': 400}, {'logins': 20, 'date_added': 200, 'date_used': 300}]
>>> pprint(_)
[{'date_added': 150, 'logins': 0},
 {'date_added': 100, 'logins': 0},
 {'date_added': 400, 'date_used': 500, 'logins': 500},
 {'date_added': 300, 'date_used': 400, 'logins': 500},
 {'date_added': 200, 'date_used': 300, 'logins': 20}]

However, you can use the following sort key too:

(not d['logins'], d['logins'], d['date_used'] if d['logins'] else d['date_added'])

This creates a tuple of (has_logins, num_logins, date) where the date picked is based on whether or not the user has logged in.

Use it as the key argument to the sorted() function, and reverse the sort, like this:

>>> key = lambda d: (not d['logins'], d['logins'], d['date_used'] if d['logins'] else d['date_added'])
>>> pprint(sorted(sample.itervalues(), key=key, reverse=True))
[{'date_added': 150, 'logins': 0},
 {'date_added': 100, 'logins': 0},
 {'date_added': 400, 'date_used': 500, 'logins': 500},
 {'date_added': 300, 'date_used': 400, 'logins': 500},
 {'date_added': 200, 'date_used': 300, 'logins': 20}]

If you needed the keys as well, use dict.iteritems() and update the key function to accept a (k, d) tuple:

>>> key = lambda (k, d): (not d['logins'], d['logins'], d['date_used'] if d['logins'] else d['date_added'])
>>> pprint(sorted(sample.iteritems(), key=key, reverse=True))
[('unused_account', {'date_added': 150, 'logins': 0}),
 ('unused_account2', {'date_added': 100, 'logins': 0}),
 ('power_user_2', {'date_added': 400, 'date_used': 500, 'logins': 500}),
 ('power_user', {'date_added': 300, 'date_used': 400, 'logins': 500}),
 ('regular_user', {'date_added': 200, 'date_used': 300, 'logins': 20})]

Post a Comment for "Sort A Dictionary With Custom Sorting Function"