python - 一本宽容的字典

标签 python dictionary defaultdict dictionary-missing

我想知道如何创建宽容字典(如果引发 KeyError 则返回默认值的字典)。

在下面的代码示例中,我会得到一个 KeyError;例如

a = {'one':1,'two':2}
print a['three']

为了不得到一个,我会 1. 必须捕获异常或使用 get。

我不想用我的字典做那件事......

最佳答案

import collections
a = collections.defaultdict(lambda: 3)
a.update({'one':1,'two':2})
print a['three']

根据需要发出 3。您也可以自己子类化 dict 并覆盖 __missing__,但是当 defaultdict 行为(忽略确切丢失的键是正在查找)非常适合你...

编辑 ...除非,也就是说,您担心每次查找缺失项时 a 都会增长一个条目键(它是 defaultdict 语义的一部分)并且宁愿获得更慢的行为但节省一些内存。例如,在内存方面...:

>>> import sys
>>> a = collections.defaultdict(lambda: 'blah')
>>> print len(a), sys.getsizeof(a)
0 140
>>> for i in xrange(99): _ = a[i]
... 
>>> print len(a), sys.getsizeof(a)
99 6284

...defaultdict,最初是空的,现在有我们查找的 99 个以前丢失的键,占用 6284 字节(相比之下,它为空时占用 140 字节)。

替代方法...:

>>> class mydict(dict):
...   def __missing__(self, key): return 3
... 
>>> a = mydict()
>>> print len(a), sys.getsizeof(a)
0 140
>>> for i in xrange(99): _ = a[i]
... 
>>> print len(a), sys.getsizeof(a)
0 140

...如您所见,完全节省了内存开销。当然,性能是另一个问题:

$ python -mtimeit -s'import collections; a=collections.defaultdict(int); r=xrange(99)' 'for i in r: _=a[i]'
100000 loops, best of 3: 14.9 usec per loop

$ python -mtimeit -s'class mydict(dict):
>   def __missing__(self, key): return 0
> ' -s'a=mydict(); r=xrange(99)' 'for i in r: _=a[i]'
10000 loops, best of 3: 92.9 usec per loop

由于 defaultdict 在查找时添加了(先前丢失的)键,下次查找这样的键时它会变得更快,而 mydict (它覆盖了 __missing__ 以避免添加)每次都支付“丢失的 key 查找开销”。

当然,您是否关心这两个问题(性能与内存占用)完全取决于您的具体用例。在任何情况下,了解权衡都是一个好主意!-)

关于python - 一本宽容的字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3358580/

相关文章:

python - 在 Matplotlib 3D 图中更改旋转中心

python - 请求 URL 中缺少方案

python - 排列嵌套的 dict 项 Python

c++ - Python ImportError - undefined symbol - 用于自定义 C++ 模块

python - 使用 pandas.to_sql() 编写 datetime.datetime() 列

python - 将计数器对象映射到 DataFrame 以创建新列

android - 如何在android中的 map 上绘制叠加层?

python - 如何更改字典中键值对的顺序?

python - 将集合的 defaultdict 替换为带有 setdefault 的普通字典

python - 如何可视化和理解这段代码