📜  Python|将嵌套字典转换为扁平字典

📅  最后修改于: 2022-05-13 01:55:05.153000             🧑  作者: Mango

Python|将嵌套字典转换为扁平字典

给定一个嵌套字典,任务是将此字典转换为一个扁平字典,其中键由“_”分隔,以防嵌套键被启动。

下面给出了解决上述任务的一些方法。

方法#1:使用朴素的方法

Python3
# Python code to demonstrate
# conversion of nested dictionary
# into flattened dictionary
 
# code to convert ini_dict to flattened dictionary
# default separator '_'
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 }
         
# initialising_dictionary
ini_dict = {'geeks': {'Geeks': {'for': 7}},
            'for': {'geeks': {'Geeks': 3}},
            'Geeks': {'for': {'for': 1, 'geeks': 4}}}
 
# printing initial dictionary
print ("initial_dictionary", str(ini_dict))
 
 
# printing final dictionary
print ("final_dictionary", str(flatten_dict(ini_dict)))


Python3
# Python code to demonstrate
# conversion of nested dictionary
# into flattened dictionary
 
from collections import MutableMapping
 
# code to convert ini_dict to flattened dictionary
# default separator '_'
def convert_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(convert_flatten(v, new_key, sep = sep).items())
        else:
            items.append((new_key, v))
    return dict(items)
         
# initialising_dictionary
ini_dict = {'geeks': {'Geeks': {'for': 7}},
            'for': {'geeks': {'Geeks': 3}},
            'Geeks': {'for': {'for': 1, 'geeks': 4}}}
 
# printing initial dictionary
print ("initial_dictionary", str(ini_dict))
 
 
# printing final dictionary
print ("final_dictionary", str(convert_flatten(ini_dict)))


Python3
# Python code to demonstrate
# conversion of nested dictionary
# into flattened dictionary
 
my_map = {"a" : 1,
        "b" : {
            "c": 2,
            "d": 3,
            "e": {
                "f":4,
                6:"a",
                5:{"g" : 6},
                "l":[1,"two"]
            }
        }}
 
# Expected Output
# {'a': 1, 'b_c': 2, 'b_d': 3, 'b_e_f': 4, 'b_e_6': 'a', 'b_e_5_g': 6, 'b_e_l': [1, 'two']}
 
 
ini_dict = {'geeks': {'Geeks': {'for': 7}},
            'for': {'geeks': {'Geeks': 3}},
            'Geeks': {'for': {'for': 1, 'geeks': 4}}}
 
# Expected Output
# {‘Geeks_for_geeks’: 4, ‘for_geeks_Geeks’: 3, ‘Geeks_for_for’: 1, ‘geeks_Geeks_for’: 7}
 
def flatten_dict(pyobj, keystring=''):
    if type(pyobj) == dict:
        keystring = keystring + '_' if keystring else keystring
        for k in pyobj:
            yield from flatten_dict(pyobj[k], keystring + str(k))
    else:
        yield keystring, pyobj
 
print("Input : %s\nOutput : %s\n\n" %
     (my_map, { k:v for k,v in flatten_dict(my_map) }))
 
print("Input : %s\nOutput : %s\n\n" %
     (ini_dict, { k:v for k,v in flatten_dict(ini_dict) }))


输出:
initial_dictionary {'geeks': {'Geeks': {'for': 7}}, 'Geeks': {'for': {'geeks': 4, 'for': 1}}, 'for': {'极客':{'极客':3}}}
final_dictionary {'Geeks_for_for':1,'geeks_Geeks_for':7,'for_geeks_Geeks':3,'Geeks_for_geeks':4}

方法 #2:使用mutuableMapping

Python3

# Python code to demonstrate
# conversion of nested dictionary
# into flattened dictionary
 
from collections import MutableMapping
 
# code to convert ini_dict to flattened dictionary
# default separator '_'
def convert_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(convert_flatten(v, new_key, sep = sep).items())
        else:
            items.append((new_key, v))
    return dict(items)
         
# initialising_dictionary
ini_dict = {'geeks': {'Geeks': {'for': 7}},
            'for': {'geeks': {'Geeks': 3}},
            'Geeks': {'for': {'for': 1, 'geeks': 4}}}
 
# printing initial dictionary
print ("initial_dictionary", str(ini_dict))
 
 
# printing final dictionary
print ("final_dictionary", str(convert_flatten(ini_dict)))
输出:
initial_dictionary {'Geeks': {'for': {'for': 1, 'geeks': 4}}, 'for': {'geeks': {'Geeks': 3}}, 'geeks': {'极客': {'for': 7}}}
final_dictionary {'Geeks_for_geeks':4,'for_geeks_Geeks':3,'geeks_Geeks_for':7,'Geeks_for_for':1}

方法 #3:使用Python生成器

Python3

# Python code to demonstrate
# conversion of nested dictionary
# into flattened dictionary
 
my_map = {"a" : 1,
        "b" : {
            "c": 2,
            "d": 3,
            "e": {
                "f":4,
                6:"a",
                5:{"g" : 6},
                "l":[1,"two"]
            }
        }}
 
# Expected Output
# {'a': 1, 'b_c': 2, 'b_d': 3, 'b_e_f': 4, 'b_e_6': 'a', 'b_e_5_g': 6, 'b_e_l': [1, 'two']}
 
 
ini_dict = {'geeks': {'Geeks': {'for': 7}},
            'for': {'geeks': {'Geeks': 3}},
            'Geeks': {'for': {'for': 1, 'geeks': 4}}}
 
# Expected Output
# {‘Geeks_for_geeks’: 4, ‘for_geeks_Geeks’: 3, ‘Geeks_for_for’: 1, ‘geeks_Geeks_for’: 7}
 
def flatten_dict(pyobj, keystring=''):
    if type(pyobj) == dict:
        keystring = keystring + '_' if keystring else keystring
        for k in pyobj:
            yield from flatten_dict(pyobj[k], keystring + str(k))
    else:
        yield keystring, pyobj
 
print("Input : %s\nOutput : %s\n\n" %
     (my_map, { k:v for k,v in flatten_dict(my_map) }))
 
print("Input : %s\nOutput : %s\n\n" %
     (ini_dict, { k:v for k,v in flatten_dict(ini_dict) }))
输出:
initial_dictionary {'for': {'geeks': {'Geeks': 3}},'geeks': {'Geeks': {'for': 7}},'Geeks': {'for': {'for ':1,'极客':4}}}
final_dictionary {'Geeks_for_geeks':4,'for_geeks_Geeks':3,'Geeks_for_for':1,'geeks_Geeks_for':7}