python字典奇怪的行为

时间:2013-09-04 04:46:22

标签: python dictionary

  1. 我不明白为什么,当c = 2和c = 3时,dict2 ['A'] = 1和dict2 ['A'] = 4分别而不是0,即使我让dict2相等到dict1,dict1 ['A'] = 0?为什么dict1 ['A']从0变化?我没有改变任何dict1变量!
  2. 为什么dict3在循环中显示正确的值,但只显示循环结束后最后一次迭代3的值。
  3. 非常感谢。

    import collections
    
    def main():
    
    
        dict1 = collections.OrderedDict()
        dict2 = collections.OrderedDict()
        dict3 = collections.OrderedDict()
    
        dict1['A'] = 0
        dict1['B'] = 0
        dict1['C'] = 0
    
        for c in [1, 2, 3]:
            print('c=' + str(c))
            dict2 = dict1
            print('dict1A=' + str(dict1['A']))
            print('dict2A=' + str(dict2['A']))
            if c == 1:
                dict2['A'] = 1
                dict2['B'] = 2
                dict2['C'] = 3
            elif c ==2:
                dict2['A'] = 4
                dict2['B'] = 5
                dict2['C'] = 6
            elif c ==3:
                dict2['A'] = 7
                dict2['B'] = 8
                dict2['C'] = 9
            dict3['c' + str(c)] = dict2
            print('dict2A=' + str(dict2['A']))
            print('dict' + str(c) + 'A=' + str(dict3['c' + str(c)]['A']))
            print('dict' + str(c) + 'B=' + str(dict3['c' + str(c)]['B']))
            print('dict' + str(c) + 'C=' + str(dict3['c' + str(c)]['C']))
    
        print('dict3-c1A='+ str(dict3['c1']['A']))
        print('dict3-c2B=' + str(dict3['c2']['B']))
        print('dict3-c3C=' + str(dict3['c3']['C']))
    
    if __name__ == '__main__':
        main()
    

    输出:

    c=1
    dict1A=0
    dict2A=0
    dict2A=1
    dict1A=1
    dict1B=2
    dict1C=3
    c=2
    dict1A=1
    dict2A=1
    dict2A=4
    dict2A=4
    dict2B=5
    dict2C=6
    c=3
    dict1A=4
    dict2A=4
    dict2A=7
    dict3A=7
    dict3B=8
    dict3C=9
    dict3-c1A=7
    dict3-c2B=8
    dict3-c3C=9
    

    *编辑 * 非常感谢您的回答。我不知道字典的'='操作与变量的操作不同。我发现并且正如g.d.d.c所建议的那样,copy()就是我想要的:

            dict2 = dict1.copy()
    

3 个答案:

答案 0 :(得分:3)

  1. 这就是Python对象模型的工作原理。通过说dict2 = dict1,在第一次循环迭代期间实质上发生的是原始dict2对象被丢弃,而dict2现在引用与dict 1 相同的底层对象。在后续循环迭代期间,dict2 = dict1语句无效,因为dict1dict2已经指向同一个底层对象。

  2. dict3的打印语句比循环体更进一步缩进;它们不是循环的一部分,因此只有在循环结束后才执行。

答案 1 :(得分:1)

dict2 = dict1

这不会删除dict2的内容,并将其填入dict1的内容。这使得名称dict1dict2引用相同的对象。您对dict2所做的任何操作都会影响dict1,因为它们是相同的。

如果你想要一个新的字典,请制作一个新的字典:

dict2 = collections.OrderedDict()

如果你想清除旧字典,请清除它,但这可能不是你想要的:

dict2.clear()

答案 2 :(得分:1)

当您指定dict2 = dict1时,您将之前存在的名称替换为空OrderedDict,并告诉口译员改为使用dict2来引用存在的Object在名称dict1中。你可以做几件事来解决这个问题:

# copy
dict2 = dict1.copy()
# update dict 2
dict2.update(dict1.iteritems())