【发布时间】:2021-10-26 22:14:43
【问题描述】:
我在 Python 的深度嵌套字典中有一些来自远程服务器的数据。由于数据收集过程(我无法控制),这个字典的几个级别被包装在一个不必要的字典中,带有一个名为"__collections__" 的单个键。例如,字典是这样的
{"data_level_1":
{"__collections__":
{"data_level_2": ...}
}
}
当我真正想要的是
{"data_level_1":
{"data_level_2": ...}
}
我需要一种递归迭代嵌套字典的方法,以将那些包装的字典“移动”一级,同时摆脱 "__collections__" 包装字典。这是我的尝试:
import collections.abc
def remove_repeat_named_level(dictionary, key):
q = list(dictionary.items())
for v, d in q:
if isinstance(d, MutableMapping):
for nv, nd in d.items():
if isinstance(nd, MutableMapping):
if v==key:
nd = remove_repeat_named_level(nd, key)
q.append((nv, nd))
if (v, d) in q: q.remove((v, d))
elif nv==key:
nd = remove_repeat_named_level(nd, key)
q.append((v, nd))
if (v, d) in q: q.remove((v, d))
elif v==key:
q.append((nv, nd))
if (v, d) in q: q.remove((v, d))
return dict(q)
其中dictionary 是嵌套字典,key 是我要删除的包装字典中单个键的名称(在本例中为collections)。
这在一些简单的测试用例上效果很好,例如:
test_key = "A"
test_dict = {"A":
{"B":
{"A":
{"i":
{"A":
{"One":
{"A":
{"alpha": "a",
"beta": "b"
}
},
"Two": 2
}
},
"ii": 2
}
}
}
}
remove_repeat_named_level(test_dict, test_key)
返回预期结果:
{'B': {'i': {'One': {'alpha': 'a', 'beta': 'b'}, 'Two': 2}, 'ii': 2}
但是,当我通过函数传递带有数据的嵌套字典时,递归似乎在某个级别停止:
字典:
test_d2 = {"__collections__":
{"tasks":
{"task1":
{"__collections__":
{"subjects":
{"subject1":
{"date": 1,
"time": 1,
"__collections__":
{"surveys":
{"survey1":
{"survey_data":
{"Q1": {"Response": 1},
"Q2": {"Response": 2}
}
},
"__collections__": {}
}
}
}
}
}
}
}
}
}
预期:
{"tasks":
{"task1":
{"subjects":
{"subject1":
{"date": 1,
"time": 1,
{"surveys":
{"survey1":
{"survey_data":
{"Q1": {"Response": 1},
"Q2": {"Response": 2}
}
}
}
}
}
}
}
}
}
结果:
{"tasks":
{"task1":
{"subjects":
{"subject1":
{"date": 1,
"time": 1,
"__collections__":
{"surveys":
{"survey1":
{"survey_data":
{"Q1": {"Response": 1},
"Q2": {"Response": 2}
}
},
"__collections__": {}
}
}
}
}
}
}
}
为了弄清楚这一点,我已经绞尽脑汁好几个小时了。为什么递归会在某个点停止?有没有我没有考虑到的情况?
【问题讨论】:
-
您最后的预期结果不是有效的 python 字典。你不能在没有密钥的情况下在字典中只拥有一个赤裸裸的
{"surveys":。
标签: python dictionary recursion nested