ひとりでのアプリ開発 - fineの備忘録 -

ひとりでアプリ開発をするなかで起こったことや学んだことを書き溜めていきます

Python - ミュータブル・イミュータブル、代入

初めに

 Pythonでは、ミュータブルな型でイミュータブルな型があります。本記事ではこれらの違いとPythonの代入の仕方についてまとめます。

ミュータブル・イミュータブル

ミュータブル(mutable)、イミュータブル(immutable)

 Pythonのオブジェクトには、ミュータブルなものとイミュータブルなものがあります。

ミュータブル 値を変更できるオブジェクト
イミュータブル 値を変更できないオブジェクト

 mutable は "可変" を意味します。

ミュータブルな型
  • リスト
  • 辞書
  • セット
イミュータブルな型
  • int
  • float
  • bool
  • str
  • bool
  • タプル

参照渡し

値渡し・参照渡し

 一般に代入には、値渡しと参照渡しがあります。

値渡し 変数に値そのものが割り当てられる
参照渡し 変数に値の参照が割り当てられる

Pythonにおける代入について

 Pythonにおける代入は参照渡しによって行われます。

(例)

x = [10, 20, 30]
y = x

print(x, y)  # 出力: [10, 20, 30] [10, 20, 30]

y.append(100)   # y のリストに 100 を追加

print(x, y)  # 出力: [10, 20, 30, 100] [10, 20, 30, 100]

 上の例では、リストxyに代入したあと、yに 100 を追加した結果、xにも 100 が追加されたことがわかります。

 Pythonにおける代入は参照渡しです。リストはミュータブルな型であるため、xyの片方を変更するともう片方も変更されます。

イミュータブルな型の代入

 参照渡しでは、ミュータブルな型の場合は代入先の変数が元の値に影響を与えました。

 次は、イミュータブルな型の代入の例を見てみます。

(例)

x = 10
y = x

x = x + 1

print(x, id(x))  # 出力: 11 140720110422776
print(y, id(y))  # 出力: 10 140720110422744

 xyはint型なため、イミュータブルな型になっています。このときy = xでの代入は参照渡しではなく、yという新しいオブジェクトを生成しています。

 xyは別のオブジェクトであるため、y = xの後にxを変更してもyは変更されません。

 xyが別オブジェクトであることはidを見ると判別できます。

ミュータブルなオブジェクトをコピー

 ミュータブルなオブジェクトを代入した場合、片方の値を変更するともう片方も変更されます。

 このような状況は、オブジェクトをコピーし、新しいオブジェクトを生成することで避けることができます。

x = [10, 20, 30]
y = x.copy()    # 新しいオブジェクトを生成

print(x, y)  # 出力: [10, 20, 30] [10, 20, 30]

y.append(100)   # y のリストに 100 を追加

print(x, y)  # 出力: [10, 20, 30] [10, 20, 30, 100]

関数の引数

 関数の引数も代入と同じ処理が行われます。

(例:ミュータブルな型の場合)

def add_one(x):
  x[0] += 1
  return x

num = [10]
result = add_one(num)

print(num, result)  # 出力: [11] [11]

(例:イミュータブルな型の場合)

def add_one(x):
  x += 1
  return x

num = 10
result = add_one(num)

print(num, result)  # 出力: 10 11