LoginSignup
1
2

More than 5 years have passed since last update.

jsとpythonのディープコピー

Last updated at Posted at 2018-06-06

JSのオブジェクトが参照渡しであることに知らずにハマったあと、Pythonでも参照渡しでループを回してlistの要素が全て同じ、みたいな事例に出くわしたので整理のために書いておく。

JSでハマったコード

mapDataをLeftとRightとで別に持ちたかったが、GETするたびにresultが更新される → 参照渡しなので、LeftもRightも同じになってしまっていた。

// 以下、ajaxでGETしたときのコールバック
svg = _setSvgArea( id );

if ( id == "#mapLeft" ) {

  // 1. _getJapanMapがオブジェクトを返す。
  mapDataLeft = _getJapanMap( result, JAPAN_MAP );

  } else if ( id == "#mapRight" ) {

  // 2. もう一回GETすると、resultが更新されるとmapDataLeftも更新されてしまう。
  mapDataRight = _getJapanMap( result, JAPAN_MAP );

};

jQueryの$.extendで解決。

mapDataLeft = $.extend(true, {}, _getJapanMap( result, JAPAN_MAP ) );

pythonで出くわしたコード

この場合はループの中のcolumnが参照渡し先。medicine['medicine_name']などで値を更新すると、前のループでappendしたcolumnまで更新されてしまう。

for medicine in medicines:
  column = GET_MEDICINES_MESSAGE['column']
  column['text'] = medicine['medicine_name']
  columns.append(column)

copyモジュールのdeepcopyで解決。

from copy import deepcopy
.
.
for medicine in medicines:
  column = GET_MEDICINES_MESSAGE['column']
  column['text'] = medicine['medicine_name']
  columns.append(deepcopy(column))

結局は、どういうときにディープコピーが必要になるのか?

変数や関数でつくったオブジェクト(辞書)をループで回すなど繰り返し処理するときにディープコピーを使う。
変数や関数でつくったオブジェクト(辞書)をループで回すなど繰り返しで値を代入するときにディープコピーを使う。

1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2