2016-02-20 2 views
0

Массивы yn и zn являются равно numericaly говоря, но есть нечетная разница: линии yn += 7, как и ожидалось, не меняется tn массива, но вторая последняя строка zn += 7 изменяет tn массив!Оператор на месте Python (как «+ =»), массив numpy и функция идентификации не работают должным образом?

Это код:

import numpy as np 
def f(x): return (1*x) 
def g(x): return (x) 
nn = 5 
tn = np.zeros(nn) 
yn = np.zeros(nn) 
zn = np.zeros(nn) 

tn = np.linspace(0,1,nn) 
yn = f(tn) 
zn = g(tn) 

print('tn at step1 =',tn) 
yn += 7 #as expected, this line does not change tn. 
print('tn at step2 =',tn) 
zn += 7 #why this line adds 7 to tn array?! 
print('tn at step3 =',tn) 

Выход:

tn at step1 = [ 0. 0.25 0.5 0.75 1. ] 
tn at step2 = [ 0. 0.25 0.5 0.75 1. ] 
tn at step3 = [ 7. 7.25 7.5 7.75 8. ] *why is 7 added to tn array?!* 

Обратите внимание, что участвуют:

  • NumPy массив
  • г (х) как функция идентичности
  • в месте iadd оператора (+ =)

Хотя я решил эту проблему, используя вместо zn = zn + 7zn += 7 моего вопроса: почему во второй последней строке zn += 7 изменяется tn массива?

+0

Несколько кодовых точек. Исходные «нули» определений 'tn' и т. Д. Перезаписываются последующими назначениями. они вам не нужны. В 'g'' '()' ничего не добавляет. Используйте 'return x' или, как рекомендовано в ответе' return x.copy() '. – hpaulj

ответ

7

Когда вы определяете g(), вы заставляете его возвращать свой аргумент без изменений. Из-за этого, когда вы говорите zn = g(tn), вы фактически говорите zn = tn. Поэтому zn теперь просто другое имя для tn. Оператор += не вполне точный дубликат x = x +. Обычно он делает то же самое, но в фоновом режиме он вызывает метод с именем __iadd__. Поскольку zn и tn - это тот же объект, вы вызываете метод tn__iadd__. Из-за этого изменяется tn. Чтобы изменить это, вы можете сказать zn = tn.copy(), когда вы его определяете; или вы могли бы сказать zn = zn + 7 при попытке добавить 7.