关于python:如何添加或增加字典条目?

How to add or increment a dictionary entry?

我现在正在和Python接触,在很久不在的时候,我很喜欢它。然而,我发现自己一次又一次地遇到一个模式。我一直在想,一定有更好的方式来表达我想要的东西,而且我可能做得不对。

我正在编写的代码格式如下:

1
2
3
4
5
# foo is a dictionary
if foo.has_key(bar):
  foo[bar] += 1
else:
  foo[bar] = 1

我在我的程序中写了很多。我的第一个反应是将它推出到一个助手函数中,但是通常Python库已经提供了类似的东西。

有没有一些简单的语法技巧我不知道?还是应该这样做?


使用defaultdict

1
2
3
4
from collections import defaultdict

foo = defaultdict(int)
foo[bar] += 1

在python>=2.7中,为了这些目的,您还拥有一个单独的counter类。对于python 2.5和2.6,可以使用它的后端口版本。


dictget()方法采用一个可选的第二个参数,如果找不到请求的键,该参数可用于提供默认值:

1
foo[bar] = foo.get(bar, 0) + 1


我做了一些时间比较。差不多。不过,单行的.get()命令速度最快。

输出:

1
2
3
get 0.543551800627
exception 0.587318710994
haskey 0.598421703081

代码:

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
import timeit
import random

RANDLIST = [random.randint(0, 1000) for i in range(10000)]

def get():
    foo = {}
    for bar in RANDLIST:
        foo[bar] = foo.get(bar, 0) + 1


def exception():
    foo = {}
    for bar in RANDLIST:
        try:
            foo[bar] += 1
        except KeyError:
            foo[bar] = 1


def haskey():
    foo = {}
    for bar in RANDLIST:
        if foo.has_key(bar):
            foo[bar] += 1
        else:
            foo[bar] = 1


def main():
    print 'get', timeit.timeit('get()', 'from __main__ import get', number=100)
    print 'exception', timeit.timeit('exception()', 'from __main__ import exception', number=100)
    print 'haskey', timeit.timeit('haskey()', 'from __main__ import haskey', number=100)


if __name__ == '__main__':
    main()


您还可以利用异常处理中的控制结构。当您试图将一个值赋给一个不存在的键时,字典会抛出一个KeyError异常:

1
2
3
4
5
my_dict = {}
try:
    my_dict['a'] += 1
except KeyError, err:    # in 2.6: `except KeyError as err:`
    my_dict['a'] = 1


对于python>=2.5,可以执行以下操作:

1
foo[bar] = 1 if bar not in foo else foo[bar]+1