Pythonを学習していると、文字列とリストがいくつかの点で非常に似ていることに気づきます。どちらも複数の要素が順番に並んだシーケンスという共通点を持っており、同じような操作が可能です。
しかし、この二つにはプログラムの挙動を左右する決定的な違いがあります。この記事では、文字列とリストの共通点と、**ミュータブル(変更可能)とイミュータブル(変更不可能)**という重要な違いについて解説します。
リスト風のデータ型:文字列
文字列は、文字が順番に並んだデータ型です。そのため、リストと同じようにインデックスやスライスを使って、特定の部分にアクセスすることができます。
# 文字列を定義
my_text = "Python"
# インデックスで文字を取得
print(my_text[0]) # 出力: P
print(my_text[-1]) # 出力: n
# スライスで一部分を取得
print(my_text[1:4]) # 出力: yth
また、in
演算子を使って、文字列内に特定の文字や部分文字列が含まれているかを確認することもできます。
# 文字列内に "tho" が含まれているか
print("tho" in my_text) # 出力: True
# 文字列内に "java" が含まれていないか
print("java" not in my_text) # 出力: True
このように、文字列は多くの点でリストと同じように扱うことができます。
ミュータブル、イミュータブルなデータ型
ここからが最も重要な違いです。Pythonのデータ型は、作成後にその値を変更できるかどうかに基づいて、ミュータブルとイミュータブルの2種類に分類されます。
- イミュータブル (Immutable): 変更不可能なデータ型。一度作成すると、その中身を変えることはできません。文字列はこちらに属します。
- ミュータブル (Mutable): 変更可能なデータ型。作成後も、要素を追加、変更、削除できます。リストはこちらに属します。
イミュータブルな文字列
文字列はイミュータブルなので、一度作成した文字列の一部分だけを直接変更しようとするとエラーになります。
message = "Hello, Python!"
# message[7] = "W" # この行は TypeError を引き起こします
文字列の内容を変更したい場合は、スライスや連結を使って、新しい文字列を作成する必要があります。
message = "Hello, Python!"
# スライスと連結で新しい文字列を作成
new_message = message[0:7] + "World!"
print(message) # 出力: Hello, Python! (元の文字列は変わらない)
print(new_message) # 出力: Hello, World!
元の変数message
は変わらず、new_message
に新しい文字列が代入されていることが分かります。
ミュータブルなリスト
一方、リストはミュータブルなので、その場で直接値を変更できます。
numbers = [10, 20, 30]
print(f"変更前: {numbers}")
# インデックスで値を変更
numbers[0] = 100
print(f"値を変更後: {numbers}")
# 要素を削除
del numbers[2]
print(f"要素を削除後: {numbers}")
# 要素を追加
numbers.append(400)
print(f"要素を追加後: {numbers}")
実行結果:
変更前: [10, 20, 30]
値を変更後: [100, 20, 30]
要素を削除後: [100, 20]
要素を追加後: [100, 20, 400]
このように、リストはappend()
やdel
文、インデックスによる代入で、オブジェクトそのものを直接変更できます。
まとめ
- 文字列とリストは、インデックスやスライスを使える点で似ています。
- **文字列はイミュータブル(変更不可能)**です。変更するには新しい文字列を作成する必要があります。
- **リストはミュータブル(変更可能)**です。要素の変更、追加、削除を直接行うことができます。
この違いはPythonプログラミングの根幹に関わる重要な概念ですので、しっかりと覚えておきましょう。