Python特定类型的深度嵌套字典

标签 python dictionary functools

我想要一本深度嵌套的字典。让我们“深入地”考虑一下。为了展示我需要一个 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 的特定类型的嵌套字典,例如 setlist 使用 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/

相关文章:

python - 从 Python 中的列表填充字典中的键元组和值

c++ find()用于成员函数的映射

java - HashMap,其中键的顺序很重要

python - 使用装饰器记录执行时间

python-docx:在后面插入一段

python - 列表行为异常

python - 如何使用 duck typing 编写 OOP 一致的代码?

python - pandas 是否可以在 diff 操作中将(NULL)不存在的索引/值视为 0?

python - 部分:不允许覆盖给定的关键字参数

python - 创建一个组合两个函数的装饰器,而不指定原始函数的调用签名