Sorting dictionary keys by values in a list?
I have a dictionary and a list. The values of the keys mat开发者_开发问答ch those of the list, I'm just trying to find out how to sort the values in the dictionary by the values in the list.
>>> l = [1, 2, 37, 32, 4, 3]
>>> d = {
32: 'Megumi',
1: 'Ai',
2: 'Risa',
3: 'Eri',
4: 'Sayumi',
37: 'Mai'
}
I've tried using something along the lines of...
>>> sorted(dict.keys(), key=list.index)
... but obviously that only returns the keys in the desired order.
(Should have realized at 3AM that list
and dict
were horrible names, I changed them to l
and d
accordingly.)
Don't shadow the builtins dict
and list
>>> L = [1, 2, 37, 32, 4, 3]
>>> D = {
... 32: 'Megumi',
... 1: 'Ai',
... 2: 'Risa',
... 3: 'Eri',
... 4: 'Sayumi',
... 37: 'Mai'
... }
# Seems roundabout to use sorted here
# This causes an index error for keys in D that are not listed in L
>>> sorted(D.items(), key=lambda x:L.index(x[0]))
[(1, 'Ai'), (2, 'Risa'), (37, 'Mai'), (32, 'Megumi'), (4, 'Sayumi'), (3, 'Eri')]
>>>
# I think this is more direct than using sorted.
# This also ignores/skips keys in D that aren't listed in L
>>> [(i,D[i]) for i in L]
[(1, 'Ai'), (2, 'Risa'), (37, 'Mai'), (32, 'Megumi'), (4, 'Sayumi'), (3, 'Eri')]
>>>
You shouldn't call you variables dict and list, because then, you cant use the build-in methods any more. I have renamed them in this example.
>>> l = [1, 2, 37, 32, 4]
>>> d = dict = {
... 32: 'Megumi',
... 1: 'Ai',
... 2: 'Risa',
... 3: 'Eri',
... 4: 'Sayumi',
... 37: 'Mai'
... }
Note that prior to Python 3.7 you could not sort dictionaries in Python (they were hash tables sorted by the hash functions of the keys). Alternative dictionary implementations existed to work around this (OrderedDict
).
But you can create a new list containing the (key, value)-tuples from any dictionary, which is sorted by the first list:
>>> s = list((i, d.get(i)) for i in L)
>>> print s
[(1, 'Ai'), (2, 'Risa'), (37, 'Mai'), (32, 'Megumi'), (4, 'Sayumi')]
Or if you are only interested in the values:
>>> s = list(d.get(i) for i in L)
>>> print s
['Ai', 'Risa', 'Mai', 'Megumi', 'Sayumi']
Hope that helps!
You can't sort a dictionary because a dictionary is not ordered.
What you can do instead is:
- Get all the key-value pairs out of the dictionary, sort them and put them into a list or
- What you are already doing: keep a sorted list of the keys and use the dictionary when you need the value corresponding to a key.
Sorted dict is in fact a list of 2-tuples, because in Python 2.x there're no ordered dictionaty built-in. You almost got the solution, just add a value lookup after sorting keys:
[(k,dict[k]) for k in sorted(dict.keys(), key=list.index)]
But this fails when a key is not in list
. Let's add a modification to put all such values at the end of sort, ordered by value:
def _index(x): # Allow non-full key list to be used in sorting
try: return (list.index(x), x)
except ValueError: return (sys.maxint, x)
[(k,dict[k]) for k in sorted(dict.keys(), key=_index)]
In Python 3.1, you could use the OrderedDict class:
from collections import OrderedDict
l = [1, 2, 37, 32, 4]
d = {
32: 'Megumi',
1: 'Ai',
2: 'Risa',
3: 'Eri',
4: 'Sayumi',
37: 'Mai'
}
def myindex(element):
try:
return l.index(element)
except ValueError:
return -1 # nonexisting keys are appended to the beginning of the list
od = OrderedDict(sorted(d.items(), key = lambda t: myindex(t[0])))
print(od)
As I didn't know what you want to do with keys that aren't in the list, I just return -1 in that case, meaning those elements are prepended to the list somehow (i.e. in non-stable order).
My example will print
OrderedDict([(3, 'Eri'), (1, 'Ai'), (2, 'Risa'), (37, 'Mai'), (32, 'Megumi'), (4, 'Sayumi')])
精彩评论