Pythonでデータをまとめて扱う際によく使われる「リスト(list)」「タプル(tuple)」「セット(set)」。
一見似ているこれらのデータ型ですが、定義に使うカッコの記号 [] () {} や、変更可能性(ミュータブル/イミュータブル)、操作方法に明確な違いがあります。
適切なデータ型を選択することは、バグの防止やプログラムの処理速度向上に直結します。
本記事では、3つの違いからカッコ記号の扱い方、要素の追加・削除方法、実務での注意点までを網羅して解説します。
1. 基本的な違いとカッコ記号の一覧
まずは3つのデータ型の概要、使用するカッコ記号、特徴を表で比較してみましょう。
| データ型 | カッコ記号 | 定義例 | 順序保持 | 重複 | 変更可能性 | 主な用途 |
リスト (list) | 角カッコ [] | [1, 2, 3] | あり | 許可 | 可 (Mutable) | データの順序を保ち、頻繁に更新したい場合 |
タプル (tuple) | 丸カッコ () | (1, 2, 3) | あり | 許可 | 不可 (Immutable) | 変更されたくない固定データ(座標、設定値など) |
セット (set) | 波カッコ {} | {1, 2, 3} | なし | 不可 | 可 (Mutable) | 重複を排除したい場合、高速な検索・集合演算 |
2. カッコ記号 [] () {} に関する注意点
各データ型で使うカッコ記号には、Python特有の文法ルールや落とし穴があります。
- 角カッコ
[](リスト)a = []と書くことで空のリストを作成できます。
- 丸カッコ
()(タプル)- 1要素のタプルを作成する場合、カッコだけでなく必ず末尾にカンマが必要です(例:
a = (1,))。カンマがないa = (1)は単なる数値として扱われます。 a = ()と書くことで空のタプルを作成できます。
- 1要素のタプルを作成する場合、カッコだけでなく必ず末尾にカンマが必要です(例:
- 波カッコ
{}(セット)- 波カッコは辞書(dict)の定義にも使われます。そのため、
a = {}と書くと空の辞書になってしまいます。 - 空のセットを作成する場合は、必ず
a = set()と関数形式で記述する必要があります。
- 波カッコは辞書(dict)の定義にも使われます。そのため、
3. 要素の追加と削除方法の違い
データ型によってサポートされているメソッドや操作が異なります。
リスト (list) の操作
要素の順序が保持されるため、位置を指定した操作や末尾への追加が可能です。
- 追加
append(x): 末尾に1つの要素を追加insert(i, x): 指定したインデックス位置に挿入extend(iterable): 別のリストやイテラブルを結合
- 削除
remove(x): 最初に見つかった値xを削除(存在しない場合はValueError)pop([i]): 指定インデックス(デフォルトは末尾)の要素を取り出して削除clear(): すべての要素を削除
タプル (tuple) の操作
タプルはイミュータブル(不可変)であるため、標準機能として要素を追加・削除する専用のメソッドは用意されていません。
- 追加・削除を行いたい場合
- 基本的には変更不可ですが、一度
list()でリスト型に変換して追加・削除の操作を行い、再度tuple()に戻すといった手順を踏むことで実現自体は可能です。
- 基本的には変更不可ですが、一度
セット (set) の操作
セットは順序を持たないため、インデックス([0] など)での操作はできません。
- 追加
add(x): 1つの要素を追加(既に存在する場合は無視される)update(iterable): 複数の要素をまとめて追加
- 削除
remove(x): 値xを削除(存在しない場合は KeyError が発生)discard(x): 値xを削除(存在しなくてもエラーにならない)pop(): 任意の要素を1つ取り出して削除(順序がないため指定不可)
4. 実務での注意点とハマりポイント
1. タプルの要素書き換えエラー(TypeError)
タプルは一度作成すると要素の書き換え(代入)ができません。以下のように直接インデックスを指定して値を変更しようとすると、TypeError が発生します。
tuple_a = (1, 2, 3)
tuple_a[1] = 5 # TypeError: 'tuple' object does not support item assignment
print(tuple_a)値を変更したい可能性が事前にある場合は、タプルではなく最初からリスト [] を選択しましょう。
2. 存在しない要素の削除エラー(セット)
セットで要素を削除する際、remove() は要素が存在しないと KeyError を送出します。エラーを避けたい安全な削除を行う場合は discard() を使うのが鉄則です。
my_set = {1, 2, 3}
my_set.discard(99) # エラーにならず安全
# my_set.remove(99) # KeyError が発生する3. 要素の検索速度(パフォーマンスの差)
「特定の値が含まれているか(x in collection)」を判定する際、内部構造の違いにより処理速度に大きな差が出ます。
- リスト / タプル: $O(N)$(要素数に比例して検索時間が伸びる)
- セット: $O(1)$(ハッシュテーブルを使用しているため、要素数に関係なく一瞬で検索完了)
大量のデータから要素の存在確認を行う場合は、リストではなくセットを使用するべきです。
4. セットに追加できる要素の制限
セットの要素はハッシュ可能(Hashable)である必要があります。そのため、変更可能なデータ(リストや辞書、他のセット)をセットの要素にすることはできません。
# OK: 数値、文字列、タプルなどは格納可能
valid_set = {1, "hello", (1, 2)}
# NG: リストなどのミュータブルなオブジェクトは TypeError になる
# invalid_set = {[1, 2], [3, 4]} 5. まとめ:用途ごとの適切な選び方
- リスト
[]: データが変わる、順番が重要、重複を許容したいとき(標準的なデータ保持) - タプル
(): データを途中で変更されたくないとき(標準での追加・削除・書き換えは不可)、関数の複数の戻り値、辞書のキーとして使いたいとき - セット
{}: 重複を除外したいとき、高速に検索を行いたいとき、積集合や和集合などの集合演算を行いたいとき
カッコ記号の違いやイミュータブル性(変更不可)などの特性を正しく理解し、用途に応じて最適なデータ型を選択していきましょう。



コメント