对于这种特定情况,请改用collections.Counter() 或collections.defaultdict() 对象:
import collections
dct = collections.defaultdict(int)
for c in string:
dict[c] += 1
或
dct = collections.Counter(string)
两者都是标准dict 类型的子类。 Counter 类型添加了一些更有用的功能,例如将两个计数器相加或列出已计数的最常见实体。 defaultdict 类也可以被赋予其他默认类型;例如,使用defaultdict(list) 将内容收集到每个键的列表中。
当您想比较两种不同方法的性能时,您想使用timeit module:
>>> 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
这说明使用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
这恰好是最快的,因为只有十分之一的案例用于新密钥。
最后但同样重要的是,我提出了两种选择:
>>> 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
所以Counter() 类型最慢,但defaultdict 确实非常快。 Counter()s 做了更多的工作,额外的功能可以在其他地方带来易于开发和执行速度的好处。