假设你有一本这样的字典:

{'a': 1,
 'c': {'a': 2,
       'b': {'x': 5,
             'y' : 10}},
 'd': [1, 2, 3]}

你会如何把它平摊成这样:

{'a': 1,
 'c_a': 2,
 'c_b_x': 5,
 'c_b_y': 10,
 'd': [1, 2, 3]}

当前回答

你可以使用递归来平展你的字典。

import collections


def flatten(
    nested_dict,
    seperator='.',
    name=None,
):
    flatten_dict = {}

    if not nested_dict:
        return flatten_dict

    if isinstance(
        nested_dict,
        collections.abc.MutableMapping,
    ):
        for key, value in nested_dict.items():
            if name is not None:
                flatten_dict.update(
                    flatten(
                        nested_dict=value,
                        seperator=seperator,
                        name=f'{name}{seperator}{key}',
                    ),
                )
            else:
                flatten_dict.update(
                    flatten(
                        nested_dict=value,
                        seperator=seperator,
                        name=key,
                    ),
                )
    else:
        flatten_dict[name] = nested_dict

    return flatten_dict


if __name__ == '__main__':
    nested_dict = {
        1: 'a',
        2: {
            3: 'c',
            4: {
                5: 'e',
            },
            6: [1, 2, 3, 4, 5, ],
        },
    }

    print(
        flatten(
            nested_dict=nested_dict,
        ),
    )

输出:

{
   "1":"a",
   "2.3":"c",
   "2.4.5":"e",
   "2.6":[1, 2, 3, 4, 5]
}

其他回答

或者如果你已经在使用pandas,你可以像这样使用json_normalize():

import pandas as pd

d = {'a': 1,
     'c': {'a': 2, 'b': {'x': 5, 'y' : 10}},
     'd': [1, 2, 3]}

df = pd.json_normalize(d, sep='_')

print(df.to_dict(orient='records')[0])

输出:

{'a': 1, 'c_a': 2, 'c_b_x': 5, 'c_b_y': 10, 'd': [1, 2, 3]}

这是一种“功能性的”、“单行程序”实现。它是递归的,基于条件表达式和字典理解。

def flatten_dict(dd, separator='_', prefix=''):
    return { prefix + separator + k if prefix else k : v
             for kk, vv in dd.items()
             for k, v in flatten_dict(vv, separator, kk).items()
             } if isinstance(dd, dict) else { prefix : dd }

测试:

In [2]: flatten_dict({'abc':123, 'hgf':{'gh':432, 'yu':433}, 'gfd':902, 'xzxzxz':{"432":{'0b0b0b':231}, "43234":1321}}, '.')
Out[2]: 
{'abc': 123,
 'gfd': 902,
 'hgf.gh': 432,
 'hgf.yu': 433,
 'xzxzxz.432.0b0b0b': 231,
 'xzxzxz.43234': 1321}

使用生成器的Python 3.3解决方案:

def flattenit(pyobj, keystring=''):
   if type(pyobj) is dict:
     if (type(pyobj) is dict):
         keystring = keystring + "_" if keystring else keystring
         for k in pyobj:
             yield from flattenit(pyobj[k], keystring + k)
     elif (type(pyobj) is list):
         for lelm in pyobj:
             yield from flatten(lelm, keystring)
   else:
      yield keystring, pyobj

my_obj = {'a': 1, 'c': {'a': 2, 'b': {'x': 5, 'y': 10}}, 'd': [1, 2, 3]}

#your flattened dictionary object
flattened={k:v for k,v in flattenit(my_obj)}
print(flattened)

# result: {'c_b_y': 10, 'd': [1, 2, 3], 'c_a': 2, 'a': 1, 'c_b_x': 5}
def flatten(dictionary, prefix = '', separator = '_'):
    out_dict = {}
    if type(dictionary) != dict:
        out_dict[prefix] = dictionary
        return out_dict
    elif dictionary is None:
        return None
    for k in dictionary.keys():
        if prefix:
            prefix_n = prefix + f'{separator}{k}'
        else:
            prefix_n = k
        out_dict.update(flatten_new(dictionary[k], prefix_n))
    return out_dict

输出:

{'a': 1, 'c_a': 2, 'c_b_x': 5, 'c_b_y': 10, 'd': [1, 2, 3]}

代码:

test = {'a': 1, 'c': {'a': 2, 'b': {'x': 5, 'y' : 10}}, 'd': [1, 2, 3]}

def parse_dict(init, lkey=''):
    ret = {}
    for rkey,val in init.items():
        key = lkey+rkey
        if isinstance(val, dict):
            ret.update(parse_dict(val, key+'_'))
        else:
            ret[key] = val
    return ret

print(parse_dict(test,''))

结果:

$ python test.py
{'a': 1, 'c_a': 2, 'c_b_x': 5, 'd': [1, 2, 3], 'c_b_y': 10}

我使用python3.2,更新为您的python版本。