Python 具有可变深度、列表和int类型的多级defaultdict
我正在尝试创建一个具有可变深度、列表和int类型的多级dict 数据结构如下所示Python 具有可变深度、列表和int类型的多级defaultdict,python,dictionary,defaultdict,Python,Dictionary,Defaultdict,我正在尝试创建一个具有可变深度、列表和int类型的多级dict 数据结构如下所示 A --B1 -----C1=1 -----C2=[1] --B2=[3] D --E ----F ------G=4 在上述数据结构的情况下,最后一个值可以是int或list 如果上面的数据结构只有int,那么我可以使用下面的代码轻松实现: from collections import defaultdict f = lambda: defaultdict(f) d = f() d['A']['B1']['C
A
--B1
-----C1=1
-----C2=[1]
--B2=[3]
D
--E
----F
------G=4
在上述数据结构的情况下,最后一个值可以是int
或list
如果上面的数据结构只有int,那么我可以使用下面的代码轻松实现:
from collections import defaultdict
f = lambda: defaultdict(f)
d = f()
d['A']['B1']['C1'] = 1
但由于最后一个值同时具有列表和int,这对我来说有点问题
现在我们可以使用两种方法在列表中插入数据
d['A']['B1']['C2']= [1]
d['A']['B1']['C2'].append([2])
但是,当我只使用append方法时,它会导致错误
错误是:
AttributeError: 'collections.defaultdict' object has no attribute 'append'
因此,有没有办法只使用append方法来创建列表?没有办法使用当前基于
defaultdict的结构来创建d['a']['B1']['C2']。如果'C2'
键不存在,则append(1)
可以正常工作,因为数据结构不能告诉未知键应该对应于一个列表,而不是另一个字典层。它不知道您将对它返回的值调用什么方法,因此它不知道它不应该返回字典(就像它第一次查找'a'
和'B'
时所做的那样)
对于裸整数来说,这不是问题,因为对于裸整数来说,直接分配给一个新键(所有早期级别都是字典)。在赋值时,数据结构不会创建值,而您会创建值,因此您可以使用所需的任何类型
现在,如果您的键在某种程度上是与众不同的,那么给定一个像'C2'
这样的键,您就可以确定它应该对应于一个列表,您可能有机会。您可以编写自己的dict
子类,定义一个\uuuuu missing\uuuu
方法,以自己的特殊方式处理尚未存在的密钥的查找:
def Tree(dict):
def __missing__(self, key):
if key_corresponds_to_list(key): # magic from somewhere
result = self[key] = []
else:
result = self[key] = Tree()
return result
# you might also want a custom __repr__
下面是一个使用magic key函数运行的示例,该函数使任意偶数长度的键默认为列表,而奇数长度的键默认为dict:
> def key_corresponds_to_list(key):
return len(key) % 2 == 0
> t = Tree()
> t["A"]["B"]["C2"].append(1) # the default value for C2 is a list because it's even length
> t
{'A': {'B': {'C2': [1]}}}
> t["A"]["B"]["C10"]["D"] = 2 # C10's another layer of dict, since it's length is odd
> t
{'A': {'B': {'C10': {'D': 2}, 'C2': [1]}}} # it didn't matter what length D was though
你可能不想用全局函数来控制这个类,我只是举个例子。如果您使用这种方法,我建议将逻辑直接放入\uuuuu missing\uuuuu
方法中(或者可能将函数作为参数传递,如defaultdict
对其工厂函数所做的那样)。类型是如何确定的?在列表中执行d['a']['B1']['C2']=[1]
有什么问题,我们通常使用append函数在列表中插入任何数据。当我使用d['A']['B1']['C2'].append([1])
时,它会导致错误。没错,因为您将默认值定义为一个defaultdict
,它没有append
方法<代码>d['A']['B1']['C2']=[1]
是追加之前应该做的事情。就像你所做的那样,d['A']['B1']['C1']=1
@AshwiniChaudhary-谢谢你的回复。我已经编辑了我的问题,以便恰当地提出我的问题。