我有一个文件:
Key1:
Key2:
Key3:
Key4: Value4
我正在逐行阅读文件:
with open(configuration_file) as config_file:
nested_dict = {}
for line in config_file:
dict_reader(line)
每行都要通过此功能dict_reader
我想将每行添加到N嵌套字典中。
def dict_reader(line):
if ": " in line and not ": &" in line and not ": *" in line:
# create key-value pair, add it to the last empty dictionary in nested_dict
if ":" in line and not ": " in line:
if nested_dict:
key2 = str(line.split(':')[0].strip())
d = {key2: {}}
for k, v in nested_dict.items():
if isinstance(v, dict):
v.update(d)
break
print(nested_dict)
else:
key1 = str(line.split(':')[0])
nested_dict[key1] = {}
第一次运行后,将返回:{'Key1': {}}
,这就是我所追求的
第二次运行后,返回:{'Key1': {'Key2': {}}}
也是我所追求的
但是在第三次及其后的运行之后,它返回:{'Key1': {'Key2': {}, 'Key3': {}}}
。它没有将{'Key3': {}}
作为'Key2'
的值,而是将其作为该字典中的另一个元素返回。对于'Key4'
,例如
{'Key1': {'Key2': {}, 'Key3': {}, 'Key4': {}}}
每行之后,应该只有一个空字典:
{'Key1': {}}
{'Key1': {'Key2': {}}}
{'Key1': {'Key2': {'Key3': {}}}}
{'Key1': {'Key2': {'Key3': {'Key4': {}}}}}
etc.
对于每个循环,我想搜索N个嵌套字典,找到一个空字典的第一个匹配项(只有一个),然后将空字典更新为我刚刚从文件中读取的行。
任何帮助将不胜感激!
答案 0 :(得分:1)
问题出在for循环中。
在循环的第三遍调用v.update(d)
时
d = {'Key3': {}}
v = {'Key2': {}}
请记住k, v
,您正在遍历nested_dict
项的{'Key1': {'Key2': {}}}
项。
v.update(d)
更改为v = {'Key2': {}, 'Key3': {}}
。
为什么?根据方法文档字符串,D.update(E)
根据输入有一些不同的行为。在这种情况下:
“如果E存在并且具有.keys()方法,则执行:
for k in E: D[k] = E[k]
”。
因此,在这种情况下,它仅将'Key3': {}
对添加到v
,其中v
实际上只是引用了nested_dict
中持有的值(该值只有一个键值对)。
如果我正确理解,在您的示例中,您正在编写一个打算复制load
库中的yaml
函数的函数。
我假定将其写为 point ,因为您不想使用该库-为了他人的利益,可以按以下步骤进行操作:
import yaml
data = """
Key1:
Key2:
Key3:
Key4: Value4
"""
parsed = yaml.load(data)
# parsed = {'Key1': {'Key2': {'Key3': {'Key4': 'Value4'}}}}
由于您不想这样做,因此您需要仔细阅读字典,直到达到最深的层次为止,而不是for k, v in nested_dict.items()
。问题是,您事先不知道将要达到多少个级别。我建议您可以定义如下函数:
def get_deepest_level(d):
if not isinstance(d, dict):
return d # if the value isn't a dict, just return it
# otherwise continue:
for k, v in d.items():
if v:
return get_deepest_level(v) # recursion!
else:
return v
这将继续在嵌套级别中下拉,直到遇到不是字典或空字典的值-这些值中的任何一个都将在顶层返回。如果您致电
deepest_level = get_deepest_level(nested_dict)
deepest_level.update(d)
这将更新它可能找到的最深入嵌套的字典(请记住,其中的项目之间总是存在循环,这些项目将始终落入您的第一个键值对中……但这仍然是您正在做的事情)