Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 具有可变深度、列表和int类型的多级defaultdict_Python_Dictionary_Defaultdict - Fatal编程技术网

Python 具有可变深度、列表和int类型的多级defaultdict

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

我正在尝试创建一个具有可变深度、列表和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']['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-谢谢你的回复。我已经编辑了我的问题,以便恰当地提出我的问题。