Newbie: sort list of dictionaries
Wade Leftwich
wade at lightlink.com
Tue Dec 30 17:40:42 EST 2003
Paul Rubin <http://phr.cx@NOSPAM.invalid> wrote in message news:<7xy8su7a1k.fsf at ruckus.brouhaha.com>...
> Sven Brandt <no_more_spam at no_use_for.me> writes:
> > I have a list of dictionaries. I want the elements of the list to be
> > sorted by the value of a key of the dict .
> >
> > Excample:
> > my_list=[{'title': 'foo', 'id': 5, 'text': 'some text'},
> > {'title': 'bar', 'id': 3, 'text': 'my text'},
> > {'title': 'bla', 'id': 6, 'text': 'any text'}, ]
> >
> > my_list.sort("by the id value")
>
> The Pythonic way to do it may not be what you're used to, but once you
> understand it you'll be able to apply the understanding to other areas
> of programming.
>
> The list sort method lets you pass an optional comparison function,
> that takes two items and returns -1, 0, or 1, depending on what order
> the items are supposed to appear in. The comparison function takes
> exactly two args (the items to be compared). You can't pass a third
> arg to specify the field name. You could do something ugly like use a
> global variable, but the preferred way given a field name is to
> construct a brand new comparison function just for that name:
>
> def compare_by (fieldname):
> def compare_two_dicts (a, b):
> return cmp(a[fieldname], b[fieldname])
> return compare_two_dicts
> [snip ...]
Another way to do it, also Pythonic I think, is with the
Decorate-Sort-Undecorate (DSU) pattern:
unsorted_list = [{'id':99, 'title':'a'},{'id':42, 'title':'b'}, ... ]
decorated_list = [(x['id'],x) for x in unsorted_list]
decorated_list.sort()
sorted_list = [y for (x,y) in decorated_list]
If performance is a consideration, this is supposed to be much faster
than providing a comparison function to list.sort().
If you want to package it up as a function, try this:
>>> def sortlist(L, decorator=None):
... if decorator is None:
... def decorator(x):
... return x
... newL = [(decorator(x), x) for x in L]
... newL.sort()
... L[:] = [y for (x,y) in newL]
...
>>> L = [2,3,6,1,17,0]
>>> sortlist(L)
>>> L
[0, 1, 2, 3, 6, 17]
>>> L = [{'id':99, 'title':'a'},{'id':42, 'title':'b'}]
>>> def mydecorator(mydict):
... return mydict['id']
...
>>> sortlist(L, mydecorator)
>>> L
[{'id': 42, 'title': 'b'}, {'id': 99, 'title': 'a'}]
>>>
Now you have in-place sorting, just like with the built-in sort()
method.
-- Wade Leftwich
Ithaca, NY
More information about the Python-list
mailing list