扁平化深度不明的字典列表中的字典列表(可怕的JSON结构)

6 投票
1 回答
5282 浏览
提问于 2025-04-17 08:13

我正在处理一个JSON结构,输出的格式像这样:

[{u'item': u'something',
  u'data': {
            u'other': u'',
            u'else':
               [
                  {
                    u'more': u'even more',
                    u'argh':
                         {
                            ...etc..etc

你可以看到,这些是嵌套的字典和列表。 关于如何递归地将这些结构扁平化的讨论很多,但我还没有找到一个可以处理字典列表的方案,而这些字典列表可能又包含字典的列表、列表的列表、字典的字典等等,深度也是未知的!在某些情况下,深度可能会达到100层左右。 到目前为止,我尝试了这个方法,但效果不太好(使用的是python 2.7.2):

def flatten(structure):
    out = []
    for item in structure:
        if isinstance(item, (list, tuple)):
            out.extend(flatten(item))
        if isinstance(item, (dict)):
            for dictkey in item.keys():
                out.extend(flatten(item[dictkey]))
        else:
            out.append(item)
    return out

有什么想法吗?

更新 这个方法基本上是可行的:

def flatten(l):
    out = []
    if isinstance(l, (list, tuple)):
        for item in l:
            out.extend(flatten(item))
    elif isinstance(l, (dict)):
        for dictkey in l.keys():
            out.extend(flatten(l[dictkey]))
    elif isinstance(l, (str, int, unicode)):
        out.append(l)
    return out

1 个回答

11

因为你的数据层级是任意的,所以使用递归来把它变成一维的会更简单。这个函数会创建一个扁平化的字典,字典的每个键都是到达每个数据项的路径,这样可以避免重复的键。

你可以稍后用 for key in sorted(dic_.keys()) 来获取里面的内容,例如。

我没有测试这个,因为你没有提供一个“有效”的数据片段。

def flatten(structure, key="", path="", flattened=None):
    if flattened is None:
        flattened = {}
    if type(structure) not in(dict, list):
        flattened[((path + "_") if path else "") + key] = structure
    elif isinstance(structure, list):
        for i, item in enumerate(structure):
            flatten(item, "%d" % i, path + "_" + key, flattened)
    else:
        for new_key, value in structure.items():
            flatten(value, new_key, path + "_" + key, flattened)
    return flattened

撰写回答