pyList

传说中最快的python字典排序方法

对简单字典的排序,如d = {'a':2, 'b':23, 'c':5, 'd':17, 'e':1},按key-value排序,官方有一种传说是最快的方法。

快速排序

最快方式

from operator import itemgetter

d = {'a':2, 'b':23, 'c':5, 'd':17, 'e':1}
d2 = sorted(d.iteritems(), key=itemgetter(1), reverse=True)
# d2 = [('b', 23), ('d', 17), ('c', 5), ('a', 2), ('e', 1)]

不同方法比较

另附一些排序方法的测试代码:

def sbv0(d,reverse=False):
    return sorted(d.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):
    return sorted(d.items(), key=lambda x: x[1] , reverse=reverse)

def sbv3(d,reverse=False):
    L = ((k,v) for (k,v) in d.iteritems())
    return sorted(L, key=lambda x: x[1] , reverse=reverse)

def sbv4(d,reverse=False):
    return sorted(d.iteritems(), key=lambda x: x[1] , reverse=reverse)

from operator import itemgetter
def sbv5(d,reverse=False):
    return sorted(d.iteritems(), key=itemgetter(1), reverse=True)

D = dict(zip(range(100),range(100)))

from profile import run

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)")

比较结果

上面测试代码输出的结果

1030003 function calls in 5.028 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    10000    0.028    0.000    0.028    0.000 :0(iteritems)
        1    0.000    0.000    0.000    0.000 :0(setprofile)
    10000    2.648    0.000    4.896    0.000 :0(sorted)
        1    0.048    0.048    5.028    5.028 <string>:1(<module>)
        1    0.000    0.000    5.028    5.028 profile:0(for ii in xrange(10000):  sbv0(D, reverse=True))
        0    0.000             0.000          profile:0(profiler)
    10000    0.056    0.000    4.980    0.000 sortdict.py:1(sbv0)
  1000000    2.248    0.000    2.248    0.000 sortdict.py:2(<lambda>)

         1030003 function calls in 4.792 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    10000    0.028    0.000    0.028    0.000 :0(iteritems)
        1    0.000    0.000    0.000    0.000 :0(setprofile)
    10000    2.324    0.000    4.476    0.000 :0(sorted)
        1    0.056    0.056    4.792    4.792 <string>:1(<module>)
        1    0.000    0.000    4.792    4.792 profile:0(for ii in xrange(10000):  sbv1(D, reverse=True))
        0    0.000             0.000          profile:0(profiler)
    10000    0.232    0.000    4.736    0.000 sortdict.py:4(sbv1)
  1000000    2.152    0.000    2.152    0.000 sortdict.py:6(<lambda>)

         1030003 function calls in 4.516 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    10000    0.048    0.000    0.048    0.000 :0(items)
        1    0.000    0.000    0.000    0.000 :0(setprofile)
    10000    2.132    0.000    4.364    0.000 :0(sorted)
        1    0.028    0.028    4.516    4.516 <string>:1(<module>)
        1    0.000    0.000    4.516    4.516 profile:0(for ii in xrange(10000):  sbv2(D, reverse=True))
        0    0.000             0.000          profile:0(profiler)
    10000    0.076    0.000    4.488    0.000 sortdict.py:8(sbv2)
  1000000    2.232    0.000    2.232    0.000 sortdict.py:9(<lambda>)

         2040003 function calls in 9.073 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    10000    0.028    0.000    0.028    0.000 :0(iteritems)
        1    0.000    0.000    0.000    0.000 :0(setprofile)
    10000    4.524    0.000    8.897    0.001 :0(sorted)
        1    0.040    0.040    9.073    9.073 <string>:1(<module>)
        1    0.000    0.000    9.073    9.073 profile:0(for ii in xrange(10000):  sbv3(D, reverse=True))
        0    0.000             0.000          profile:0(profiler)
    10000    0.108    0.000    9.033    0.001 sortdict.py:11(sbv3)
  1010000    2.340    0.000    2.340    0.000 sortdict.py:12(<genexpr>)
  1000000    2.032    0.000    2.032    0.000 sortdict.py:13(<lambda>)

         1030003 function calls in 4.664 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    10000    0.004    0.000    0.004    0.000 :0(iteritems)
        1    0.000    0.000    0.000    0.000 :0(setprofile)
    10000    2.348    0.000    4.548    0.000 :0(sorted)
        1    0.024    0.024    4.664    4.664 <string>:1(<module>)
        1    0.000    0.000    4.664    4.664 profile:0(for ii in xrange(10000):  sbv4(D, reverse=True))
        0    0.000             0.000          profile:0(profiler)
    10000    0.088    0.000    4.640    0.000 sortdict.py:15(sbv4)
  1000000    2.200    0.000    2.200    0.000 sortdict.py:16(<lambda>)

         30003 function calls in 0.336 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    10000    0.004    0.000    0.004    0.000 :0(iteritems)
        1    0.000    0.000    0.000    0.000 :0(setprofile)
    10000    0.204    0.000    0.204    0.000 :0(sorted)
        1    0.044    0.044    0.336    0.336 <string>:1(<module>)
        1    0.000    0.000    0.336    0.336 profile:0(for ii in xrange(10000):  sbv5(D, reverse=True))
        0    0.000             0.000          profile:0(profiler)
    10000    0.084    0.000    0.292    0.000 sortdict.py:19(sbv5)

扩展排序

对下面字典,按d[key][1] 排序

d = { 'a1': ['g',6],
           'a2': ['e',2],
           'a3': ['h',3],
           'a4': ['s',2],
           'a5': ['j',9],
           'a6': ['y',7] }

# L = sorted(d, key=lambda k:d[k][1])
# L = sorted(d, key=lambda k:d[k][0])
L = sorted(d.items(), key=lambda (k, v): v[1])

# L [('a2', ['e', 2]), ('a4', ['s', 2]), ('a3', ['h', 3]), ('a1', ['g', 6]), ('a6', ['y', 7]), ('a5', ['j', 9])]

# 获取排序后的key
map(lambda (k,v): k, L)

# ['a2', 'a4', 'a3', 'a1', 'a6', 'a5']

对一个字典列表,按字典的某个键排序

from operator import itemgetter

old_list = [{'name':'Homer', 'age':39}, {'name':'Bart', 'age':10}]

newlist = sorted(old_list, key=itemgetter('name')) 
# newlist = sorted(old_list, key=lambda k: k['name'])
# newlist = sorted(old_list, key=itemgetter('name'), reverse=True)
# old_list.sort(key=itemgetter('name'))
本文标签: 性能 排序 Python
本文网址: https://pylist.com/t/1348382582 (转载注明出处)
如果你有任何建议或疑问可以在下面 留言
发表第一条评论!
验证码图片
相关推荐