压平嵌套的Python字典,压缩键,并递归为带字典的子列表

2024-06-26 12:59:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我一直在使用imranflatten nested Python dictionaries, compressing keys的很好的答案,并试图想出一种方法来进一步扁平化可能在列表中的字典项的值
(当然,由于我的数据通常来自XML,所以这也可以是递归的……

from pprint import pprint
from collections import MutableMapping

def flatten(d, parent_key='', sep='_'):
    items = []
    for k, v in d.items():
        new_key = parent_key + sep + k if parent_key else k
        if isinstance(v, MutableMapping):
            items.extend(flatten(v, new_key, sep=sep).items())
        else:
            items.append((new_key, v))
    return dict(items)

给出这样一个dict d

^{pr2}$

这很有效:

pprint(flatten(d))

        {'a': 1,
         'b': 2,
         'c_sub-a': 'one',
         'c_sub-b': 'two',
         'c_sub-c': 'thre'}

但是,我想通过dict项的列表值进一步重复,并检查列表中的每个dict是否可以进一步扁平化。在

下面是一个使用c-list作为嵌套列表值的示例输入:

d = {"a": 1,
     "b": 2,
     "c-list": [
         {"id": 1, "nested": {"sub-a": "one", "sub-b": "two", "sub-c": "thre"} },
         {"id": 2, "nested": {"sub-a": "one", "sub-b": "two", "sub-c": "thre"} },
         {"id": 3, "nested": {"sub-a": "one", "sub-b": "two", "sub-c": "thre"} }]}

以下是我当前使用上述函数得到的结果:

pprint(flatten(d))

{'a': 1,
 'b': 2,
 'c-list': [{'id': 1, 'nested': {'sub-a': 'one', 'sub-b': 'two', 'sub-c': 'thre'}},
            {'id': 2, 'nested': {'sub-a': 'one', 'sub-b': 'two', 'sub-c': 'thre'}},
            {'id': 3, 'nested': {'sub-a': 'one', 'sub-b': 'two', 'sub-c': 'thre'}}]}

下面是我要查找的输出,保留了原始flatten()的所有功能:

{'a': 1,
 'b': 2,
 'c-list': [{'id': 1, 'nested_sub-a': 'one', 'nested_sub-b': 'two', 'nested_sub-c': 'thre'},
            {'id': 2, 'nested_sub-a': 'one', 'nested_sub-b': 'two', 'nested_sub-c': 'thre'},
            {'id': 3, 'nested_sub-a': 'one', 'nested_sub-b': 'two', 'nested_sub-c': 'thre'}]}

当dict包含列表时,我正在努力找出如何递归地将dict“重新组合”成这个。。。有什么建议吗。在


Tags: keyid列表newitemsonedictsep
2条回答

简单地,对列表中的每个字典进行展平,将它们收集到一个新列表中,并使用原始键将其附加到items

def flatten(d, parent_key='', sep='_'):
        items = []
        for k, v in d.items():
            new_key = parent_key + sep + k if parent_key else k
            if isinstance(v, MutableMapping):
                items.extend(flatten(v, new_key, sep=sep).items())
            elif type(v) == list:
                items.append((new_key, [flatten(i) for i in v]))
            else:
                items.append((new_key, v))
        return dict(items)

如果值是一个列表,那么只需要一行代码就可以得到flatten的递归版本:

items.append((new_key, map(flatten, v)))  # for python 2.x
# or
items.append((new_key, list(map(flatten, v))))  # for python 3.x

因此,您只需对每个元素递归调用函数。在

以下是flatten的外观:

^{pr2}$

此解决方案可以处理列表中任意深度的列表。在

相关问题 更多 >