Search code examples
pythonlistdictionaryappendextend

Entire dictionary being updated when using "append" or "extend", despite accessing a single element in the dictionary


I have a dictionary in the format:

dictionary= {reference:annotation}

where the reference refers to a position, and the annotation contains information about that location.

I want to find reference positions that overlap, and update the annotation when that occurs. The annotation that I want to update is accessed by dictionary["reference"].qualifiers["ID"] (the annotation contains a second dictionary, where I can access the information I want). When if I try to add another ID to the annotation using: d

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

or

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

all reference annotations in my dictionary are being updated with that new ID. However, if do this using basic list comprehension I get the desired result:

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

Only the annotation at that reference is updated. Can anyone explain why I am getting a different result using "append" or "extend"?


Solution

  • The first example you give as not working works for me:

    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']
    

    results in:

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

    I think you have something wrong with the way you are creating annotations - possibly mistaking a shallow copy for a deep one, or a similar data structure pitfall like that.

    You need to post actual code that doesn't work.


    As a side note, the code you described as a comprehension, is not. It's just use of the array operator +.