Reputation: 17876
Initially data is this:
dict = {<User: user2>: {'diff': 48, 'alike': 1}, <User: user3>: {'diff': 42, 'alike': 2}, <User: user4>: {'diff': 45, 'alike': 1}, <User: user5>: {'diff': 43, 'alike':
2}, <User: user6>: {'diff': 46, 'alike': 1}, <User: user7>: {'diff': 46, 'alike': 1}, <User: user8>: {'diff': 49, 'alike': 1}, <User: user9>: {'diff': 50, 'ali
ke': 0}, <User: user10>: {'diff': 46, 'alike': 1}, <User: user11>: {'diff': 37, 'alike': 3}, <User: user12>: {'diff': 50, 'alike': 0}, <User: user13>: {'diff':
50, 'alike': 0}, <User: user14>: {'diff': 50, 'alike': 0}, <User: user15>: {'diff': 50, 'alike': 0}, <User: user16>: {'diff': 50, 'alike': 0}, <User: user17>: {
'diff': 50, 'alike': 0}, <User: user18>: {'diff': 50, 'alike': 0}, <User: user19>: {'diff': 50, 'alike': 0}, <User: user20>: {'diff': 50, 'alike': 0}}
Then I sort it:
sorted(dict) == [{'diff': 50, 'alike': 0}, {'diff': 50, 'alike': 0}, {'diff': 50, 'alike': 0}, {'diff': 50, 'alike': 0}, {'diff': 50, 'alike': 0}, {'diff': 50, 'alike': 0}, {'d
iff': 50, 'alike': 0}, {'diff': 50, 'alike': 0}, {'diff': 50, 'alike': 0}, {'diff': 50, 'alike': 0}, {'diff': 45, 'alike': 1}, {'diff': 46, 'alike': 1}, {'diff'
: 46, 'alike': 1}, {'diff': 46, 'alike': 1}, {'diff': 48, 'alike': 1}, {'diff': 49, 'alike': 1}, {'diff': 42, 'alike': 2}, {'diff': 43, 'alike': 2}, {'diff': 37
, 'alike': 3}]
How do I sort it by "diff"?
Upvotes: 0
Views: 234
Reputation: 89097
For one, you are not sorting a dict
- you are sorting a list of dicts
- these are very different things, not least as a dict
in Python has no defined order.
You can do this easily with sorted()
and operator.itemgetter()
:
import operator
sorted_dicts = sorted(dicts, key=operator.itemgetter("diff"))
The sorted()
builtin takes the key
keyword argument, which is a function which takes the value, and gives another value to sort on. Here we use an itemgetter()
to get the desired value from the dict
to sort by.
Given your change, there are two answers, as you are being unclear. If you want the list of values, it's simply a case of extracting them from your original dict
:
sorted(users.values(), key=operator.itemgetter("diff"))
Which is as simple as taking dict.values()
. Naturally, under Python 2.x, you will want to use viewitems()
or iteritems()
for good performance.
If you want to sort the dict
itself, it's a different matter, as dict
s (as I stated) are inherently unordered.
First of all, I would like to note that sorted(dict)
does not produce the output you suggested - a dict iterates over the keys, not the values by default:
users = {
'<User: user10>': {'alike': 1, 'diff': 46},
'<User: user11>': {'alike': 3, 'diff': 37},
'<User: user12>': {'alike': 0, 'diff': 50},
'<User: user13>': {'alike': 0, 'diff': 50},
'<User: user14>': {'alike': 0, 'diff': 50},
'<User: user15>': {'alike': 0, 'diff': 50},
'<User: user16>': {'alike': 0, 'diff': 50},
'<User: user17>': {'alike': 0, 'diff': 50},
'<User: user18>': {'alike': 0, 'diff': 50},
'<User: user19>': {'alike': 0, 'diff': 50},
'<User: user20>': {'alike': 0, 'diff': 50},
'<User: user2>': {'alike': 1, 'diff': 48},
'<User: user3>': {'alike': 2, 'diff': 42},
'<User: user4>': {'alike': 1, 'diff': 45},
'<User: user5>': {'alike': 2, 'diff': 43},
'<User: user6>': {'alike': 1, 'diff': 46},
'<User: user7>': {'alike': 1, 'diff': 46},
'<User: user8>': {'alike': 1, 'diff': 49},
'<User: user9>': {'alike': 0, 'diff': 50}
}
print(sorted(users))
Gives us:
['<User: user10>', '<User: user11>', '<User: user12>', '<User: user13>', '<User: user14>', '<User: user15>', '<User: user16>', '<User: user17>', '<User: user18>', '<User: user19>', '<User: user20>', '<User: user2>', '<User: user3>', '<User: user4>', '<User: user5>', '<User: user6>', '<User: user7>', '<User: user8>', '<User: user9>']
To produce a sorted dict
, we need to use collections.OrderedDict()
:
import collections
users = {
'<User: user10>': {'alike': 1, 'diff': 46},
'<User: user11>': {'alike': 3, 'diff': 37},
'<User: user12>': {'alike': 0, 'diff': 50},
'<User: user13>': {'alike': 0, 'diff': 50},
'<User: user14>': {'alike': 0, 'diff': 50},
'<User: user15>': {'alike': 0, 'diff': 50},
'<User: user16>': {'alike': 0, 'diff': 50},
'<User: user17>': {'alike': 0, 'diff': 50},
'<User: user18>': {'alike': 0, 'diff': 50},
'<User: user19>': {'alike': 0, 'diff': 50},
'<User: user20>': {'alike': 0, 'diff': 50},
'<User: user2>': {'alike': 1, 'diff': 48},
'<User: user3>': {'alike': 2, 'diff': 42},
'<User: user4>': {'alike': 1, 'diff': 45},
'<User: user5>': {'alike': 2, 'diff': 43},
'<User: user6>': {'alike': 1, 'diff': 46},
'<User: user7>': {'alike': 1, 'diff': 46},
'<User: user8>': {'alike': 1, 'diff': 49},
'<User: user9>': {'alike': 0, 'diff': 50}
}
print(collections.OrderedDict(sorted(users.items(), key=lambda x: x[1]["diff"])))
Which gives us:
OrderedDict([('<User: user11>', {'diff': 37, 'alike': 3}), ('<User: user3>', {'diff': 42, 'alike': 2}), ('<User: user5>', {'diff': 43, 'alike': 2}), ('<User: user4>', {'diff': 45, 'alike': 1}), ('<User: user10>', {'diff': 46, 'alike': 1}), ('<User: user7>', {'diff': 46, 'alike': 1}), ('<User: user6>', {'diff': 46, 'alike': 1}), ('<User: user2>', {'diff': 48, 'alike': 1}), ('<User: user8>', {'diff': 49, 'alike': 1}), ('<User: user20>', {'diff': 50, 'alike': 0}), ('<User: user9>', {'diff': 50, 'alike': 0}), ('<User: user13>', {'diff': 50, 'alike': 0}), ('<User: user19>', {'diff': 50, 'alike': 0}), ('<User: user12>', {'diff': 50, 'alike': 0}), ('<User: user18>', {'diff': 50, 'alike': 0}), ('<User: user15>', {'diff': 50, 'alike': 0}), ('<User: user14>', {'diff': 50, 'alike': 0}), ('<User: user17>', {'diff': 50, 'alike': 0}), ('<User: user16>', {'diff': 50, 'alike': 0})])
Note that here we had to use a lambda
statement for the key argument, as an itemgetter()
unfortunately can't get multiple levels of items for us.
Upvotes: 8
Reputation: 160073
sorted(your_list, key=lambda el: el["diff"])
The key
keyword argument should be a function that takes an element of the list you are sorting and returns the value that should be used in the sort comparison. lambda
is shorthand for def
- that is, it defines a function (with several limitations). The same line could be written this way:
def get_key(el):
return el["diff"]
sorted(your_list, key=get_key)
Upvotes: 5