How to sort a list of objects based on an attribute of the objects?
A way that can be fastest, especially if your list has a lot of records, is to use operator.attrgetter("count")
. However, this might run on an pre-operator version of Python, so it would be nice to have a fallback mechanism. You might want to do the following, then:
try: import operatorexcept ImportError: keyfun= lambda x: x.count # use a lambda if no operator moduleelse: keyfun= operator.attrgetter("count") # use operator since it's faster than lambdaut.sort(key=keyfun, reverse=True) # sort in-place
Readers should notice that the key= method:
ut.sort(key=lambda x: x.count, reverse=True)
is many times faster than adding rich comparison operators to the objects. I was surprised to read this (page 485 of "Python in a Nutshell"). You can confirm this by running tests on this little program:
#!/usr/bin/env pythonimport randomclass C: def __init__(self,count): self.count = count def __cmp__(self,other): return cmp(self.count,other.count)longList = [C(random.random()) for i in xrange(1000000)] #about 6.1 secslongList2 = longList[:]longList.sort() #about 52 - 6.1 = 46 secslongList2.sort(key = lambda c: c.count) #about 9 - 6.1 = 3 secs
My, very minimal, tests show the first sort is more than 10 times slower, but the book says it is only about 5 times slower in general. The reason they say is due to the highly optimizes sort algorithm used in python (timsort).
Still, its very odd that .sort(lambda) is faster than plain old .sort(). I hope they fix that.