リストとタプルはPythonで最もよく使われるデータ構造の2つで、ディクショナリーはその3つ目です。リストとタプルは多くの類似点を持っています。
- どちらもアイテムのコレクションを格納するシーケンスデータ型です。
- どのようなデータ型の項目でも格納できる
- そして、どの項目もそのインデックスを介してアクセス可能です。
そこで、ここで答えたいのは、両者はどう違うのか、ということです。そして、もし両者に違いがないのであれば、なぜこの2つを用意する必要があるのでしょうか?リストとタプルのどちらか一方だけではだめなのでしょうか?
この記事では、リストとタプルがどのように違うのかを紹介します。
>
構文の違い
Pythonでは、リストとタプルは異なる方法で宣言されます。リストは角括弧 []
で作成されるのに対し、タプルは括弧 ()
で作成されます。
tuple_names = ('Nicholas', 'Michelle', 'Alex')
list_names = ['Nicholas', 'Michelle', 'Alex']
print(tuple_names)
print(list_names)
これは次のようになります。
('Nicholas', 'Michelle', 'Alex')
['Nicholas', 'Michelle', 'Alex']
ここでは、 tuple_names
という名前のタプルと list_names
という名前のリストを定義しました。タプルの定義では、括弧 ()
を使い、リストの定義では、角括弧 []
を使っています。
Pythonの type()
メソッドは、オブジェクトの型を簡単に特定するのに役立ちます。
print(type(tuple_names)) # <class 'tuple'=""
print(type(list_names)) # <class 'list'=""
ミュータブルとイミュータブル
リストはMutableであるのに対し、タプルはImmutableであることが両者の大きな違いです。これは何を意味するのでしょうか。
それはどういうことでしょうか。
リストの値を変更することはできますが、タプルの値を変更することはできません。
リストは変更可能なので、リストを辞書のキーとして使用することはできません。これは、辞書のキーとして使用できるのは、不変のオブジェクトのみだからです。したがって、必要であれば、タプルを辞書のキーとして使用することができます。
それでは、リストとタプルの不変性の違いを示す例を見てみましょう。異なる名前のリストを作ってみましょう。
names = ["Nicholas", "Michelle", "Alex"]
このリストの最初の要素を Nicholas
から Samuel
に変更しようとするとどうなるか見てみましょう。
names[0] = "Samuel"
注:最初の要素はインデックス 0
にある。
では、リストの中身を表示してみましょう。
print(names)
これで更新されたリストが出力されます。
['Samuel', 'Michelle', 'Alex']
同じことをタプルでやってみるとどうなるでしょうか?まず、タプルを作ってみよう。
names = ("Nicholas", "Michelle", "Alex")
タプルの最初の要素を Nicholas
から Samuel
に変更しましょう。
names[0] = "Samuel"
この場合、次のようなエラーが発生します。
Traceback (most recent call last):
File "<pyshell#7", line 1, in <module
names[0] = "Samuel"
TypeError: 'tuple' object does not support item assignment
タプルオブジェクトは項目の割り当てをサポートしていないというエラーが発生しました。理由は、タプルオブジェクトは作成後に変更することができないからです。
再利用 vs 複製
タプルはコピーできない。その理由は、タプルは不変だからです。もし tuple(tuple_name)
を実行したら、それは直ちに自分自身を返します。
names = ('Nicholas', 'Michelle', 'Alex')
copy_names = tuple(names)
print(names is copy_names)
この2つは同じものである。
True
これに対して、list(list_name)
は、すべてのデータを新しいリストにコピーする必要がある。
names = ['Nicholas', 'Michelle', 'Alex']
copy_names = list(names)
print(names is copy_names)
namesと
copy_namesは同じではないので、結果は
False` となります。
False
次に、リストとタプルのサイズの違いについて説明します。
サイズ差
Pythonはタプルに対して、イミュータブルであるため、より大きなメモリブロックを低オーバーヘッドで確保します。一方、リストに対しては、Pythonは小さなメモリブロックを割り当てます。最後には、タプルはリストと比較してより小さなメモリを持つことになります。このため、要素数が多い場合は、リストと比較してタプルの方が少しスペース効率が良くなります。
例えば、同じ要素を含むリストとタプルを作成し、両者のサイズを比較してみましょう。
tuple_names = ('Nicholas', 'Michelle', 'Alex')
list_names = ['Nicholas', 'Michelle', 'Alex']
print(tuple_names.__sizeof__())
print(list_names.__sizeof__())
出力はリストの方がタプルよりサイズが大きいことを示している。
48
64
注:表示されるサイズはバイト数です。
ホモジニアス vs ヘテロジニアス
タプルは通常、異なるデータ型に属する要素である異種要素を格納するために使用されます。一方、リストは、通常、同じデータ型に属する要素である同種の要素を格納するために使用されます。
注:これは意味上の違いに過ぎない。どちらのデータ型も異種であるが、規約が異なる。同じ型の要素はタプルに、異なる型の要素はリストに格納することができます。
以下のコードは、リストに文字列と数値が混在しているにもかかわらず、エラーなく実行されます。
list_elements = ['Nicholas', 10, 'Alex']
tuple_elements = ('Nicholas', "Michelle", 'Alex')
可変長と固定長の比較
タプルは固定長であるのに対し、リストは可変長である。つまり、作成したリストのサイズは変更できるが、既存のタプルのサイズを変更することはできない。
list_names = ['Nicholas', 'Michelle', 'Alex']
list_names.append("Mercy")
print(list_names)
出力は、リストに4番目の名前が追加されたことを示している。
['Nicholas', 'Michelle', 'Alex', 'Mercy']
これはPythonの append()
メソッドを使用したものです。同じことを insert()
メソッドで実現することもできました。
list_names = ['Nicholas', 'Michelle', 'Alex']
list_names.insert(3, "Mercy")
print(list_names)
出力は再び、リストに4番目の要素が追加されたことを示しています。
['Nicholas', 'Michelle', 'Alex', 'Mercy']
Pythonのタプルはそのサイズを変更する方法を提供してくれません。
結論
リストとタプルはどちらもPythonのデータ構造ですが、両者の間には顕著な違いがあります。主な違いは、リストがmutableであるのに対し、タプルはimmutableであるということです。リストは可変サイズであるのに対して、タプルは固定サイズです。タプルに対する操作は、リストに対する操作に比べて高速に実行することができます。
#7> </module