views:

14150

answers:

9

I got a list of dictionaries and want that to be sorted by a value of that dictionary.

This

[{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

sorted by name, should become

[{'name':'Bart', 'age':10}, {'name':'Homer', 'age':39}]
+1  A: 

You have to implement your own comparison function that will compare the dictionaries by values of name keys. See Sorting Mini-HOW TO from PythonInfo Wiki

Matej
+2  A: 

I guess you've meant:

[{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

This would be sorted like this:

sorted(l,cmp=lambda x,y: cmp(x['name'],y['name']))
Bartosz Radaczyński
+1  A: 
input = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

input.sort(lambda x,y : cmp(x['name'], y['name']))

input will now be what you want.

pjz
+49  A: 

It may look cleaner using a key instead a cmp:

newlist = sorted(l, key=lambda k: k['name'])

or as J.F.Sebastian and others suggested,

from operator import itemgetter
newlist = sorted(l, key=itemgetter('name'))
Mario
Using key is not only cleaner but more effecient too.
J.F. Sebastian
`lambda k: k['name']` could be replaced by operator.itemgetter('name').
J.F. Sebastian
What would you change to make it sort descending?
NealWalters
The fastest way would be to add a newlist.reverse() statement. Otherwise you can define a comparison like cmp=lambda x,y: - cmp(x['name'],y['name']).
Mario
if the sort value is a number you could say:lambda k: (k['age'] * -1)to get a reverse sort
Philluminati
To sort descending: newlist = sorted(l, key=itemgetter('name'), reverse=True)
fitzgeraldsteele
+1  A: 
import operator
a_list_of_dicts.sort(key=operator.itemgetter('name'))

'key' is used to sort by an arbitrary value and 'itemgetter' sets that value to each item's 'name' attribute.

efotinis
+2  A: 

You could use a custom comparison function, or you could pass in a function that calculates a custom sort key. That's usually more efficient as the key is only calculated once per item, while the comparison function would be called many more times.

You could do it this way:

def mykey(adict): return adict['name']
x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}]
sorted(x, key=mykey)

But the standard library contains a generic routine for getting items of arbitrary objects: itemgetter. So try this instead:

from operator import itemgetter
x = [{'name': 'Homer', 'age': 39}, {'name': 'Bart', 'age':10}]
sorted(x, key=itemgetter('name'))
Owen
+1  A: 

import operator

to sort the list of dictionaries by key='name' :

list_of_dicts.sort(key=operator.itemgetter('name'))

to sort the list of dictionaries by key='age'

list_of_dicts.sort(key=operator.itemgetter('age'))
Anyway to combine name and age ? (like in SQL ORDER BY name,age ?)
monojohnny
A: 

Here is my answer to a related question on sorting by multiple columns. It also works for the degenerate case where the number of columns is only one.

hughdbrown
+2  A: 

If you want to sort the list by multiple keys you can do the following:

input = [{'name':'Homer', 'age':39}, {'name':'Milhouse', 'age':10}, {'name':'Bart', 'age':10} ]
sortedlist = sorted(input, key=lambda elem: "%02d %s" % (elem['age'], elem['name']))

It is rather hackish, since it relies on converting the values into a single string representation for comparison, but it works as expected for numbers including negative ones (although you will need to format your string appropriately with zero paddings if you are using numbers)

Dologan