如何添加或增加字典条目?

cur*_*rsa 57 python syntax

我目前正在重新与Python合作,并且喜欢它.但是,我发现自己一遍又一遍地遇到一种模式.我一直在想,必须有一种更好的方式来表达我想要的东西,而且我可能是以错误的方式做到这一点.

我正在编写的代码如下:

# foo is a dictionary
if foo.has_key(bar):
  foo[bar] += 1
else:
  foo[bar] = 1
Run Code Online (Sandbox Code Playgroud)

我在我的程序中写了很多.我的第一反应是推出一个帮助函数,但是python库经常提供这样的东西.

是否有一些我缺少的简单的小语法技巧?或者这是应该做的方式?

Tam*_*más 99

使用defaultdict:

from collections import defaultdict

foo = defaultdict(int)
foo[bar] += 1
Run Code Online (Sandbox Code Playgroud)

在Python> = 2.7中,您还有一个单独的Counter类用于这些目的.对于Python 2.5和2.6,您可以使用其反向移植版本.

  • `collections.Counter`在`2.7`http://docs.python.org/dev/whatsnew/2.7.html#new-and-improved-modules (3认同)

sth*_*sth 98

所述dictget()方法采用的是可以被用来提供一个缺省值,如果所请求的密钥未找到一个可选的第二个参数:

foo[bar] = foo.get(bar, 0) + 1
Run Code Online (Sandbox Code Playgroud)

  • @Tamas ......这似乎是对DRY原理的一种相当极端的解释......我通常在重复逻辑的背景下看到它 - 而不是变量名称!这本书是一个很好的答案,因为它可以干净地传达逻辑,并且可以适应多种场景(任何默认值,任何要执行的功能) (18认同)
  • 为什么选择downvote?它有效且可读 (4认同)
  • 我没有否决它,但我猜最初的否决者这样做是因为它违反了 DRY(不要重复自己)原则:“foo”和“bar”都被提到了两次。 (2认同)
  • 这比接受的答案要好,不需要导入。 (2认同)

小智 5

我做了一些时间比较.几乎相同.但是,单行.get()命令最快.

输出:

get 0.543551800627
exception 0.587318710994
haskey 0.598421703081
Run Code Online (Sandbox Code Playgroud)

码:

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()
Run Code Online (Sandbox Code Playgroud)