Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

なんということもない話なのですが、
これで困ったことがなかったので改めて勉強しなおしたという話です。
今更ではありますが、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]

やったぜ。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした