【问题标题】:How to update dictionaries inside two separate lists?如何更新两个单独列表中的字典?
【发布时间】:2022-01-01 01:42:38
【问题描述】:

我有两个清单:

list1 = [{"name":"xyz" ,"roll":"r" , "sap_id":"z"} , {"name":"pqr" ,"roll":"s" , "sap_id":"w"}]
list2 = [{"cn_number":"26455"} , {"cn_number":"26456"}]

我想要一个新列表,例如:

new_list = [{"name":xyz ,"roll":"r" , "sap_id":"z","cn_number":"26455"} , {"name":"pqr" ,"roll":"s" , "sap_id":"w","cn_number":"26456"}]

我尝试了以下方法:

new_list = [i.update(j) for i, j in zip(list1, list2)]

但出现了一些严重的错误

【问题讨论】:

  • “但有一些严重的错误”根本没有帮助。打个比方,如果你去看医生,你会说“我感到很痛”吗?
  • 我没有收到错误。也许你的意思是一个bug,新列表是[None, None],因为i.update(j) 更新i 但不返回它。如果您使用for i, j in zip(list1, list2): i.update(j)list1 现在将成为所需的新列表,但这种突变不是好的做法。
  • 我没试过。

标签: python list dictionary


【解决方案1】:

此语法适用于python3.5+ 合并两个字典z = {**x, **y}

Python 3.7.0 (default, Jun 28 2018, 13:15:42)
>>> list1 = [{"name":"xyz" ,"roll":"r" , "sap_id":"z"} , {"name":"pqr" ,"roll":"s" , "sap_id":"w"}]
>>> list2 = [{"cn_number":"26455"} , {"cn_number":"26456"}]
>>> new_list = [{**i, **j} for i, j in zip(list1, list2)]
>>> new_list
[{'name': 'xyz', 'roll': 'r', 'sap_id': 'z', 'cn_number': '26455'}, {'name': 'pqr', 'roll': 's', 'sap_id': 'w', 'cn_number': '26456'}]

更多信息:How do I merge two dictionaries in a single expression (take union of dictionaries)?

【讨论】:

  • 它适用于 Python 3.7.0(默认,2018 年 6 月 28 日,13:15:42)
  • @AKX,不,||= 是在 3.9 中添加的,请阅读您提供的链接。 {**x, **y} 是 3.9 之前的版本。
  • 哎呀,我错了。 (修复了我的答案中的文档链接。)
【解决方案2】:

您可以使用Python 3.5+ dict 合并语法:

new_list = [{**a, **b} for (a, b) in zip(list1, list2)]

结果

[
  {'name': 'xyz', 'roll': 'r', 'sap_id': 'z', 'cn_number': '26455'}, 
  {'name': 'pqr', 'roll': 's', 'sap_id': 'w', 'cn_number': '26456'},
]

【讨论】:

    【解决方案3】:

    一个有效的方法是使用collections.ChainMap,它专门用于组合多个字典。阅读更多关于文档here

    from collections import ChainMap
    
    [dict(ChainMap(i,j)) for i,j in zip(list1, list2)]
    
    [{'cn_number': '26455', 'name': 'xyz', 'roll': 'r', 'sap_id': 'z'},
     {'cn_number': '26456', 'name': 'pqr', 'roll': 's', 'sap_id': 'w'}]
    

    注意:根据您希望如何使用更新列表中的每个元素,您可以使用生成器并避免使用 dict() 而不是 ChainMap 对象,以便在不使用不必要内存的情况下仍然获得所需的内容! ChainMap 通过仍然引用原始对象为您提供多个字典的单一可更新视图。

    #efficient way -
    
    #EDITED: lesser keystrokes as suggested by @Kelly
    g = map(ChainMap, list1, list2) 
    
    #g = (ChainMap(i,j) for i,j in zip(list1, list2))
    
    next(g).get('sap_id')
    
    z
    

    【讨论】:

    • 我们也可以使用[dict(ChainMap(*t)) for t in zip(list1, list2)]
    • g = map(ChainMap, list1, list2)。没有必要为此编写自己的生成器表达式。
    • 感谢@KellyBundy 的输入。要么工作!但地图确实使用较少的击键(代码高尔夫球手!)所以我更新了我的答案:)
    猜你喜欢
    • 2017-06-10
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 2019-10-24
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    相关资源
    最近更新 更多