Python 从列表生成嵌套字典

Python 从列表生成嵌套字典,python,python-3.x,dictionary,Python,Python 3.x,Dictionary,我想在python3中填充一个嵌套字典,但我不知道如何干净地完成这项工作。我希望有一个更新功能,其工作方式如下: #pseudo code for the update given One and Two: One = ('W/X/Y/Z.py', 1, 8) Two = ('A/B/C/D.py', 12, 42) #blank initialization Dict = dict() #structure gets created based on the path in Two def

我想在python3中填充一个嵌套字典,但我不知道如何干净地完成这项工作。我希望有一个更新功能,其工作方式如下:

#pseudo code for the update given One and Two:
One = ('W/X/Y/Z.py', 1, 8)
Two = ('A/B/C/D.py', 12, 42)

#blank initialization
Dict = dict()

#structure gets created based on the path in Two
def updateDict(One, Two):
    tuple = (1, 8, 12, 42)
    try:
        Dict["A"]["B"]["C"]["D.py"]['W/X/Y/Z.py'].append(tuple)
    except:
        Dict["A"]["B"]["C"]["D.py"]['W/X/Y/Z.py'] = [tuple]
#where:
#Dict["A"] is now a dict, 
#Dict["A"]["B"] is now a dict, 
#Dict["A"]["B"]["C"] is now a dict and 
#Dict["A"]["B"]["C"]["D.py"] is now a dict
#Dict["A"]["B"]["C"]["D.py"]["W/X/Y/Z.py"] is now a list of tuples with four values

因此Dict[“A”][“B”][“C”]将返回一个字典:

dict(
    "D.py": {
        "W/X/Y/Z.py" : [(1,8,12,42), (50,60,90,100)],
        "W/X/Y/NOTZ.py" : [(3,14,15,22)]
     },
    "NOTD.py": {
        "W/X/Y/Z.py" : [(14,62,13,56)]
    }
)

dict(
    "W/X/Y/Z.py" : [(1,8,12,42), (50,60,90,100)],
    "W/X/Y/NOTZ.py" : [(3,14,15,22)]
)
Dict[“A”][“B”][“C”][“D.py”]将返回一个字典:

dict(
    "D.py": {
        "W/X/Y/Z.py" : [(1,8,12,42), (50,60,90,100)],
        "W/X/Y/NOTZ.py" : [(3,14,15,22)]
     },
    "NOTD.py": {
        "W/X/Y/Z.py" : [(14,62,13,56)]
    }
)

dict(
    "W/X/Y/Z.py" : [(1,8,12,42), (50,60,90,100)],
    "W/X/Y/NOTZ.py" : [(3,14,15,22)]
)
Dict[“A”][“B”][“C”][“D.py”][“W/X/Y/Z.py”]将返回元组列表:

[(1,8,12,42), (50,60,90,100)]
所以所有的嵌套值都是字典,但所有的叶子都是元组列表

1和2中字符串中的路径在以文件名结尾之前可以是任意长度和值(因此可以得到W/X/Y/Z.py或W/X/AA.py或Q/R/S/T/U/V.py)


任何可能有助于这一点的软件包都将不胜感激。

很难理解您在做什么。但让我试着描述一下你需要做什么

Dict = {}
Dict.setdefault('A', {})
Dict['A'].setdefault('B', {})
Dict['A']['B'].setdefault('C', {})
Dict['A']['B']['C'].setdefault('D.py', {})
Dict['A']['B']['C']['D.py'].setdefault('W/X/Y/Z.py', set())
Dict['A']['B']['C']['D.py']['W/X/Y/Z.py'].add(???)
还有一点你需要知道,set不能添加列表。您只能添加一个数字或元组,这是不可变的。因此,最后一步您应该执行以下操作:

Dict['A']['B']['C']['D.py']['W/X/Y/Z.py'] = Dict['A']['B']['C']['D.py']['W/X/Y/Z.py'].union([1, 8, 12, 42]).union([50, 60, 90, 100])
# {1, 8, 12, 42, 50, 60, 90, 100}
# or
Dict['A']['B']['C']['D.py']['W/X/Y/Z.py'].add((1, 8, 12, 42))
Dict['A']['B']['C']['D.py']['W/X/Y/Z.py'].add((50, 60, 90, 100))
# {(1, 8, 12, 42), (50, 60, 90, 100)}

好的,我看到您已经编辑了最后一步。所以现在容易多了

Dict = {}
Dict.setdefault('A', {})
Dict['A'].setdefault('B', {})
Dict['A']['B'].setdefault('C', {})
Dict['A']['B']['C'].setdefault('D.py', {})
Dict['A']['B']['C']['D.py'].setdefault('W/X/Y/Z.py', [])
Dict['A']['B']['C']['D.py']['W/X/Y/Z.py'].append(tuple)

这里有一个版本的
updateDict()
可以满足您的需要(注意:Py3)。它使用一个指针
d
进入任意深度字典,然后将元组附加到该指针:

Dict = dict()

def updateDict(One, Two):
    k, *v1 = One
    path, *v2 = Two
    d = Dict
    for p in path.split('/'):
        d = d.setdefault(p, {})
    d.setdefault(k, []).append(tuple(v1+v2))

In []:
One = ('W/X/Y/Z.py', 1, 8)
Two = ('A/B/C/D.py', 12, 42)
updateDict(One, Two)
Dict

Out[]:
{'A': {'B': {'C': {'D.py': {'W/X/Y/Z.py': [(1, 8, 12, 42)]}}}}}

In []:
One = ('W/X/Y/Z.py', 50, 60)
Two = ('A/B/C/D.py', 90, 100)
updateDict(One, Two)
Dict

Out[]:
{'A': {'B': {'C': {'D.py': {'W/X/Y/Z.py': [(1, 8, 12, 42), (50, 60, 90, 100)]}}}}}

等等。

我不知道你在问什么。。。但是我猜你想要dict.setdefault,我想我的问题是如何根据列表输入生成这些任意深度的字典访问器。如果没有硬编码,我怎么能将[A,B,C,D]转换成Dict[A][B][C][D]。@MichaelHackman我想你需要
'A/B/C/D.py'。拆分('/')
,然后执行for循环或递归。
Dict = dict()

def updateDict(One, Two):
    k, *v1 = One
    path, *v2 = Two
    d = Dict
    for p in path.split('/'):
        d = d.setdefault(p, {})
    d.setdefault(k, []).append(tuple(v1+v2))

In []:
One = ('W/X/Y/Z.py', 1, 8)
Two = ('A/B/C/D.py', 12, 42)
updateDict(One, Two)
Dict

Out[]:
{'A': {'B': {'C': {'D.py': {'W/X/Y/Z.py': [(1, 8, 12, 42)]}}}}}

In []:
One = ('W/X/Y/Z.py', 50, 60)
Two = ('A/B/C/D.py', 90, 100)
updateDict(One, Two)
Dict

Out[]:
{'A': {'B': {'C': {'D.py': {'W/X/Y/Z.py': [(1, 8, 12, 42), (50, 60, 90, 100)]}}}}}