3

Assuming I've the following list of lists:

dict1 = [['Jeremy', 25, 120000], ['Paul', 23, 75000], ['Mike', 32, 80000]]

I can easily sort the lists on index 2 as follows:

from operator import itemgetter

sorted_dict = sorted(dict1, key=itemgetter(1))
print(sorted_dict)
>>>
[['Paul', 23, 75000], ['Jeremy', 25, 120000], ['Mike', 32, 80000]]

Things get a little more complicated with a dictionary of lists. Assuming I've the following:

dict2 = {'employee1':['Paul', 23, 75000], 
         'employee2':['Mike', 32, 80000], 
         'employee3':['Jeremy', 25, 120000]}

I can approximate a sort on index 2 as follows:

from operator import itemgetter

#First, extract lists
result1 = dict2.values()
#Second, sort list by index 2
result2 = sorted(result1, key=itemgetter(1))
#Finally, use for loop to sort dictionary
for a in result2:
    for b in dict2.keys():
        if a == dict2[b]:
            print("{0}:{1}".format(b,a))

>>>
   employee1:['Paul', 23, 75000]
   employee3:['Jeremy', 25, 120000]
   employee2:['Mike', 32, 80000]

I would like a better way to perform a sort on the dictionary. I found a community wiki post on sorting dictionaries (here) but the dictionary in that post has constant key. In my dictionary above, each list has a unique key.

Thanks.

Using Python 3.4.1

Community
  • 1
  • 1
sedeh
  • 5,252
  • 4
  • 37
  • 51

2 Answers2

3

First, you can't sort a dict because it doesn't have order 1. You can sort it's items however:

sorted(d.items(), key=lambda t: t[1][1])

Should do the trick.

notes

  • t[1] # => the "value", t[0] is the "key"
  • t[1][1] # => The second element in the value.

You'll get a list of 2-tuples (where the first element is the key, and the second element is the value). Of course, you could always pass this list of 2-tuples directly to collections.OrderedDict if you wanted to construct a dict which has an ordering after the fact ...

1More correctly, the order is arbitrary and could change based on key insertions, deletions, python implementation or version ... (which is why it's easier to say that dict's are unordered)

mgilson
  • 264,617
  • 51
  • 541
  • 636
  • 1
    Perfecto! Aside, please could you refer me to the best resource on lambda. It always looks Greek to me. – sedeh Aug 18 '14 at 13:23
  • @sedeh -- `lamda arguments: expression` simply creates a function which evaluates the expression with the given arguments. I think I used this one a good bit back when I was first familiarizing myself with them: http://www.diveintopython.net/power_of_introspection/lambda_functions.html – mgilson Aug 18 '14 at 16:43
1

You can sort the keys and create another dict with ordered keys

>>>>from collections import OrderedDict
>>>>dict2 = {'employee1':['Paul', 23, 75000], 
     'employee2':['Mike', 32, 80000], 
     'employee3':['Jeremy', 25, 120000]}

>>>>OrderedDict([
        #new item: ordered key, it's value form original dict
        ( x, dict2[x]) 
        #sort keys of original dict
        for x in sorted(dict2, key=lambda x: dict2[x][1])
])
OrderedDict([('employee1', ['Paul', 23, 75000]), ('employee3', ['Jeremy', 25, 120000]), ('employee2', ['Mike', 32, 80000])])
xecgr
  • 4,297
  • 3
  • 14
  • 27
  • I'm not sure what you're going for here -- `dict(...)` will destroy any order that you got from the initial sort. – mgilson Aug 18 '14 at 06:07
  • you are right, I've change default dict to OrderedDict which lets you define key's order. This scripts output is the same that question's one – xecgr Aug 18 '14 at 06:12