Reputation: 1595
I have a dictionary and a list. The values of the keys match 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.)
Upvotes: 6
Views: 5604
Reputation: 94639
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!
Upvotes: 5
Reputation: 70108
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')])
Upvotes: 0
Reputation: 304137
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')]
>>>
Upvotes: 7
Reputation: 6044
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)]
Upvotes: 1
Reputation: 837996
You can't sort a dictionary because a dictionary is not ordered.
What you can do instead is:
Upvotes: 1