[英]Flatten nested dictionaries with tuple keys
如何将这个问题推广到可能是元组的大小写键?
即使对于所有字符串键来说,这样做的好处是,如果将它们累积到一个元组中,则不需要临时分隔符(尽管JSON导出是另一回事):
一种方法是基于此答案 。 我尝试了2个版本:
def flatten_keys(d,handler,prefix=[]):
return {handler(prefix,k) if prefix else k : v
for kk, vv in d.items()
for k, v in flatten_keys(vv, handler, kk).items()
} if isinstance(d, dict) else { prefix : d }
元组处理程序在哪里:
def tuple_handler_1(prefix,k):
return tuple([prefix]+[k])
def tuple_handler_2(prefix,k):
return tuple(flatten_container((prefix,k)))
使用实用程序生成器:
def flatten_container(container):
for i in container:
if isinstance(i, (list,tuple)):
for j in flatten_container(i):
yield j
else:
yield i
考虑一下其中一个测试字典,但使用元组键('hgf',1)
:
data = {'abc':123, ('hgf',1):{'gh':432, 'yu':433}, 'gfd':902, 'xzxzxz':{"432":{'0b0b0b':231}, "43234":1321}}
两者均无法按预期工作:
flatten_keys(data,tuple_handler_1)
{'abc':123,((('hgf',1),'gh'):432,(('hgf',1),'yu'):433,'gfd':902,('xzxzxz', ('432','0b0b0b')):231,('xzxzxz','43234'):1321}
('xzxzxz', ('432', '0b0b0b'))
。 不展平
然后第二个展平输入元组键
flatten_keys(data,tuple_handler_2)
{'abc':123,('hgf',1,'gh'):432,('hgf',1,'yu'):433,'gfd':902,('xzxzxz','432', '0b0b0b'):231,('xzxzxz','43234'):1321}
扁平化方法是否有明显的修改,可以正确连接字符串和其他散列?
编辑
根据下面的评论,使用此方法处理键冲突是字符串键的基本情况,例如{'a_b':{'c':1}, 'a':{'b_c':2}}
。
因此,即使对于len
1个键路径,每个键路径也应该是一个元组,以避免键冲突,例如{((1,2),): 3, (1,2):4}}
。
假设您需要以下输入/输出
# input
{'abc': 123,
('hgf', 1): {'gh': 432, 'yu': 433},
'gfd': 902,
'xzxzxz': {'432': {'0b0b0b': 231}, '43234': 1321}}
# output
{('abc',): 123,
(('hgf', 1), 'gh'): 432,
(('hgf', 1), 'yu'): 433,
('gfd',): 902,
('xzxzxz', '432', '0b0b0b'): 231,
('xzxzxz', '43234'): 1321}
一种方法是对字典进行递归,直到找到非字典值,然后在递归期间将当前键作为元组传递。
def flatten_dict(deep_dict):
def do_flatten(deep_dict, current_key):
for key, value in deep_dict.items():
# the key will be a flattened tuple
# but the type of `key` is not touched
new_key = current_key + (key,)
# if we have a dict, we recurse
if isinstance(value, dict):
yield from do_flatten(value, new_key)
else:
yield (new_key, value)
return dict(do_flatten(deep_dict, ()))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.