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].phase и J1[iFld][0,1,:,:] = U1[iFld].amplitude, но я получаю J1[iFld] быть одинаковым для все iFld и равны сумме по всем iFld ключам U1 (отслеживание phase и amplitude полей U1, конечно).

Для меня это похоже на ошибку, но я использую Python только месяц или около того (переход из Matlab), поэтому я не уверен.

Вопрос: Является ли это ожидаемым поведением или ошибкой? Что я должен изменить в своем коде, чтобы получить поведение, которое я хочу?

Примечание: Я выбрал число измерений dict_keys, J1 и U1, чтобы отразить мою конкретную ситуацию.

+0

Значения python dict похожи на указатели, я думаю, что все ключи указывают на один и тот же объект. Вы можете проверить, являются ли они одним и тем же объектом, используя встроенную функцию 'id' или оператор' is'. Если это так, используйте метод 'dict.copy'. –

ответ

1

Это не ошибка, хотя это довольно распространенная проблема, которая проявляется в нескольких разных ситуациях. dict.fromkeys создает новый словарь, где все значения - это тот же объект. Это отлично работает для неизменяемых типов (например, int, str), но для изменяемых типов вы можете столкнуться с проблемами.

например:

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

(или, предварительно python2 .7):

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

Да, это сработало! Спасибо за подробный ответ !!! – rtphase

 Смежные вопросы

  • Нет связанных вопросов^_^