Welcome, guest | Sign In | My Account | Store | Cart

I wrote this method to be, first and foremost, flexible. This method implements what is referred to as a Schwartzian transform algorithm. This method does provide a mechanism to ensure stability in the sort. This version does a sort in place.

Python, 63 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
def sortByAttrs(seq, attrs):

	listComp = ['seq[:] = [(']

	for attr in attrs:
		listComp.append('seq[i].%s, ' % attr)

	listComp.append('i, seq[i]) for i in xrange(len(seq))]')

	exec('%s' % ''.join(listComp))

	seq.sort()

	seq[:] = [obj[-1] for obj in seq]

	return

#
# begin test code
#

from random import randint

class a:
	def __init__(self):
		self.x = (randint(1, 5), randint(1, 5))

class b:
	def __init__(self):
		self.x = randint(1, 5)
		self.y = (a(), a())

class c:
	def __init__(self, arg):
		self.x = arg
		self.y = b()

if __name__ == '__main__':

	aList = [c(1), c(2), c(3), c(4), c(5), c(6)]

	print '\n...to be sorted by obj.y.y[1].x[1]'
	print '    then, as needed, by obj.y.x'
	print '    then, as needed, by obj.x\n\n     ',

	for i in range(6):
		print '(' + str(aList[i].y.y[1].x[1]) + ',',
		print str(aList[i].y.x) + ',',
		print str(aList[i].x) + ') ',

	sortByAttrs(aList, ['y.y[1].x[1]', 'y.x', 'x'])

	print '\n\n...now sorted by listed attributes.\n\n     ',

	for i in range(6):
		print '(' + str(aList[i].y.y[1].x[1]) + ',',
		print str(aList[i].y.x) + ',',
		print str(aList[i].x) + ') ',
	print

#
# end test code
#

As demonstrated in the test code above, a list can be sorted by attribute, by dotted attribute, and by dotted attribute[index] forms.

The list/tuple of passed attributes can have an arbitrary length greater than zero. This allows for a very robust determination of comparison 'on the fly'. If an object in the list does not have a passed attribute, the method will throw (and not catch) an AttributeError.

Created by Frank H on Thu, 18 Sep 2003 (PSF)
Python recipes (4591)
Frank H's recipes (1)

Required Modules

Other Information and Tasks