Python字典以某种方式更新

时间:2013-12-26 21:47:07

标签: python python-3.x dictionary

我已尽力解决这个问题,但我不能为我的生活做好准备。我有一个包含许多不同值的字典,包括另一个字典。在为字典中的字典设置值之前,我尝试将值设置为等于“空白”字典,以便在后续步骤中我可以更新它。

短篇小说是:我有两行不知何故正在改变我不期望的字典。鉴于一些决定:  blankresiduedict = {stuff:[stuff], stuff:[stuff]}; blankidentifiers = {stuff:stuff, stuff:stuff}

self.pdb_chain_dict['1MH9_B'] = (blankresiduedict.copy(),blankidentifiers.copy())
self.pdb_chain_dict['1MH9_B'][0][(stuff)][0] = residuedict[('A','D','41')]

以某种方式将blankresiduedict的值更改为等于residuedict。

知道这是怎么回事吗?在该段代码中几乎没有其他对blankresiduedict的引用,当我查看输出时,blankresiduedict开始准确,然后每个循环保持更改值等于该循环的任何残差。



(以下是更详细的说明)

这是一个非常大的项目的一小部分,因此其中一些可能很难以紧凑的形式表示。我会尽力消除不必要的东西。这是我尝试用于更新类实例的字典的类中的方法。

blankresiduedict = {}
blankidentifiers = {}
self.allowmultiples = True
self.ancestorline = [
    '1MH9', 
    'A', 'D', '41',
    'A', 'D', '43',
    'A', 'T', '130', 
    #etc...
]
self.no_key_residues = 6
self.pdb_chain_dict = {
    '1MH9_B': (
        {
            ('A','D','41'): [('B','D','41')],
            ('A','D','43'): [('B','D','43')], 
            ('A','T','130'): [('B','T','130')]
        }, 
        #{identifiers dictionary}
    ), 
    '1MH9_C': (
        #{etc},{etc}
    ), 
    # etc...
}


for i in range(1, (3*self.no_key_residues)+1, 3): # Using this loop structure allows a variable number of key residues to be given
    if not self.allowmultiples:
        raise Exception("Do some stuff here")
    else:
        blankresiduedict[(self.ancestorline[i],self.ancestorline[i+1],self.ancestorline[i+2])] = [('-','-','-')] 
blankidentifiers = {'EC Num':'-','Sprot':'-','Class':'-','Keywords':'-','Title':'-','SeqRepr':'-'}

### Begin some loop structure, where for every loop, the following is basically happening
residuedict = {
    ('A','D','41'): ('B','D','10'), 
    ('A','D','43'): ('B','D','12')
} #in actuality this value would change for every loop, but just showing what a typical loop would look like
self.pdb_chain_dict['1MH9_B'] = (blankresiduedict.copy(),blankidentifiers.copy())
self.pdb_chain_dict['1MH9_B'][0][('A','D','41')][0] = residuedict[('A','D','41')]

这里应该发生的是pdb_chain_dict中的值被设置为两个空白字典的元组({residuedict},{identifiers})我在这个例子中大部分都是单独留下标识符字典,因为它具有确切的同样的问题。但是,我发现的是,blankresidimedict实际上正在发生变化。并且,在进行了大量测试之后,它所更改的行是self.pdb_chain_dict['1MH9_B'][0][('A,'D','41')][0] = residuedict[('A','D','41')]

这对我来说毫无意义...... blankresidimed甚至没有涉及,但不知何故,它的价值正在改变。

1 个答案:

答案 0 :(得分:3)

那是因为字典的副本不是深层副本,而你的字典值是列表,它们是可变的。以下是重现问题的最小示例:

d1 = {"foo": [1, 2, 3]}
d2 = d1.copy()
# Add a new element to d2 to show that the copy worked
d2["bar"] = []

# The two dicts are different.
print d1
print d2

# However, the list wasn't copied 
# it's the same object that shows up in 2 different dicts
print d1["foo"] is d2["foo"]

# So that's what happens in your code: you're mutating the list.
d1["foo"].append(5)
print d2["foo"]