【问题标题】:Simplify a deep dictionary in Python在 Python 中简化深度字典
【发布时间】:2020-11-12 01:53:44
【问题描述】:

我有一个相当深刻的 dict 需要简化。我这样做也遇到了一些问题。

这里是需要简化的字典的一个小样本:

data_dict = {
    "DATA": {
        "Page1": [{
            "Section": [{
                "Name": [{
                    "text": "John"
                }],
                "ID_Number": [{
                    "text": "123456"
                }]
            }]
        }],
        "Page2": [{
            "Section": [{
                "Name": [{
                    "text": "Rob"
                }],
                "ID_Number": [{
                    "text": "654321"
                }]
            }]
        }]
    }
}

我已经做了什么:

my_dict = {}
for value in data_dict.values():
    for key, val in value.items():
        if "Tab" in key:
            my_dict[key] = val
        if type(val) == list:
            for i in val:
                for key1, val1 in i.items():
                    my_dict[key] = val1


result_dict = {}
page_list = []
for keys, values in my_dict.items():
    for val in values:
        if type(val) != str:
            for key1, val1 in val.items():
                for x in val1:
                    result_dict[key1] = x.get('text')
                    page_list.append(result_dict)
                    my_dict[keys] = page_list
print("my_dict = ", my_dict)

当前结果:

my_dict = {'Page1': [{'Name': 'Rob', 'ID_Number': '654321'}, {'Name': 'Rob', 'ID_Number': '654321'}, {'Name': 'Rob', 'ID_Number': '65432
1'}, {'Name': 'Rob', 'ID_Number': '654321'}], 'Page2': [{'Name': 'Rob', 'ID_Number': '654321'}, {'Name': 'Rob', 'ID_Number': '
654321'}, {'Name': 'Rob', 'ID_Number': '654321'}, {'Name': 'Rob', 'ID_Number': '654321'}]} 

问题是result_dict 被多次附加到page_list,这是不必要的。另外,我的方法非常混乱。有没有更简洁的方法来获得相同的结果?

想要的结果:

my_dict = {"Page1": [{"Name": "John", "ID_Number": "123456"}], "Page2": [{"Name": "Rob", "ID_Number": "654321"}]}

【问题讨论】:

    标签: python dictionary data-manipulation


    【解决方案1】:

    解决方案 1(更少的循环,但添加了 if 语句):

    如果你想避免太多的嵌套 for 循环。我会利用事先了解重复键的优势,并使用该信息轻松获取内部键或值。

    解决方案 1 和 2 的 dict 参考:

    data_dict = {"DATA": {"Page1": [{"Section": [{"Name": [{"text": "John"}],"ID_Number": [{"text": "123456"}]}]}],"Page2": [{"Section": [{"Name": [{"text": "Rob"}],"ID_Number": [{"text": "654321"}]}]}]}}
    

    代码:

    # Depth #1
    old_dict = data_dict["DATA"]
    new_dict = {}
    
    for d1_key in old_dict:
        d2 = old_dict[d1_key][0]["Section"][0]
        for d2_key in d2:
            if d2_key == "Name":
                new_dict[d1_key] = [{d2_key: d2[d2_key][0]["text"]}]
            if d2_key == "ID_Number":
                merge = new_dict[d1_key][0]
                # Merge above if statement (dict merging)
                new_dict[d1_key] = [{**merge, **{d2_key:d2[d2_key][0]["text"]}}]
    print(new_dict)
    

    输出:

    {'Page1': [{'Name': 'John', 'ID_Number': '123456'}], 'Page2': [{'Name': 'Rob', 'ID_Number': '654321'}]}
    

    解决方案 2:(更多 for 循环,更易读)

    (推荐) 这是第二种解决方案,它提供了相同的所需输出,它不利用有关键或值的信息,而只查看数据的结构。我更喜欢这个,因为它很容易阅读修改扩展

    代码:

    # Depth #1
    old_dict = data_dict["DATA"]
    new_dict = {}
    
    unlist = 0
    k3_temp = None # instead of merge
    v4_temp = None
    for k1, v1 in old_dict.items():
        for v2 in v1[unlist].values(): # using values because we don't use the Section key
            for k3, v3 in v2[unlist].items():
                for k4, v4 in v3[unlist].items():
                    new_dict[k1] = [{k3_temp:v4_temp, k3:v4}]
                    k3_temp = k3
                    v4_temp = v4
    
    print(new_dict)
    

    输出:

    {'Page1': [{'Name': 'John', 'ID_Number': '123456'}], 'Page2': [{'Name': 'Rob', 'ID_Number': '654321'}]}
    

    【讨论】:

    • 谢谢!第二个解决方案完美!如果我可能会问,如果“Section”键下的列表中有更多字典会发生什么变化? (我的特殊情况不需要这个,只是不想浪费机会学习一些新技巧)
    • @StarterAndroid 取决于键的顺序,但它们会被当前键“Name”和“ID_Number”或其他方式覆盖,因此您总是以两个键结束。如果需要,可以修复它。
    【解决方案2】:

    只是为了看到另一个解决方案,for loops 数量荒谬:

    new_dic = {}
    inner_list = []
    
    for i in data_dict:
        for j in data_dict[i]:
            for k in data_dict[i][j]:
                for m in k:
                    for n in k[m]:
                        for x in n:
                            for y in n[x]:
                                for keys, values in y.items():
                                    inner_list.append(values)
                        new_dic[j] = [{'Name': inner_list[0], 'ID_Number': inner_list[1]}]
                        inner_list = [] 
                                        
    print(new_dic)
    

    输出

    {'Page1': [{'Name': 'John', 'ID_Number': '123456'}], 'Page2': [{'Name': 'Rob', 'ID_Number': '654321'}]}
    

    【讨论】:

      猜你喜欢
      • 2021-11-22
      • 2012-03-21
      • 1970-01-01
      • 1970-01-01
      • 2021-12-21
      • 1970-01-01
      • 2017-04-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多