我自己发布了一个解决方案,但我对它不满意,这太复杂了。
有时候,我们需要压扁一个dict,有时反过来,例如: 嵌套的dict看起来像这样:
{'a': 'A', 'b': {'c': 'BC', 'd': [4, 44, 444]}}
和一个扁平的词典:
{'a': 'A', 'b__c': 'BC', 'b__d': [4, 44, 444]}
我们可以看到,在这种情况下,我们使用双下划线来表示嵌套级别。
我写了两个函数来做这些,请检查我发布的答案,但我仍然更喜欢任何robost第三方库或任何其他想法来使这两个函数变为eaiser?
而且除了之外,我还想知道什么是压扁值的正确方法,哪种类型是一个填充dict对象的列表?让我们这样说吧,如果我们用dicts intead替换数字4,44,444那么应该是什么应该是扁平的dict。
答案 0 :(得分:0)
我写了两个函数来转换flatten和嵌套dict,但我更喜欢找一些robost lib来处理这些情况。
def flatten(nested_dict, result=None, prefix=''):
from collections import OrderedDict
if result is None:
result = dict()
for k, v in nested_dict.items():
new_k = '__'.join((prefix, k)) if prefix else k
if not (isinstance(v, dict) or isinstance(v, OrderedDict)):
result.update({new_k: v})
else:
flatten(v, result, new_k)
return result
def rebuild(flatten_dict, result=None):
from collections import defaultdict
import json
def tree():
return defaultdict(tree)
def rec(keys_iter, value):
_r = tree()
try:
_k = next(keys_iter)
_r[_k] = rec(keys_iter, value)
return _r
except StopIteration:
return value
if result is None:
result = dict()
for k, v in flatten_dict.items():
keys_nested_iter = iter(k.split('__'))
cur_level_dict = result
while True:
try:
k = next(keys_nested_iter)
if k in cur_level_dict:
cur_level_dict = cur_level_dict[k]
else:
cur_level_dict[k] = json.loads(json.dumps(rec(keys_nested_iter, v)))
except StopIteration:
break
return result
if __name__ == "__main__":
my_dict = {'a': 'A',
'b':
{
'd': [4, 44, 444],
'c': 'BC'
}
}
my_flatten_dict = flatten(my_dict)
assert my_flatten_dict == {'a': 'A', 'b__c': 'BC', 'b__d': [4, 44, 444]}
my_nested_dict = rebuild(my_flatten_dict)
assert my_nested_dict == {'a': 'A', 'b': {'c': 'BC', 'd': [4, 44, 444]}}
答案 1 :(得分:0)
虽然不是你应该做的事情,但你可以使用json.dumps
将其更改为字符串并使用re.sub
来执行操作< / p>
import json, re
d = {'a': 'A', 'b': {'c': 'BC', 'd': [4, 44, 444]}}
def flatten(to_flat):
return json.loads(re.sub('\}+','}',re.sub('":? *\{"', '__', json.dumps(d))))
print(flatten(d))
# prints {'a': 'A', 'b__c': 'BC', 'd': [4, 44, 444]}
但rebuilt
函数存在问题,您如何知道近距离大括号的位置?你不能。但如果它总是位于最后,你可以这样做:
def rebuilt(to_rebuilt):
to_rebuilt = re.sub('__', '": {"', json.dumps(to_rebuilt))
return re.sub('\}','}'*to_rebuilt.count("{"),to_rebuilt)
print(rebuilt(flatten(d)))
# prints {'a': 'A', 'b': {'c': 'BC', 'd': [4, 44, 444]}}