假设我有一个嵌套的dict
,我想把它展平。dict
只有一层深,嵌套元素是dict
或str
。下面给出了示例数据:
data = {
'foo': 'bar',
'sample': {
'a': 213,
'b': 634298,
'c': 1},
'doo': 'val',
'spaz': {
'x': 4,
'y': 32,
'z': 18}}
期望的输出是平坦的dict
,如下所示:
{'foo': 'bar',
'sample_a': 213,
'sample_b': 634298,
'sample_c': 1,
'doo': 'val',
'spaz_x': 4,
'spaz_y': 32,
'spaz_z': 18}
传统的方法是这样循环:
data_out = {}
for k, v in data.items():
if isinstance(v, dict):
for ik, iv in v.items():
data_out[f'{k}_{ik}'] = iv
else:
data_out[k] = v
虽然我想看看我如何才能做到这一点干净的理解。我的尝试使用了条件嵌套循环和itertools.chain.from_iterable
data_out = dict(chain.from_iterable(((f'{k}_{ik}', iv) for ik, iv in v.items()) if isinstance(v, dict) else ((k, v),) for k, v in data.items()))
以下内容与上述内容相同,只是为了便于阅读而按行细分:
data_out = dict(chain.from_iterable(
((f'{k}_{ik}', iv) for ik, iv in v.items())
if isinstance(v, dict)
else ((k, v),)
for k, v in data.items()))
虽然这是有效的,但我确信这是不必要的,我只是想不出更好的方法,最好是传统的dict
理解,而不是在生成器理解上使用dict
。我能想到的唯一缩短代码的方法是删除.from_iterable
,然后开始解包生成器,尽管我不认为这对这种方法更合适。你知道吗
实际上,我找到了一种方法,可以使用
getattr
作为检查其是否为dict
的快捷方式。对我来说,这比我见过的其他方法更有效:图例:
如果你的钥匙里有
0
,我刚才用了一个“trasher”对象:您可以在dict理解中反转循环的顺序,从而直接创建“扁平”字典,而无需
chain.from_iterable
,但这并不能真正使它更清晰。你知道吗另一种方法可能是创建两个dict,然后
**
-将它们组合成最终dict:但是,IMHO您的“传统”嵌套循环比这三个版本都要干净得多。或者,只需使用此处的任何其他递归“具有任意深度的展平字典”函数。你知道吗
相关问题 更多 >
编程相关推荐