Python内置函数sorted可以对可迭代对象进行排序,其中有cmp和key两个参数,这两个参数对排序的效率有很大的影响。
cmp是一个回调函数,原型是:cmp(x, y) ,这与其他语言的sort函数相似,上层自己对元素x和y进行比较,最终返回-1, 0, 1,以此来决定谁在前在后。
key也是一个回调函数,原型是:key(x), 这函数只有一个参数,是可迭代对象的元素,它的意图是通过该函数返回一个可比较的值,然后就不必通过函数来处理,直接比较就行了。因为元素可能是一个对象或其他复杂类型,不可以直接比较。
应该尽可能的使用key来进行排序,它能大大的提高效率,原因是cmp在一次排序中调用的次数很多,每比较两个元素就要调用一次;而key只需要每个元素调用一次;下面用代码来证明:
假设有一个学生类:
class student(object): def __init__(self, name, grade, age, score): self.name = name self.grade = grade self.age = age self.score = score我来生成10万个学生:
students = [student(random.choice(('tom', 'colin', 'lily', 'mike', 'red', 'blue')), random.randint(1, 6), random.randint(6, 16), \ random.randint(0, 150)) for i in xrange(100000)]现在要对这10万个学生进行排序,排序优化级分别是:
1. 年级按小到大排序
2. 分数按小到大排序
3. 年龄按小到大排序
首先我用cmp的方式来排序,并测试排序花费的时间:
def cmp(s1, s2): ret = s1.grade - s2.grade if ret != 0: return ret ret = s1.score - s2.score if ret != 0: return ret return s1.age - s2.age t1 = time.clock() students = sorted(students, cmp=cmp) t2 = time.clock() print 'time = ', t2 - t1输出的结果是:
time = 0.394109990123
按着我用key的方式来排序,用key的话需要使用一点技巧,将年级,分数,年龄三个结合起来转化成一个数值:
t1 = time.clock() students =sorted(students, key=lambda s: s.grade * 100000 + s.score*100 + s.age) t2 = time.clock() print 'time = ', t2 - t1输出的结果是:
time = 0.071763113157
效率快了好几倍。
当然这效率仍然不及原生语言,我用Delphi做了测试,速度还要快上3倍,如果Delphi也使用key的方式来优化排序,应该可以更快。
但不管怎么样,对于python来说,尽可能用key来排序总是没错的。