## 3 Operator Module Functions 

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(student_tuples, key =itemgetter(2)) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] 

>>> sorted(student_objects, 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(student_tuples, key =itemgetter(1,2)) [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)] 

>>> sorted(student_objects, key =attrgetter( 'grade','age')) [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)] 

## 4 Ascending and Descending 

Both$_{list.sort()}$ and$_{sorted()}$ accept a reverse parameter with a boolean value. This is used to flag descend- ing sorts. For example, to get the student data in reverse age order: 

>>> sorted(student_tuples, key =itemgetter(2), reverse = True ) [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)] 

>>> sorted(student_objects, key =attrgetter( 'age'), reverse = True ) [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)] 

## 5 Sort Stability and Complex Sorts 

Sorts are guaranteed to be stable. That means that when multiple records have the same key, their original order is preserved. 

>>> data =[('red',1), ( 'blue',1), ( 'red',2), ( 'blue',2)] >>> sorted(data, key =itemgetter(0)) [('blue', 1), ('blue', 2), ('red', 1), ('red', 2)] 

Notice how the two records for blue retain their original order so that$_{('blue', 1)}$ is guaranteed to precede ('blue', 2) . 

This wonderful property lets you build complex sorts in a series of sorting steps. For example, to sort the student data by descending grade and then ascending age , do the age sort first and then sort again using grade : 

>>> s =sorted(student_objects, key =attrgetter( 'age')) # sort on secondary key >>> sorted(s, key =attrgetter( 'grade'), reverse = True ) # now sort on primary ␣ ↪ → key, descending [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] 

