33
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Pythonのリストで参照渡しでないコピーを作成する話

Last updated at Posted at 2016-07-25

なんということもない話なのですが、
これで困ったことがなかったので改めて勉強しなおしたという話です。
今更ではありますが、pythonでは何かを代入すると値ではなく参照が渡されます。

a = 1
b = a
print(id(a))
print(id(b))

>1928654608
>1928654608

整数型の場合、bに別の値を代入するとbのみ新しいアドレスに参照先が切り替わります。
元のaについては変更を行いません。

b = 334
print(a)
print(b)

>1
>334

しかし、リストの場合は勝手が違っています。

a = [1, 2, 3, 4]
b = a
print(a)
print(b)

>[1, 2, 3, 4]
>[1, 2, 3, 4]

b.pop(1)
print(a)
print(b)

>[1, 3, 4]
>[1, 3, 4]

bにリストaを代入し、popでbから要素を削除すると直接変更していないaの内容も変わっています。
参照先もそのままです。

print(id(a))
print(id(b))

>2277581359240
>2277581359240

「aの元の情報を保持したままbに破壊的な操作を加えたい」みたいな場合には以下のように、
スライスを使ってコピーを生成するのが手軽です。

a_ =[1, 2, 3, 4]
c = a_[:]
c.pop(1)
print(a_)
print(c)

>[1, 2, 3, 4]
>[1, 3, 4]

(2016/7/27追記)list()とかcopyモジュールを使ってもできるという意見をもらったので試しました。

a = [1, 2, 3, 4]
b = list(a)
b.pop(1)
print(a)
print(b)

>[1, 2, 3, 4]
>[1, 3, 4]

import copy
a = [1, 2, 3, 4]
c = copy.copy(a)
c.pop(1)
print(a)
print(c)

>[1, 2, 3, 4]
>[1, 3, 4]

やったぜ。

33
21
5

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?