プログラミングを学んでいると、「イミュータブル(Immutable)」と「ミュータブル(Mutable)」という言葉を目にすることがあります。
イミュータブルとミュータブルは、「オブジェクトの中身を後から変更できるかどうか」に関係しています。
この記事では、
- イミュータブルとミュータブルの違い
- Pythonの具体的なコード例
を、プログラミング初心者の方にも分かるように丁寧に解説していきます。
「イミュータブル」と「ミュータブル」の違い
まずは、イミュータブルとミュータブルの意味を整理しましょう。
イミュータブル(Immutable)は、「不変の」「変更できない」という意味を持つ英単語です。プログラミングにおいては、一度作成したオブジェクトの中身(状態)を、あとから変更できないという性質を指します。
たとえば、Pythonでは、次のような型がイミュータブルです。
- 数値(
int,float) - 文字列(
str)
これらは、作られた瞬間に中身(状態)が確定し、後から中身を直接書き換えることができません。
一方、ミュータブル(Mutable)は、「可変の」「変更できる」という意味を持つ英単語です。プログラミングにおいては、一度作成したオブジェクトの中身(状態)を、後から変更できるという性質を指します。
たとえば、Pythonでは、次のような型がミュータブルです。
- リスト(
list) - 辞書(
dict)
これらは、オブジェクトそのものを作り直さなくても、後から中身だけを変更できます。
イミュータブルなオブジェクトの例(Python)
Pythonの文字列(str)はイミュータブルな文字列オブジェクトです。つまり、一度作成した文字列の中身を、直接書き換えることはできません。
以下は、Pythonで一度作成した文字列の中身を変更しようとした例です。
text = "Hello"
# 先頭の文字を変更しようとする
text[0] = "h"
print(text)上記のコードを実行すると、次のエラーが発生します。
TypeError: 'str' object does not support item assignment"Hello"はイミュータブルな文字列オブジェクトです。そのため、文字列の各文字(text[0]など)は直接変更できません。
正しい変更方法:新しい文字列オブジェクトを作る
文字列を変更したい場合は、既存の文字列オブジェクトを変更するのではなく、新しい文字列オブジェクトを作ります。以下にサンプルコードを示します。
text = "Hello"
new_text = "h" + text[1:]
print(new_text)上記のコードでは、"Hello"を分解し、必要な部分を組み合わせて、まったく新しい文字列new_textを作成しています。元のtextは一切変更されていません。このコードを実行すると、以下のような結果が表示されます。
hello元のtextは変更せず、新しい文字列new_textを作っているのでエラーが発生しなくなります。
「再代入」はエラーにならない理由
次のコードはエラーになりません。
text = "Hello"
text = "World"これを見て、「あれ?文字列って変更できないんじゃないの?」と思うかもしれません。しかし、ここで行っているのは「文字列の変更」ではありません。
"Hello"という文字列オブジェクトはそのまま存在しています。新しく"World"という文字列オブジェクトを作成して、変数textが指している先を切り替えているだけだからです。つまり、"Hello"を書き換えているのではなく、textが参照するオブジェクトを変えているのでエラーにならないのです。
「変数の再代入」と「オブジェクトの変更」は別物です。
ミュータブルなオブジェクトの実例(Python)
Pythonのリスト(list)はミュータブルなリストオブジェクトです。つまり、一度作成したリストの中身を、後から自由に変更できます。
以下は、Pythonでリストを生成し、そのリストの要素を変更する例です。
numbers = [1, 2, 3]
numbers[0] = 100
print(numbers)上記のコードを実行すると、以下のような結果が表示されます。
[100, 2, 3]このコードでは、[1, 2, 3]というリストオブジェクトの中の要素だけを書き換えています。文字列のときと違ってエラーは発生しません。[1, 2, 3]はミュータブルなリストオブジェクトだからです。
本記事のまとめ
この記事では『イミュータブルとミュータブルの違い』について説明しました。
イミュータブルとミュータブルの違いは「オブジェクトの中身を後から変更できるかどうか」です。
- 文字列(
str)や数値(int)はイミュータブル - リスト(
list)や辞書(dict)はミュータブル
また、「変数の再代入」と「オブジェクトの変更」は別物である点も重要です。
お読みいただきありがとうございました。