迭代嵌套字典 returns 仅第一个元素
Iterating over nested dictionary returns only first element
我有这个嵌套字典(“字典的字典”)
source = {
"OuterVal0": {"InnerVal": [10, 21, 96],"InnerVal2": [100, 91, 71]},
"OuterVal1": {"InnerVal": [21, 19, 76],"InnerVal2": [1, 1, 1]},
"OuterVal2": {"InnerVal": [1, 1, 96],"InnerVal2": [10, 9, 7]},
"OuterVal3": {"InnerVal": [0, 2, 6],"InnerVal2": [1, 911, 718]},
"OuterVal4": {"InnerVal": [12, 13, 9],"InnerVal2": [1000, 910, 701]},
"OuterVal5": {"InnerVal": [110, 211, 961],"InnerVal2": [10, 911, 918]},
}
我想创建一个新的,它由与内部值相关联的外键组成(见下面的预期输出)
我使用这个递归函数:
def myPrint(d, key=""):
output = {}
for k, v in d.items():
i = 0
if isinstance(v, dict):
return myPrint(v, k)
else:
for value in d.values():
newkey = (f"{i}_{key}")
output[newkey] = value
i += 1
return output
但是当我尝试打印时:
print(myPrint(source))
我明白了(只处理了第一个字典:
# {'0_OuterVal0': [10, 21, 96], '1_OuterVal0': [100, 91, 71]}
但我想要这样的东西(处理所有词典)
"""
Expected output
{'0_OuterVal0': [10, 21, 96], '1_OuterVal0': [100, 91, 71]}
{'0_OuterVal1':[21, 19, 76], '1_OuterVal1': [1, 1, 1]}
.
.
.
{'0_OuterVal5': [110, 211, 961], '1_OuterVal5': [10, 911, 918]}
"""
我做错了什么?
非常感谢您的帮助。
使用调试器逐步执行代码会对您有所帮助:
当您调用 myPrint(source)
并进入 for 循环时,您确实递归地调用了您的函数,但您没有将第一个嵌套字典添加到输出中,而是使用了 return
关键字。所以用第一个键创建的字典被返回,这就是你的函数的结尾。
如果你的函数的目的是打印,并且你想保留你原来的代码结构,你可以使用这个:
def myPrint(d, key=""):
output = {}
lines = ""
for k, v in d.items():
i = 0
if isinstance(v, dict):
lines += str(myPrint(v, k)) + '\n'
else:
for value in d.values():
newkey = (f"{i}_{key}")
output[newkey] = value
i += 1
return output if lines == "" else lines
您想要的输出可以更简单地作为列表理解获得:
output = [{f'0_OuterVal{i}': v['InnerVal'], f'1_OuterVal{i}': v['InnerVal2']}
for i, (k, v) in enumerate(source.items())]
这将创建一个包含您指定的键和值的字典列表。
问题是,当您第一次调用 return myPrint(v, k)
时,您计算第一个字典的值然后 return 而不是继续 for 循环中的其他值。
将函数更改为:
def myPrint(d, key=""):
output = {}
for k, v in d.items():
i = 0
if isinstance(v, dict):
output.update(myPrint(v, k))
else:
for value in d.values():
newkey = (f"{i}_{key}")
output[newkey] = value
i += 1
return output
会return一本大字典,给你举个例子:
{'0_OuterVal0': [10, 21, 96], '1_OuterVal0': [100, 91, 71],
'0_OuterVal1': [21, 19, 76], '1_OuterVal1': [1, 1, 1],
'0_OuterVal2': [1, 1, 96], '1_OuterVal2': [10, 9, 7],
'0_OuterVal3': [0, 2, 6], '1_OuterVal3': [1, 911, 718],
'0_OuterVal4': [12, 13, 9], '1_OuterVal4': [1000, 910, 701],
'0_OuterVal5': [110, 211, 961], '1_OuterVal5': [10, 911, 918]}
但是,函数可以很好地打包成 non-recursive 方式,如下所示:
output = [{f'{ii}_{k}': vv for (k, v) in source.items() for ii, (kk, vv) in enumerate(v.items())}]
我有这个嵌套字典(“字典的字典”)
source = {
"OuterVal0": {"InnerVal": [10, 21, 96],"InnerVal2": [100, 91, 71]},
"OuterVal1": {"InnerVal": [21, 19, 76],"InnerVal2": [1, 1, 1]},
"OuterVal2": {"InnerVal": [1, 1, 96],"InnerVal2": [10, 9, 7]},
"OuterVal3": {"InnerVal": [0, 2, 6],"InnerVal2": [1, 911, 718]},
"OuterVal4": {"InnerVal": [12, 13, 9],"InnerVal2": [1000, 910, 701]},
"OuterVal5": {"InnerVal": [110, 211, 961],"InnerVal2": [10, 911, 918]},
}
我想创建一个新的,它由与内部值相关联的外键组成(见下面的预期输出) 我使用这个递归函数:
def myPrint(d, key=""):
output = {}
for k, v in d.items():
i = 0
if isinstance(v, dict):
return myPrint(v, k)
else:
for value in d.values():
newkey = (f"{i}_{key}")
output[newkey] = value
i += 1
return output
但是当我尝试打印时:
print(myPrint(source))
我明白了(只处理了第一个字典:
# {'0_OuterVal0': [10, 21, 96], '1_OuterVal0': [100, 91, 71]}
但我想要这样的东西(处理所有词典)
"""
Expected output
{'0_OuterVal0': [10, 21, 96], '1_OuterVal0': [100, 91, 71]}
{'0_OuterVal1':[21, 19, 76], '1_OuterVal1': [1, 1, 1]}
.
.
.
{'0_OuterVal5': [110, 211, 961], '1_OuterVal5': [10, 911, 918]}
"""
我做错了什么?
非常感谢您的帮助。
使用调试器逐步执行代码会对您有所帮助:
当您调用 myPrint(source)
并进入 for 循环时,您确实递归地调用了您的函数,但您没有将第一个嵌套字典添加到输出中,而是使用了 return
关键字。所以用第一个键创建的字典被返回,这就是你的函数的结尾。
如果你的函数的目的是打印,并且你想保留你原来的代码结构,你可以使用这个:
def myPrint(d, key=""):
output = {}
lines = ""
for k, v in d.items():
i = 0
if isinstance(v, dict):
lines += str(myPrint(v, k)) + '\n'
else:
for value in d.values():
newkey = (f"{i}_{key}")
output[newkey] = value
i += 1
return output if lines == "" else lines
您想要的输出可以更简单地作为列表理解获得:
output = [{f'0_OuterVal{i}': v['InnerVal'], f'1_OuterVal{i}': v['InnerVal2']}
for i, (k, v) in enumerate(source.items())]
这将创建一个包含您指定的键和值的字典列表。
问题是,当您第一次调用 return myPrint(v, k)
时,您计算第一个字典的值然后 return 而不是继续 for 循环中的其他值。
将函数更改为:
def myPrint(d, key=""):
output = {}
for k, v in d.items():
i = 0
if isinstance(v, dict):
output.update(myPrint(v, k))
else:
for value in d.values():
newkey = (f"{i}_{key}")
output[newkey] = value
i += 1
return output
会return一本大字典,给你举个例子:
{'0_OuterVal0': [10, 21, 96], '1_OuterVal0': [100, 91, 71],
'0_OuterVal1': [21, 19, 76], '1_OuterVal1': [1, 1, 1],
'0_OuterVal2': [1, 1, 96], '1_OuterVal2': [10, 9, 7],
'0_OuterVal3': [0, 2, 6], '1_OuterVal3': [1, 911, 718],
'0_OuterVal4': [12, 13, 9], '1_OuterVal4': [1000, 910, 701],
'0_OuterVal5': [110, 211, 961], '1_OuterVal5': [10, 911, 918]}
但是,函数可以很好地打包成 non-recursive 方式,如下所示:
output = [{f'{ii}_{k}': vv for (k, v) in source.items() for ii, (kk, vv) in enumerate(v.items())}]