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

标签 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 都是相同的,并且等于所有 的总和U1 的 iFld 键(当然要跟踪 U1phaseamplitude 字段) .

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

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

注意:我选择了 dict_keysJ1U1 的维度数来反射(reflect)我的特定情况.

最佳答案

这不是一个错误,尽管这是一个非常常见的问题,会在几种不同的情况下出现。 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)

关于Python:修改包含数组 View 的单个字典项会修改所有项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35898028/

相关文章:

python - 如何使用父字段限制查询集?

python - 如何从 python 中检查计算机上是否安装了 LaTeX 和 TeX Live?

c - 如何在访问数组和二维数组时通过 c 中的 malloc 分配最大长度?

python - 获取新的唯一列表,仅包含原始列表中最后出现的元素

python - Julia 将分区数据框存储到字典中

php - Array PHP,检查是否存在多个元素到另一个数组

c++ - 对整数指针数组进行排序

python - PyQt5:如何连接()和发射()

python - IntegerField 只接受 11 位数字(不小于 11,不大于 11)

dictionary - 在一种情况下检查键是否存在于多个映射中