dict.get()方法的效率

noo*_*r69 0 python methods dictionary get

我刚刚开始学习python,并担心如果我使用dict.get(key,default_value)或者我为它定义自己的方法....所以它们有任何区别:

[第一种方法]:

dict={}
for c in string:
    if c in dict:
        dict[c]+=1
    else:
        dict[c]=1
Run Code Online (Sandbox Code Playgroud)

和python提供的另一个dict.get()方法

for c in string:
    dict[c]=dict.get(c,0)+1
Run Code Online (Sandbox Code Playgroud)

他们在效率或速度方面有任何差异......或者它们是相同的,第二个只能节省更多的代码行...

Mar*_*ers 6

对于这种特定情况,请使用a collections.Counter()collections.defaultdict()对象:

import collections

dct = collections.defaultdict(int)

for c in string:
     dict[c] += 1
Run Code Online (Sandbox Code Playgroud)

要么

dct = collections.Counter(string)
Run Code Online (Sandbox Code Playgroud)

两者都是标准dict类型的子类.该Counter类型添加了一些更有用的功能,例如对两个计数器求和或列出已计数的最常见实体.该defaultdict班也可以给予其他的默认类型; 使用defaultdict(list)例如收集到的东西每个键列表.

如果要比较两种不同方法的性能,则需要使用该timeit模块:

>>> import timeit
>>> def intest(dct, values):
...     for c in values:
...         if c in dct:
...             dct[c]+=1
...         else:
...             dct[c]=1
... 
>>> def get(dct, values):
...     for c in values:
...         dct[c] = dct.get(c, 0) + 1
... 
>>> values = range(10) * 10
>>> timeit.timeit('test(dct, values)', 'from __main__ import values, intest as test; dct={}')
22.210275888442993
>>> timeit.timeit('test(dct, values)', 'from __main__ import values, get as test; dct={}')
27.442166090011597
Run Code Online (Sandbox Code Playgroud)

这表明使用in速度要快一些.

但是,还有第三种选择可供考虑; 捕获KeyError异常:

>>> def tryexcept(dct, values):
...     for c in values:
...         try:
...             dct[c] += 1
...         except KeyError:
...             dct[c] = 1
... 
>>> timeit.timeit('test(dct, values)', 'from __main__ import values, tryexcept as test; dct={}')
18.023509979248047
Run Code Online (Sandbox Code Playgroud)

这恰好是最快的,因为10个案例中只有1个用于新密钥.

最后但同样重要的是,我提出的两个备选方案:

>>> def default(dct, values):
...     for c in values:
...         dct[c] += 1
... 
>>> timeit.timeit('test(dct, values)', 'from __main__ import values, default as test; from collections import defaultdict; dct=defaultdict(int)')
15.277361154556274
>>> timeit.timeit('Counter(values)', 'from __main__ import values; from collections import Counter')
38.657804012298584
Run Code Online (Sandbox Code Playgroud)

因此,Counter()类型是最慢的,但是defaultdict非常快确实如此.Counter()虽然做了很多工作,但额外的功能可以使其他地方的开发和执行速度更快.