1

我有两个具有相同键的字典。每个项目是一个ndarray。Python:修改包含数组视图的单个字典项目修改所有项目

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并且等于U1的所有iFld键的总和(当然保持跟踪phaseamplitude字段的U1)。

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

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

注:我选择的dict_keysJ1U1维数,以反映我的特殊情况。

+0

Python字典值就像指针,我猜所有的键都指向同一个对象。你可以使用内建'id'函数或'is'运算符来检查它们是否是同一个对象。如果是这种情况,请使用'dict.copy'方法。 –

回答

1

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

如:

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

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

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

(或预python2 .7):

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

是的,这个工作!感谢您的详细回复! – rtphase