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

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

快速排序

最快方式

1
2
3
4
5
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)]

不同方法比较

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

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

比较结果

上面测试代码输出的结果

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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] 排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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']

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

1
2
3
4
5
6
7
8
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'))

本文网址: https://pylist.com/topic/25.html 转摘请注明来源

Suggested Topics

Python List 按键高效排序方法

Python含有许多古老的排序规则,这些规则在你创建定制的排序方法时会占用很多时间,而这些排序方法运行时也会拖延程序实际的运行速度。...

python 对中文链接安全转码

当一个链接里包含中文时,有些浏览器并不能正确解析,这就需要首先对中文作安全转码,这里介绍用 python 对中文链接安全转码,...

Leave a Comment