我有两个要比较的文件,并插入缺少key_value的第二个文件或使用新值更新现有密钥。 对我来说问题是第一个文件有点分隔键:
{"a.b.c":0}
第二个文件如下:
{"a":{"b":{"c":0}}}
答案 0 :(得分:0)
我最近不得不处理类似的事情。这就是我想出的:
def to_flat_dict(d, delim='.'):
"""TLDR;
While there are entries in the dictionary that have a dict as a value:
pop them at the outer level and create a delimitted path as a key, eg:
{'a': {'b': {'c': 0}}} -> {'a.b': {'c': 0}}
# by same process
{'a.b': {'c': 0}} -> {'a.b.c': 0}
"""
flat = dict(d) # work on a copy
incomplete = list(flat)
while(incomplete):
k = incomplete.pop()
if isinstance(flat[k], dict):
val = flat.pop(k)
for subk, subv in val.items():
new_key = delim.join((k, subk))
flat[new_key] = subv
incomplete.append(new_key)
return flat
def to_nested_dict(d, delim='.'):
"""TLDR;
flat: {"a.b.c":0}
# pop 'a.b.c' and value 0 and break key into parts
parts: ['a','b','c']:
# process 'a'
flat <- {'a':dict()}
# process 'b'
flat <- {'a': {'b': dict()}}
# process 'c' @ tmp[parts[-1]] = val
flat <- {'a': {'b': {'c': 0}}}
"""
flat = dict(d) # work on a copy
keys = list(d) # we copy the keys since we are modifying the dict in place
for key in keys:
# Basic idea: for all keys that contain the delim
if delim in key:
val = flat.pop(key)
# get the parts (a.b.c -> [a, b, c])
parts = key.split(delim)
# we start with the outer dict, but as we process parts of the key
level = flat # we assign level to the newly created deeper dicts
for part in parts[:-1]:
if part not in level: # if the part isn't a key at this depth
level[part] = dict() # create a new dict to fill
level = level[part] # and work on the next deeper level
level[parts[-1]] = val # when we get to the "leaf" set it as val
return flat
您可以致电:
获取所需的嵌套字典to_nested_dict({'a.b.c':0})
您可以使用 to_flat_dict :
将其反转to_flat_dict(to_nested_dict({'a.b.c':0})) # back to {'a.b.c':0}
您的里程可能会有所不同!
答案 1 :(得分:0)
我编写的代码对我有用,但我讨厌它,尤其是ff_function。 我认为应该使用递归函数来完成 - 不知道如何:(
>>> def ff(k, d, i, v):
... if i == len(k)-1:
... last_value = v
... else:
... last_value = {}
... if i == 0:
... d[k[0]] = last_value
... elif i == 1:
... d[k[0]][k[1]] = last_value
... elif i == 2:
... d[k[0]][k[1]][k[2]] = last_value
... elif i == 3:
... d[k[0]][k[1]][k[2]][k[3]] = last_value
... elif i == 4:
... d[k[0]][k[1]][k[2]][k[3]][k[4]] = last_value
... elif i == 5:
... d[k[0]][k[1]][k[2]][k[3]][k[4]][k[5]] = last_value
... return d
...
>>>
>>>
>>> def f(k, v):
... td = {}
... keys = k.split('.')
... for i in range(len(keys)):
... td = ff(keys, td, i, v)
... return td
...
>>>
>>> f('a.b.c.d', ['some', 'values', 'here'])
{'a': {'b': {'c': {'d': ['some', 'values', 'here']}}}}
>>> f('a', 0)
{'a': 0}