3 回答
TA贡献1934条经验 获得超2个赞
在Python中实现嵌套字典的最佳方法是什么?
__missing__
dict
class Vividict(dict): def __missing__(self, key): value = self[key] = type(self)() # retain local pointer to value return value # faster to return than dict lookup
self[key]
data = {('new jersey', 'mercer county', 'plumbers'): 3, ('new jersey', 'mercer county', 'programmers'): 81, ('new jersey', 'middlesex county', 'programmers'): 81, ('new jersey', 'middlesex county', 'salesmen'): 62, ('new york', 'queens county', 'plumbers'): 9, ('new york', 'queens county', 'salesmen'): 36}
vividict = Vividict()for (state, county, occupation), number in data.items(): vividict[state][county][occupation] = number
>>> import pprint>>> pprint.pprint(vividict, width=40){'new jersey': {'mercer county': {'plumbers': 3, 'programmers': 81}, 'middlesex county': {'programmers': 81, 'salesmen': 62}}, 'new york': {'queens county': {'plumbers': 9, 'salesmen': 36}}}
批评
>>> vividict['new york']['queens counyt']{}
>>> pprint.pprint(vividict, width=40){'new jersey': {'mercer county': {'plumbers': 3, 'programmers': 81}, 'middlesex county': {'programmers': 81, 'salesmen': 62}}, 'new york': {'queens county': {'plumbers': 9, 'salesmen': 36}, 'queens counyt': {}}}
说明:
Vividict
class AutoVivification(dict): """Implementation of perl's autovivification feature.""" def __getitem__(self, item): try: return dict.__getitem__(self, item) except KeyError: value = self[item] = type(self)() return value
示范使用
import pprintclass Vividict(dict): def __missing__(self, key): value = self[key] = type(self)() return value d = Vividict()d['foo']['bar']d['foo']['baz']d['fizz']['buzz']d['primary']['secondary']['tertiary']['quaternary']pprint.pprint(d)
{'fizz': {'buzz': {}}, 'foo': {'bar': {}, 'baz': {}}, 'primary': {'secondary': {'tertiary': {'quaternary': {}}}}}
__missing__
与之相反的其他备选办法:
dict.setdefault
Vividict
d = {} # or dict()for (state, county, occupation), number in data.items(): d.setdefault(state, {}).setdefault(county, {})[occupation] = number
>>> pprint.pprint(d, width=40){'new jersey': {'mercer county': {'plumbers': 3, 'programmers': 81}, 'middlesex county': {'programmers': 81, 'salesmen': 62}}, 'new york': {'queens county': {'plumbers': 9, 'salesmen': 36}}}
>>> d['new york']['queens counyt']Traceback (most recent call last): File "<stdin>", line 1, in <module>KeyError: 'queens counyt'
d = dict()d.setdefault('foo', {}).setdefault('bar', {})d.setdefault('foo', {}).setdefault('baz', {})d.setdefault('fizz', {}).setdefault ('buzz', {})d.setdefault('primary', {}).setdefault('secondary', {}).setdefault('tertiary', {}).setdefault('quaternary', {})
>>> id({}), id({}), id({})(523575344, 523575344, 523575344)
一个自动生动的默认设置
__missing__
:
from collections import defaultdictdef vivdict(): return defaultdict(vivdict)
>>> d = vivdict(); d['foo']['bar']; d['foo']['baz']; d['fizz']['buzz']; d['primary']['secondary']['tertiary']['quaternary']; import pprint; >>> pprint.pprint(d)defaultdict(<function vivdict at 0x17B01870>, {'foo': defaultdict(<function vivdict at 0x17B01870>, {'baz': defaultdict(<function vivdict at 0x17B01870>, {}), 'bar': defaultdict(<function vivdict at 0x17B01870>, {})}), 'pr mary': defaultdict(<function vivdict at 0x17B01870>, {'secondary': defaultdict(<function vivdict at 0x17B01870>, {'tertiary': defaultdict(<function vivdict at 0x17B01870 >, {'quaternary': defaultdict(<function vivdict at 0x17B01870>, {})})})}), 'fizz': defaultdict(<function vivdict at 0x17B01870>, {'buzz': defaultdict(<function vivdict at 0x17B01870>, {})})})
性能
>>> import timeit>>> min(timeit.repeat(lambda: {}.setdefault('foo', {}))) - min(timeit.repeat(lambda: {}))0.13612580299377441>>> min(timeit.repeat(lambda: vivdict()['foo'])) - min(timeit.repeat(lambda: vivdict()))0.2936999797821045>>> min(timeit.repeat(lambda: Vividict()['foo'])) - min(timeit.repeat(lambda: Vividict()))0.5354437828063965>>> min(timeit.repeat(lambda: AutoVivification()['foo'])) - min(timeit.repeat(lambda: AutoVivification()))2.138362169265747
dict.setdefault
__getitem__
__missing__
结语
__missing__
dict
易实例化 易数据总体 容易查看数据
__getitem__
糟糕的查找将悄悄地失败。 糟糕的查找将留在字典中。
setdefault
TA贡献1789条经验 获得超8个赞
class AutoVivification(dict): """Implementation of perl's autovivification feature.""" def __getitem__(self, item): try: return dict.__getitem__(self, item) except KeyError: value = self[item] = type(self)() return value
a = AutoVivification()a[1][2][3] = 4a[1][3][3] = 5a[1][2]['test'] = 6print a
{1: {2: {'test': 6, 3: 4}, 3: {3: 5}}}
TA贡献1859条经验 获得超6个赞
# yo dawg, i heard you liked dicts def yodict(): return defaultdict(yodict)
添加回答
举报