我从这个角度问这个问题,我的印象是要求宽恕而不是许可更像是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)
答案 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)