Pythonic方法确保列表在附加之前存在于dict键

时间:2013-02-20 01:56:49

标签: python

我从这个角度问这个问题,我的印象是要求宽恕而不是许可更像是Pythonic。

所以,我有一些类似的代码:

d = dict()
try:
    d[est['state']].append(est)
except Exception:
    d[est['state']] = []
    d[est['state']].append(est)

在上面的代码中,我要求宽恕而不是以允许重复自己为准,这是非常蹩脚的!所以,我知道别无选择,我宁愿:

d = dict()
if est['state'] in d:
    d[est['state']].append(est)
else:
    d[est['state']] = [est]

这两种方法都有点粗糙。有什么更好的方法呢?到目前为止我发现的最好的是:

from collections import defaultdict
d = defaultdict(list)
d[est['state']].append(est)

2 个答案:

答案 0 :(得分:1)

pythonic方式是你已经发现的后者:defaultdict是一个dict子类,它调用工厂函数来提供缺失值。它在python 2.5及更高版本中可用。

>>> import collections
>>> d = collections.defaultdict(list)
>>> d[0].append('potato')
>>> d
defaultdict(<type 'list'>, {0: ['potato']})

正是出于这个目的,所以尽可能避免dict.setdefault黑客攻击。

答案 1 :(得分:0)

如果您担心速度,可以尝试使用几种不同的方法进行基准测试。我尝试了“if key in dictionary”方法,并发现try / except平均速度提高了约10%。我发现这些问题中我的Python最佳实践每隔几年就会发生变化。如果您需要与Python 2.4兼容,这个答案可能会有所帮助。

使用你的例子,我会:

d = {}

# Confirm separately that est['state'] does not raise a KeyError.

state = est['state']

try:
    l = d[state]
except KeyError:
    l = []
    d[state] = l

l.append(est)