@@ -18,7 +18,9 @@ Sorting Basics
1818==============
1919
2020A simple ascending sort is very easy: just call the :func: `sorted ` function. It
21- returns a new sorted list::
21+ returns a new sorted list:
22+
23+ .. doctest ::
2224
2325 >>> sorted ([5 , 2 , 3 , 1 , 4 ])
2426 [1, 2, 3, 4, 5]
@@ -28,6 +30,8 @@ in-place (and returns ``None`` to avoid confusion). Usually it's less convenient
2830than :func: `sorted ` - but if you don't need the original list, it's slightly
2931more efficient.
3032
33+ .. doctest ::
34+
3135 >>> a = [5 , 2 , 3 , 1 , 4 ]
3236 >>> a.sort()
3337 >>> a
@@ -36,6 +40,8 @@ more efficient.
3640Another difference is that the :meth: `list.sort ` method is only defined for
3741lists. In contrast, the :func: `sorted ` function accepts any iterable.
3842
43+ .. doctest ::
44+
3945 >>> sorted ({1 : ' D' , 2 : ' B' , 3 : ' B' , 4 : ' E' , 5 : ' A' })
4046 [1, 2, 3, 4, 5]
4147
@@ -48,6 +54,8 @@ comparisons.
4854
4955For example, here's a case-insensitive string comparison:
5056
57+ .. doctest ::
58+
5159 >>> sorted (" This is a test string from Andrew" .split(), key = str .lower)
5260 ['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']
5361
@@ -59,6 +67,8 @@ input record.
5967A common pattern is to sort complex objects using some of the object's indices
6068as keys. For example:
6169
70+ .. doctest ::
71+
6272 >>> student_tuples = [
6373 ... (' john' , ' A' , 15 ),
6474 ... (' jane' , ' B' , 12 ),
@@ -69,6 +79,8 @@ as keys. For example:
6979
7080The same technique works for objects with named attributes. For example:
7181
82+ .. doctest ::
83+
7284 >>> class Student :
7385 ... def __init__ (self , name , grade , age ):
7486 ... self .name = name
@@ -95,6 +107,8 @@ convenience functions to make accessor functions easier and faster. The
95107
96108Using those functions, the above examples become simpler and faster:
97109
110+ .. doctest ::
111+
98112 >>> from operator import itemgetter, attrgetter
99113
100114 >>> sorted (student_tuples, key = itemgetter(2 ))
@@ -106,6 +120,8 @@ Using those functions, the above examples become simpler and faster:
106120The operator module functions allow multiple levels of sorting. For example, to
107121sort by *grade * then by *age *:
108122
123+ .. doctest ::
124+
109125 >>> sorted (student_tuples, key = itemgetter(1 ,2 ))
110126 [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
111127
@@ -119,6 +135,8 @@ Both :meth:`list.sort` and :func:`sorted` accept a *reverse* parameter with a
119135boolean value. This is used to flag descending sorts. For example, to get the
120136student data in reverse *age * order:
121137
138+ .. doctest ::
139+
122140 >>> sorted (student_tuples, key = itemgetter(2 ), reverse = True )
123141 [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
124142
@@ -132,6 +150,8 @@ Sorts are guaranteed to be `stable
132150<https://en.wikipedia.org/wiki/Sorting_algorithm#Stability> `_\. That means that
133151when multiple records have the same key, their original order is preserved.
134152
153+ .. doctest ::
154+
135155 >>> data = [(' red' , 1 ), (' blue' , 1 ), (' red' , 2 ), (' blue' , 2 )]
136156 >>> sorted (data, key = itemgetter(0 ))
137157 [('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]
@@ -143,13 +163,17 @@ This wonderful property lets you build complex sorts in a series of sorting
143163steps. For example, to sort the student data by descending *grade * and then
144164ascending *age *, do the *age * sort first and then sort again using *grade *:
145165
166+ .. doctest ::
167+
146168 >>> s = sorted (student_objects, key = attrgetter(' age' )) # sort on secondary key
147169 >>> sorted (s, key = attrgetter(' grade' ), reverse = True ) # now sort on primary key, descending
148170 [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
149171
150172This can be abstracted out into a wrapper function that can take a list and
151173tuples of field and order to sort them on multiple passes.
152174
175+ .. doctest ::
176+
153177 >>> def multisort (xs , specs ):
154178 ... for key, reverse in reversed (specs):
155179 ... xs.sort(key = attrgetter(key), reverse = reverse)
@@ -220,21 +244,27 @@ comparisons. That function should take two arguments to be compared and then
220244return a negative value for less-than, return zero if they are equal, or return
221245a positive value for greater-than. For example, we can do:
222246
247+ .. doctest ::
248+
223249 >>> def numeric_compare (x , y ):
224250 ... return x - y
225251 >>> sorted ([5 , 2 , 4 , 1 , 3 ], cmp = numeric_compare) # doctest: +SKIP
226252 [1, 2, 3, 4, 5]
227253
228254Or you can reverse the order of comparison with:
229255
256+ .. doctest ::
257+
230258 >>> def reverse_numeric (x , y ):
231259 ... return y - x
232260 >>> sorted ([5 , 2 , 4 , 1 , 3 ], cmp = reverse_numeric) # doctest: +SKIP
233261 [5, 4, 3, 2, 1]
234262
235263When porting code from Python 2.x to 3.x, the situation can arise when you have
236264the user supplying a comparison function and you need to convert that to a key
237- function. The following wrapper makes that easy to do::
265+ function. The following wrapper makes that easy to do:
266+
267+ .. testcode ::
238268
239269 def cmp_to_key(mycmp):
240270 'Convert a cmp= function into a key= function'
@@ -255,6 +285,12 @@ function. The following wrapper makes that easy to do::
255285 return mycmp(self.obj, other.obj) != 0
256286 return K
257287
288+ .. doctest ::
289+ :hide:
290+
291+ >>> sorted ([5 , 2 , 4 , 1 , 3 ], key = cmp_to_key(reverse_numeric))
292+ [5, 4, 3, 2, 1]
293+
258294To convert to a key function, just wrap the old comparison function:
259295
260296.. testsetup ::
@@ -280,6 +316,8 @@ Odd and Ends
280316 simulated without the parameter by using the builtin :func: `reversed ` function
281317 twice:
282318
319+ .. doctest ::
320+
283321 >>> data = [(' red' , 1 ), (' blue' , 1 ), (' red' , 2 ), (' blue' , 2 )]
284322 >>> standard_way = sorted (data, key = itemgetter(0 ), reverse = True )
285323 >>> double_reversed = list (reversed (sorted (reversed (data), key = itemgetter(0 ))))
@@ -289,7 +327,9 @@ Odd and Ends
289327
290328* The sort routines are guaranteed to use :meth: `__lt__ ` when making comparisons
291329 between two objects. So, it is easy to add a standard sort order to a class by
292- defining an :meth: `__lt__ ` method::
330+ defining an :meth: `__lt__ ` method:
331+
332+ .. doctest ::
293333
294334 >>> Student.__lt__ = lambda self , other : self .age < other.age
295335 >>> sorted (student_objects)
@@ -300,6 +340,8 @@ Odd and Ends
300340 are stored in a dictionary, they can be used to sort a separate list of student
301341 names:
302342
343+ .. doctest ::
344+
303345 >>> students = [' dave' , ' john' , ' jane' ]
304346 >>> newgrades = {' john' : ' F' , ' jane' :' A' , ' dave' : ' C' }
305347 >>> sorted (students, key = newgrades.__getitem__ )
0 commit comments