怎么让Python字典根据值快速排序.07年的时候, NICK GALBREATH在博客上发过一篇post post on sorting by value at Digital Sanitation Engineering介绍了一种方法, 并声称这个方法是“the fastest way to do this and it uses the least amount of memory. Enjoy.” 一般能这样声称的, 都会遭到别人质疑, 况且在python官网的Python Enhancement Proposals目录下, 还有不同的说法. 在PEP 265页面中,介绍了另外一种方法, 也说是最好的. 到底什么才是最快的字典排序方法?
Gregg Lind为了一探究竟,在去年7月的时候作了一次各种方法集合的比较, 比较的源代码如下:
def sbv0(adict,reverse=False):
return sorted(adict.iteritems(), key=lambda (k,v): (v,k), reverse=reverse)
def sbv1(d,reverse=False):
L = [(k,v) for (k,v) in d.iteritems()]
return sorted(L, key=lambda x: x[1] , reverse=reverse)
def sbv2(d,reverse=False):
L = ((k,v) for (k,v) in d.iteritems())
return sorted(L, key=lambda x: x[1] , reverse=reverse)
def sbv3(d,reverse=False):
return sorted(d.iteritems(), key=lambda x: x[1] , reverse=reverse)
def sbv4(d,reverse=False):
def sk(x):
return x[1]
return sorted(d.iteritems(), key=sk , reverse=reverse)
def sk(x):
return x[1]
def sbv5(d,reverse=False):
return sorted(d.iteritems(), key=sk , reverse=reverse)
from operator import itemgetter
def sbv6(d,reverse=False):
return sorted(d.iteritems(), key=itemgetter(1), reverse=True)
D = dict(zip(range(100),range(100)))
from profile import run
for ii in xrange(10000):
sbv6(D, reverse=True)
#run(for ii in xrange(10000): sbv0(D, reverse=True))
#run(for ii in xrange(10000): sbv1(D, reverse=True))
#run(for ii in xrange(10000): sbv2(D, reverse=True))
#run(for ii in xrange(10000): sbv3(D, reverse=True))
#run(for ii in xrange(10000): sbv4(D, reverse=True))
#run(for ii in xrange(10000): sbv5(D, reverse=True))
#run(for ii in xrange(10000): sbv6(D, reverse=True))
具体的结果, 直接拷贝代码到你的本机下运行即可知道. 在我这里, sbv6的时间是0.578s, 最慢的是用generator的sbv2, 22s左右, 其他时间是差不多的, 都是11s左右.
总的来说, PEP 265 介绍的方法基本是别的方法十倍左右的速度. 看来, 还是官网的东西比较可信阿:)