我想要一本深度嵌套的字典。让我们“深入地”考虑一下。为了展示我需要一个 5 级字典,例如 foo[1][2][3][4][5]
,它将有一个 set
或 列表
作为项目。
正如我所见here我至少可以通过两种方式来实现这一目标:
from collections import defaultdict
foo = defaultdict(lambda: defaultdict(lambda:defaultdict(lambda: defaultdict(lambda: defaultdict(set)))))
或
from functools import partial
foo = defaultdict(partial(defaultdict, partial(defaultdict, partial(defaultdict, partial(defaultdict, set)))))
然后在这两种情况下我都可以,例如 foo[1][2][3][4][5].add(1)
但我一直在寻找一种不太麻烦的方法来完成此任务,并找到了两种方法。第一个也与上述解决方案在同一位置提供:
class NestedDict(dict):
def __getitem__(self, key):
if key in self: return self.get(key)
return self.setdefault(key, NestedDict())
以及在 SO 中找到的第二个等效项 answer一个自动生存问题。
class NestedDict(dict):
"""Implementation of perl's autovivification feature."""
def __getitem__(self, item):
try:
print "__getitem__: %s" % item
return dict.__getitem__(self, item)
except KeyError:
value = self[item] = type(self)()
print "value: %s" % value
return value
我喜欢最后两种方法,但我不知道如何更改它们以生成非 dict 的特定类型的嵌套字典,例如 set
或 list
使用 defaultdict
完成。
预先感谢您的任何建议、评论或更正。
最佳答案
这是一个自动生存器,不需要您设置默认工厂的级别。当您获取 DefaultHasher 上不存在的属性时,它会将自身更改为默认工厂的实例:
class DefaultHasher(dict):
def __init__(self, default_factory, change_self=None):
self.default_factory = default_factory
self.change_self = change_self
def change(self, key):
def _change():
x = self.default_factory()
self[key] = x
return x
return _change
def __missing__(self, key):
self[key] = DefaultHasher(self.default_factory,
self.change(key))
return self[key]
def __getattr__(self, name):
result = self.change_self()
return getattr(result, name)
foo = DefaultHasher(set)
foo[1][2][3][4][5].add(1)
print(foo)
# {1: {2: {3: {4: {5: set([1])}}}}}
foo[1][2][3].add(20)
print(foo)
# {1: {2: {3: set([20])}}}
foo[1][3] = foo[1][2]
print(foo)
# {1: {2: {3: set([20])}, 3: {3: set([20])}}}
foo[1][2].add(30)
print(foo)
# {1: {2: set([30]), 3: {3: set([20])}}}
关于Python特定类型的深度嵌套字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17615206/