【问题标题】:python create list of dictionaries without referencepython创建没有参考的字典列表
【发布时间】:2016-09-15 04:44:37
【问题描述】:

我有一个要求,我需要创建字典对象,其中包含嵌入到列表对象中的重复键,如下所示:

[{ "key": "ABC" },{ "key": "EFG" } ]

我决定将一个顶级列表初始化为空,如 outer_list=[] 和一个占位符字典对象,如 dict_obj= {}。接下来,我继续使用以下步骤将元素添加到我的列表中:

  1. 使用dict_obj["key"]="ABC"{ "key": "ABC" } 分配给dict_obj
  2. 使用outer_list.append(dict_obj)将此对象添加到列表中
  3. 使用dict_obj.clear() 刷新/弹出字典对象中的键/项
  4. 根据我的数据中键/项目组合的数量重复步骤 1 到 3

问题:outer_list 对象维护对原始 dict_obj 的引用,如果 dict_obj 被刷新或添加了新的键/项,它会相应地更改。所以最后,我最终得到了这个[{ "key": "EFG" },{ "key": "EFG" } ] 而不是[{ "key": "ABC" },{ "key": "EFG" } ]

如果可能,请指导我一些解决方法。

【问题讨论】:

    标签: python list dictionary


    【解决方案1】:

    我认为有两种方法可以避免重复引用。

    第一个是append 字典的副本,而不是对它的引用。 dict 实例有一个 copy 方法,所以这很容易。只需将您当前的 append 呼叫更改为:

    outer_list.append(dict_obj.copy())`
    

    另一个选项是不总是使用相同的dict_obj 对象,而是为每个条目创建一个单独的字典对象。在此版本中,您将对 dict_obj.clear() 的调用替换为:

    dict_obj = {}
    

    对于第二种方法,您可能会选择重新排序而不是直接进行单行替换。您可以将设置代码移动到循环的开头,并在循环结束时摆脱重置逻辑。

    也就是说,更改如下所示的代码:

    outer_list = []
    dict_obj = {}
    for foo in whatever:
        # add stuff to dict_obj
        outer_list.append(dict_obj)
        dict_obj.clear()
    

    收件人:

    outer_list = []
    for foo in whatever:
        dict_obj = {}
        # add stuff to dict_obj
        outer_list.append(dict_obj)
    

    如果创建内部字典的逻辑足够简单,可以计算,你甚至可以把整个事情变成一个列表推导:

    outer_list = [{"key": value, "key2": value2} for value, value2 in some_sequence]
    

    【讨论】:

    • 感谢@Blckknght 您指出的第一个选项对我有用。我需要累积列表中的键值,直到满足某个条件,然后在完成后将其重置(并进行下一次迭代)。我对刷新列表内容的顺序有一些问题,但这主要与数据有关。我还意识到,如果我的键相同,我什至不需要重置我的字典对象 dict_obj,因为相同 id 的键值无论如何都会被覆盖。
    【解决方案2】:

    以下内容应该是不言自明的:

    # object reuse
    d = {}
    l = []
    d['key'] = 'ABC'
    l.append(d)
    d.clear()
    print(l) # [{}] : cleared!
    d['key'] = 'EFG'
    l.append(d)
    print(l) # [{'key': 'EFG'}, {'key': 'EFG'}]
    
    
    # explicit creation of new objects
    d = {}
    l  = []
    d['key'] = 'ABC'
    l.append(d)
    print(l)
    d = {}
    d['key'] = 'EFG'
    l.append(d)
    print(l)
    

    【讨论】:

      猜你喜欢
      • 2018-12-26
      • 2023-02-07
      • 2017-05-05
      • 1970-01-01
      • 1970-01-01
      • 2020-11-17
      • 2018-04-27
      • 2020-07-22
      • 1970-01-01
      相关资源
      最近更新 更多