给定列表,如何生成嵌套字典



给定下面的列表,使用Python 3如何生成一个嵌套字典,其中list[0]具有list[1:]作为嵌套子列表。

list = [
["Layer 1.A", "Layer 1.B"],
["layer 2.A", "Layer 2.B"],
["Layer 3"],
["Layer 4"]

]

我已经尝试了很多东西,但没有一个给我正确的输出。我已经尝试了以下方法:

  1. 尝试使用python的product(生成所有排列,但没有给出正确的输出。它看起来像:
[
["Layer 1.A", "Layer 2.A", "Layer 3", "Layer 4"],
["Layer 1.A", "Layer 2.B", "Layer 3", "Layer 4"],
["Layer 1.B", "Layer 2.A", "Layer 3", "Layer 4"],
["Layer 1.B", "Layer 2.B", "Layer 3", "Layer 4"]
]
  1. 尝试使用嵌套for循环创建一个嵌套字典(不知道如何添加到字典)
  2. 尝试使用递归(尝试通过每个字符串的每个元素迭代dict(zip(keys, dictionary) for keys in product(*dictionary2)), dict或zip)
  3. 尝试使用lambda函数

期望输出:请注意只有第一层变化,而内部是相同的。

[
{"Layer 1.A":
{
"Layer 2.A": 
{
"Layer 3" : "Layer 4"
},
"Layer 2.B":
{
"Layer 3" : "Layer 4"
}
}
},
{"Layer 1.B":
{
"Layer 2.A": 
{
"Layer 3" : "Layer 4"
},
"Layer 2.B":
{
"Layer 3" : "Layer 4"
}
}
}
]

您生成了所有的排列。现在根据这些排列创建您的嵌套字典。为此,我们可以定义一个函数,该函数将接受原始字典、键列表以及要在该嵌套键处设置的值。如果键不存在,则创建它并将其值设置为新字典

def nested_set(obj, keys, value):
for key in keys[:-1]:
try:
# Drill down until the penultimate key
obj = obj[key]
except KeyError:
obj[key] = {}
obj = obj[key]
# Set value of last key
obj[keys[-1]] = value

例如,在空的my_dict = dict()上执行nested_set(my_dict, ['a', 'b', 'c'], 'd')会得到如下结果:

{'a': {'b': {'c': 'd'}}}

知道了这些,你可以像这样使用你的排列列表:

perms = [
["Layer 1.A", "Layer 2.A", "Layer 3", "Layer 4"],
["Layer 1.A", "Layer 2.B", "Layer 3", "Layer 4"],
["Layer 1.B", "Layer 2.A", "Layer 3", "Layer 4"],
["Layer 1.B", "Layer 2.B", "Layer 3", "Layer 4"]
]
my_dict = dict()
for p in perms:
nested_set(my_dict, p[:-1], p[-1])

几乎你想要的结果:

{
'Layer 1.A': {
'Layer 2.A': {
'Layer 3': 'Layer 4'
},
'Layer 2.B': {
'Layer 3': 'Layer 4'
}
},
'Layer 1.B': {
'Layer 2.A': {
'Layer 3': 'Layer 4'
},
'Layer 2.B': {
'Layer 3': 'Layer 4'
}
}
}

将其转换为所需列表很容易:

result = [{k: v} for k, v in my_dict.items()]

给了:

[
{
'Layer 1.A': {
'Layer 2.A': {
'Layer 3': 'Layer 4'
},
'Layer 2.B': {
'Layer 3': 'Layer 4'
}
}
},
{
'Layer 1.B': {
'Layer 2.A': {
'Layer 3': 'Layer 4'
},
'Layer 2.B': {
'Layer 3': 'Layer 4'
}
}
}
]

这感觉像是一个递归解决方案的自然问题。

def Cartesian(theList):
if len(theList) == 2:
result = [ [x,y] for x in theList[0] for y in theList[1] ]
return result 
else:
result = [[x,y] for x in theList[0] for y in Cartesian(theList[1:])]
return result 

这个实现将返回一个包含您正在寻找的嵌套结构的列表。我真的不太了解如何将结果格式化为JSON。

最新更新