【问题标题】:How to move 2 keys / values in a Nested Dict up one level in Python如何在 Python 中将嵌套字典中的 2 个键/值向上移动一级
【发布时间】:2019-10-03 13:55:31
【问题描述】:

昨天我遇到了一个关于在这里重新构建字典列表的问题(我提到它以防其他人遇到类似问题):

Re-structuring a list of Python Dicts using setdefault

但是,我省略了数据的一个(现在看似关键的)部分。最初我认为稍后添加额外的字典键会很容易,但事实证明这在结构上很麻烦。因此,我想出了以下方法来接近我的要求。

本质上,我希望将 2 个键 'selection_id' 和 'other_data' 上移一级并完全替换 'market_data' 字典(参见下面的理想数据结构)。

我认为我可以找到一种使用 setattr 的方法,但这在循环中使用嵌套字典似乎存在问题。此外,我什至不确定这是一种合适的方式,因为无论如何我都会预先收到所有数据,只是格式错误。

我的示例代码如下所示:

market=[{'selection_id': 1099,'value':'11', 'value_name': 'a', 'other_data': 89},  
{'selection_id': 1099,'value':'78', 'value_name': 'p', 'other_data': 89},  
{'selection_id': 1097,'value':'39', 'value_name': 'b', 'other_data': 89},  
{'selection_id': 1097,'value':'52', 'value_name': 'f', 'other_data': 89},  
{'selection_id': 1098,'value':'98', 'value_name': 'd', 'other_data': 89},  
{'selection_id': 1099,'value':'13', 'value_name': 'y', 'other_data': 89},  
{'selection_id': 1098,'value':'4', 'value_name': 'r', 'other_data': 89},
]

new_structure = {}  

new_structure2 = []  


for z in market:
        new_structure.setdefault((z['selection_id'], z['other_data']), []).append({'value': z['value'], 'value_name': z['value_name']})
new_structure2.append([{'market_data': m, 'value_dict': n} for m, n in new_structure.items()])

for s in new_structure2:
    for t in s:
        dict = {}
        dict['selection_id'] = t['market_data'][0]
        dict['other_data'] = t['market_data'][1]
        t['market_data'] = dict

print(new_structure2)

上面的代码产生以下内容:

[[{'market_data':  
{'selection_id': 1099, 'other_data': 89}, 'value_dict':  
[{'value': '11', 'value_name': 'a'}, {'value': '78', 'value_name': 'p'}, {'value': '13', 'value_name': 'y'}]},  
{'market_data':  
{'selection_id': 1097, 'other_data': 89}, 'value_dict':  
[{'value': '39', 'value_name': 'b'}, {'value': '52', 'value_name': 'f'}]}, {'market_data':  
{'selection_id': 1098, 'other_data': 89}, 'value_dict':  
[{'value': '98', 'value_name': 'd'}, {'value': '4', 'value_name': 'r'}]}]]

而我正在寻找的是:

[{'selection_id': 1099, 'other_data': 89, 'value_dict':  
[{'value': '11', 'value_name': 'a'}, {'value': '78', 'value_name': 'p'}, {'value': '13', 'value_name': 'y'}]},  
{'selection_id': 1097, 'other_data': 89, 'value_dict':  
[{'value': '39', 'value_name': 'b'}, {'value': '52', 'value_name': 'f'}]},  
{'selection_id': 1098, 'other_data': 89, 'value_dict':  
[{'value': '98', 'value_name': 'd'}, {'value': '4', 'value_name': 'r'}]}]

为免生疑问,对于任何给定的 'selection_id','other_data' 将始终相同,即如果有 2 个 'selection_id' = 1099 的实例,则这些的 'other_data' 将始终等于 89(在示例中它们都是 89,但实际上对于不同的 selection_id 可能会有所不同。

【问题讨论】:

    标签: python arrays list dictionary nested


    【解决方案1】:

    这是一种方法。

    例如:

    market=[{'selection_id': 1099,'value':'11', 'value_name': 'a', 'other_data': 89},  
    {'selection_id': 1099,'value':'78', 'value_name': 'p', 'other_data': 89},  
    {'selection_id': 1097,'value':'39', 'value_name': 'b', 'other_data': 89},  
    {'selection_id': 1097,'value':'52', 'value_name': 'f', 'other_data': 89},  
    {'selection_id': 1098,'value':'98', 'value_name': 'd', 'other_data': 89},  
    {'selection_id': 1099,'value':'13', 'value_name': 'y', 'other_data': 89},  
    {'selection_id': 1098,'value':'4', 'value_name': 'r', 'other_data': 89},
    ]
    
    result = {}
    for i in market:
        if i["selection_id"] not in result:
            result[i["selection_id"]] = {'selection_id': i["selection_id"], 'other_data': i["other_data"], 'value_dict': []}
        result[i["selection_id"]]["value_dict"].append({'value': i["value"], "value_name": i["value_name"]})
    
    
    print(list(result.values()))
    

    输出:

    [{'other_data': 89,
      'selection_id': 1097,
      'value_dict': [{'value': '39', 'value_name': 'b'},
                     {'value': '52', 'value_name': 'f'}]},
     {'other_data': 89,
      'selection_id': 1098,
      'value_dict': [{'value': '98', 'value_name': 'd'},
                     {'value': '4', 'value_name': 'r'}]},
     {'other_data': 89,
      'selection_id': 1099,
      'value_dict': [{'value': '11', 'value_name': 'a'},
                     {'value': '78', 'value_name': 'p'},
                     {'value': '13', 'value_name': 'y'}]}]
    

    【讨论】:

    • 谢谢,使用我的测试数据,我能够完美地复制你在这里拥有的东西......但是使用我得到的实际数据(即动态),我有一个问题作为列表(result.values()) 创建另一个列表,它不适用于我需要传递数据的方式。我实际上只想要 results.values(),但是如果没有它之前的列表函数(然后我会将其附加到已经存在的列表中),这将不起作用。有没有办法在不先添加额外列表的情况下以某种方式附加到列表?
    • 破译调试有点棘手,但我认为相关的错误是:TypeError: Object of type dict_values is not JSON serializable (if I don't use list).
    • 其实我可以直接使用extend而不是append来考虑!虽然看起来我的数据结构无论如何都是错误的,所以可能需要重新考虑,但是在这里有你的帮助会容易得多,非常感谢!
    • 我设法适应了我的生活环境,最后这是一个简单的调整,但在这里发布没有意义,因为它与我发布的原始数据集无关,(已经标记如已回答)。
    猜你喜欢
    • 2021-01-05
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    • 1970-01-01
    • 2015-08-29
    • 2012-02-10
    相关资源
    最近更新 更多