Cheat on Python sorting

Home

1 Defiition/Syntax (sort vs sorted)

1.1 mylist.sort()

The list.sort() method modifies the list in-place (and returns None to avoid confusion.) Usually less convient than sorted, but if you don't need the original list, it is slightly more efficient.

1.2 sorted(mylist)

Calling the sorted() function returns a new sorted list.

sorted([5, 2, 4, 1, 3])

Returns: [1, 2, 3, 4, 5]

1.3 Modifiers.

Both mylist.sort() and sorted(mylist) can use optional key functions:

  • mylist.sort(reverse=True|False, key=myFunc)

Where reverse is optional specifiys ascending (False) or descending (True) And key=myFunc is optional function that can specify the sorting criteria See lambda examples below:

2 Simple Examples

movies = ["Jabberwalkie", "Life of Brian", "Holy Grail", "A Meaning of Life"]
movies.sort()

3 Examples with key based sorting

This example sorts by length of string, not by alphabetical order

# A function that returns the length of the value:
def myFunc(e):
    return len(e)

actors = ['John', 'Michael', 'Eric', 'Graham', 'Terry', 'Terry']
actors.sort(key=myFunc)

3.1 Examples key based sorting using dictionary keys

>>> student_tuples = [
    ('john', 'A', 15),
    ('jane', 'B', 12),
    ('dave', 'B', 10),
    ]
>>> sorted(student_tuples, key=lambda student: student[2])   # sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

See the lamda.org file for details on lambda functions.

The same technique works for objects with named attributes.

# Initializing list of dictionaries 
knights = [{ "name" : "King Arthur", "age" : 40},  
   { "name" : "Sir Robin", "age" : 42 }, 
   { "name" : "Sir Bedevere", "age" : 42 }, 
   { "name" : "Sir Lancelot", "age" : 41 }, 
   { "name" : "Patsy", "age" : 35 }, 
   { "name" : "Sir Galahad", "age" : 39 }] 

 pprint(knights)
 # using sorted and lambda to print list sorted
 # by age

 print("The list printed sorting by age: ")
 pprint(sorted(knights, key = lambda i: i['age']))


 # using sorted and lambda to print list sorted
 # by both age and name. Notice that "Sir Bedevere"
 # now comes before "Sir Robin"
 print("The list printed sorting by age and name: ")
 pprint( sorted(knights, key = lambda i: (i['age'], i['name'])))

 # Another example with classes: 
 >>> class Student:
      def __init__(self, name, grade, age):
          self.name = name
          self.grade = grade
          self.age = age
      def __repr__(self):
          return repr((self.name, self.grade, self.age))

 >>> student_objects = [
     Student('john', 'A', 15),
     Student('jane', 'B', 12),
     Student('dave', 'B', 10),
     ]
 >>> sorted(student_objects, key=lambda student: student.age)   # sort by age
 [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

3.2 Examples of sorting a list of dictionaries according to some dictionary value

Python code snippet that uses both lamda, and sorting by key


# Initializing list of dictionaries

from pprint import pprint

knights = [{ "name" : "King Arthur", "age" : 40},  
   { "name" : "Sir Robin", "age" : 42 }, 
   { "name" : "Sir Bedevere", "age" : 42 }, 
   { "name" : "Sir Lancelot", "age" : 41 }, 
   { "name" : "Patsy", "age" : 35 }, 
   { "name" : "Sir Galahad", "age" : 39 }] 

pprint(knights)

# using sorted and lambda to print list sorted
# by age

print("The list printed sorting by age: ")
pprint(sorted(knights, key = lambda i: i['age']))

# using sorted and lambda to print list sorted
# by both age and name. Notice that "Sir Bedevere"
# now comes before "Sir Robin"

print("The list printed sorting by age and name: ")
pprint( sorted(knights, key = lambda i: (i['age'], i['name'])))

# now in descending order

print("The list printed sorting by age in descending order: " )
pprint(sorted(knights, key = lambda i: i['age'],reverse=True))

Similar technique for tuples:

>>> student_tuples = [
   ('john', 'A', 15),
   ('jane', 'B', 12),
   ('dave', 'B', 10),
   ]

>>> sorted(student_tuples, key=lambda student: student[2])   
# sort by age
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

3.3 Examples using Python's standard library itemgetter module

3.3.1 See also ~/bin/python/bin/sort-keys-dicionary.py

Also the attrgetter module. from operator import itemgetter, attrgetter

The key-function patterns shown above are very common, so Python provides convenience functions to make accessor functions easier and faster. The operator module has itemgetter(), attrgetter(), and a methodcaller() function.

Using those functions, the above examples become simpler and faster:

>>> >>> from operator import itemgetter, attrgetter >>> >>> sorted(studenttuples, key=itemgetter(2)) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] >>> >>> sorted(studentobjects, key=attrgetter('age')) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] The operator module functions allow multiple levels of sorting. For example, to sort by grade then by age:

>>> >>> sorted(studenttuples, key=itemgetter(1,2)) [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)] >>> >>> sorted(studentobjects, key=attrgetter('grade', 'age')) [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

3.4 Home