【问题标题】:Entire dictionary being updated when using "append" or "extend", despite accessing a single element in the dictionary使用“追加”或“扩展”时更新整个字典,尽管访问字典中的单个元素
【发布时间】:2016-02-26 19:29:14
【问题描述】:

我有一本格式如下的字典:

dictionary= {reference:annotation}

其中引用指的是一个位置,并且注释包含有关该位置的信息。

我想找到重叠的参考位置,并在发生这种情况时更新注释。我要更新的注释由dictionary["reference"].qualifiers["ID"] 访问(注释包含第二个字典,我可以在其中访问我想要的信息)。 如果我尝试使用以下方法向注释添加另一个 ID:d

dictionary[reference].qualifiers["ID"].extend(["new ID"])

dictionary[reference].qualifiers["ID"].append("new ID")

我的字典中的所有参考注释都将使用该新 ID 进行更新。 但是,如果使用基本列表理解来执行此操作,我会得到所需的结果:

dictionary[reference].qualifiers["ID"] = dictionary[reference].qualifiers["ID"] + ["new ID"]

仅更新该引用处的注释。谁能解释为什么我使用“追加”或“扩展”得到不同的结果?

【问题讨论】:

  • 假设你打印一个字典["reference"].qualifiers["ID"]的值,你会得到什么?
  • 我提供了一个答案,因为它很有可能会有所帮助,即使这个问题是有缺陷的。但是,这个问题不符合提问准则:stackoverflow.com/help/mcve ... 并且可能很快就会被关闭,除非你纠正它。
  • 您发布的代码不是 MCVE。但是,您似乎认为注释掉的行与其上方的第二行相同。在您的问题中,“期望结果”代码实际上与“假定有问题”代码相同。在您的实际代码中,注释掉的是“分类”数组的第一个元素,而不是数组本身。这不一样。它也与您对问题的描述没有相似之处(“所有参考注释都已更新”),但至少看起来有差异......
  • 抱歉,我回滚到您的旧问题并投票关闭它,因为此问题无法再重现。我这样做是因为您的示例和您的完整代码似乎是不同的问题。我的意思是你的例子有效,但你的代码应该是另一个问题。正如我所说,如果您的问题没有解决,您可以提出另一个问题,但请使用 MCVE,正如@GreenAsJade 所说(就像您的旧问题一样)。另外请记住下次不要在一个问题中问两个问题。 :)
  • 所以记住我说的话,向minimal reproducible example提问:你的问题中包含的代码应该是Minimal(只有重现问题所必需的代码),完整(重现问题所需的所有代码)和可验证(我们应该能够仅使用您问题中的代码重现问题,仅此而已) . :D

标签: python list dictionary append extend


【解决方案1】:

您给出的第一个示例不起作用对我有用:

class Annotation:
    def __init__(self, initial_val):
        self.qualifiers = {'ID': [initial_val]}

an1 = Annotation("foo")
an2 = Annotation("bar")

d = {'ref1' : an1, 'ref2': an2}

print d['ref1'].qualifiers['ID']
print d['ref2'].qualifiers['ID']

d['ref1'].qualifiers['ID'].extend(['new foo'])

print d['ref1'].qualifiers['ID']
print d['ref2'].qualifiers['ID']

结果:

~ mgregory$ python foo.py
['foo']
['bar']
['foo', 'new foo']
['bar']
~ mgregory$ 

我认为您创建注释的方式有问题 - 可能将浅拷贝误认为深拷贝,或类似的数据结构陷阱。

您需要发布不起作用的实际代码。


附带说明,您描述为理解的代码不是。它只是使用数组运算符+

【讨论】:

  • 好的,感谢您的评论,我已经用原始代码更新了我的问题。自从我发帖以来,一位同事还提出了一个数据结构问题。
  • 酷 - 也许他们的建议会为您解决问题。我讨厌挑剔,但请注意,您提供的代码不是 MVCE。通常,在创建 MVCE 的过程中,您自己会发现问题。
  • 没关系,我对论坛上的回复速度印象深刻。将来我会尝试坚持使用 MVCE。在这种情况下,问题似乎源于我一直用来读取文件的另一款软件,并且可能如您所说,源于深拷贝与浅拷贝问题。无论如何,再次感谢您的帮助,我现在似乎已经解决了这个问题。
  • 更新:刚刚又看了一遍,我认为你是对的。制作该功能的深层副本似乎允许我根据需要使用附加。对于 tmp_record 中的功能:feature= copy.deepcopy(feature)
  • 您会在创建 MVCE 的过程中自己发现这一点;)
猜你喜欢
  • 2015-02-04
  • 1970-01-01
  • 1970-01-01
  • 2013-02-15
  • 2014-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-07
相关资源
最近更新 更多