ActiveState Code

Recipe 305321: SQL-like ORDER BY function for lists


This function allows you to easily sort a list by multiple columns in ascending and descending orders similar in function to the ORDER BY clause in SQL.

Python
1
2
3
4
5
6
7
8
9
def orderBy(sortlist, orderby=[], desc=[]):
    '''orderBy(sortlist, orderby, desc) >> List
    sortlist: list to be sorted
    orderby: list of field indexes
    desc: list of field indexes that are to be sorted descending'''      
    orderby.reverse()
    for i in orderby:
        sortlist.sort(lambda x, y: cmp(*[(x[i], y[i]), (y[i], x[i])][i in desc]))
    return sortlist

Discussion

Imagine you have a list:

New = [[1, 50.00, 'Bob'], [4, 50.00, 'Mary'], [3, 500.00, 'Tom'], [5, 75.00, 'Tracy'], [7, 175.00, 'Linda'], [2, 75.00, 'Charles']]

Now imagine this list is a SQL table (with fields called Loans, Amount, Name) and you want them in a particular order You might say:

SELECT *
  FROM New
 ORDER BY Amount DESC, Loans, Name

We are asking for the Amount field to be sorted in descending order.

To duplicate this using the above function:

NewList = orderBy(New, [1, 0, 2], [1])

Comments

  1. 1. At 10:22 p.m. on 24 sep 2004, Jonathan Wright said:

    and in Python 2.4.

    def orderBy(sortlist, orderby=[], desc=[]):
        for i in reversed(orderby):
            sortlist.sort(key=operator.itemgetter(i), reverse=(i in desc))
        return sortlist
    
  2. 2. At 5:12 p.m. on 24 oct 2004, pythondev dev said:

    please explain. can you please explain the code which Steve Lucy has written. what is the use of * how is the cmp function working inhis code thanks

  3. 3. At 7:57 a.m. on 1 nov 2004, Steve Lucy (the author) said:

    The * causes the tuple we choose, (x[i], y[i]) or (y[i], x[i]), to be mapped to the function's arguments, instead of being passed as a single argument (i.e., cmp(x[i], y[i]) and not cmp((x[i], y[i]))

    Let's say you have a function:

    def Add(a, b):
        return a + b
    

    and a list of values you want added:

    w = [(1, 2),
         (2, 2),
         (3, 4)]
    

    instead of saying something like:

    for a, b in w:
        print Add(a, b)
    

    You could say:

    for i in w:
        print Add(*i)
    

Sign in to comment