Python:修改包含数组视图的单个字典项会修改所有项

时间:2016-03-09 17:06:31

标签: python dictionary multidimensional-array namedtuple array-view

我有两个相同键的词典。每个项目都是一个ndarray。

from numpy import zeros, random
from collections import namedtuple

PhaseAmplitude = namedtuple('PhaseAmplitude','phase amplitude')
dict_keys = {'K1','K2', 'K3'}

J1 = dict.fromkeys(dict_keys, zeros((2,2,2,2)))
U1 = dict.fromkeys(dict_keys, PhaseAmplitude(phase = zeros((2,2)),
                                             amplitude = zeros((2,2))))

for iFld in dict_keys:
    U1[iFld] = U1[iFld]._replace(phase = random.random_sample((2,2)), 
                                 amplitude = random.random_sample((2,2)))

我想使用第二个字典中的相应项修改第一个字典中的每个项目:

for iFld in dict_keys:  
    J1[iFld][0,0,:,:] += U1[iFld].phase
    J1[iFld][0,1,:,:] += U1[iFld].amplitude

我希望得到J1[iFld][0,0,:,:] = U1[iFld].phaseJ1[iFld][0,1,:,:] = U1[iFld].amplitude,但我J1[iFld]对所有iFld都相同,并且等于所有iFld键的总和U1的{​​{当然跟踪phase的{​​{1}}和amplitude字段。

对我而言,这看起来像一个错误,但我一直在使用Python一个月左右(从matlab切换)所以我不确定。

问题:这是预期的行为还是错误?为了获得我想要的行为,我应该在代码中更改什么?

注意:我选择U1dict_keysJ1的维度来反映我的具体情况。

1 个答案:

答案 0 :(得分:1)

这不是一个错误,虽然它是一个非常常见的问题,出现在几个不同的情况下。 dict.fromkeys创建一个新词典,其中所有值都是同一个对象。这适用于不可变类型(例如intstr),但对于可变类型,您可能会遇到问题。

e.g:

>>> import numpy as np
>>> d = dict.fromkeys('ab', np.zeros(2))
>>> d
{'a': array([ 0.,  0.]), 'b': array([ 0.,  0.])}
>>> d['a'][1] = 1
>>> d
{'a': array([ 0.,  1.]), 'b': array([ 0.,  1.])}

这是因为:

>>> d['a'] is d['b']
True

在这种情况下使用dict理解来构建字典:

J1 = {k: zeros((2,2,2,2)) for k in dict_keys}

(或者,pre-python2.7):

J1 = dict((k, zeros((2,2,2,2))) for k in dict_keys)