Secondary list sorting comparison expression

D

David Pratt

I have been using the following for sorting a list of dictionaries.
This works but only provides sorting on a single key. I am wanting to
extend this with a better comparison expression so that it would sort
on one key as primary, a second key as secondary sort , and maybe even
a third as tertiary.

def sort_by_key(list, i):
list.sort(lambda a, b: cmp(a, b))

test_list = [{'number': 1, 'written_number': 'one','animal':
'giraffe','price': 1.50}, {'number': 2, 'written_number':
'two','animal': 'elephant', 'price': 2.50}, {'number': 3,
'written_number': 'three','animal': 'zebra', 'price': 1.50}, {'number':
4, 'written_number': 'four','animal': 'hippopotamus', 'price': 1.50}]

sort_by_key(test_list, 'price')

This returns:
[{'price': 1.5, 'number': 1, 'animal': 'giraffe', 'written_number':
'one'}, {'price': 1.5, 'number': 3, 'animal': 'zebra',
'written_number': 'three'}, {'price': 1.5, 'number': 4, 'animal':
'hippopotamus', 'written_number': 'four'}, {'price': 2.5, 'number': 2,
'animal': 'elephant', 'written_number': 'two'}]

What I am looking for would sort on more than one key so, say 'price'
and 'animal' so that the list would be ordered with the three items at
1.50 each but records would be giraffe, hippopotamus and zebra. If I
wanted to sort on three indexes, say 'price', 'animal' and 'written
number' and say last two animals were both zebras that it would put
this in the correct order also.

I am have to say I have read a good deal about sorting today but have
not come across a solution and have seen only limited comparison
expressions to know what could work.

Regards,
David
 
R

Raymond Hettinger

[David Pratt]
I am wanting to
extend this with a better comparison expression so that it would sort
on one key as primary, a second key as secondary sort , and maybe even
a third as tertiary.

The simplest approach is to rely on Python's sort being stable. First sort on
the tertiary key, then do another sort on the secondary key, and then sort on
the primary key.

def sort_by_key(list, i):
list.sort(lambda a, b: cmp(a, b))


Another way is to build out the sort_by_key function to handle multiple fields:

def sort_by_key(list, i, j, k):
list.sort(lambda a, b: cmp((a, a[j], a[k]), (b, b[j], b[k])))

In Py2.4, the key= option offers an alternative to cmp which is simpler and
faster:

def sort_by_key(list, i, j, k):
list.sort(key = lambda a : (a, a[j], a[k]))


Raymond Hettinger
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top