Pythonのタプルは、リストとよく似ていますが「変更できない」という重要な特徴を持っています。
この性質のおかげで、バグを防いだり、辞書のキーに使えたりと、実務で役立つ場面が多くあります。
本記事では、タプルの基本から実用的な使い方、リストとの違いと使い分けまで、図解とサンプルコードを交えながら詳しく解説します。
タプルとは
タプル(tuple)の基本と特徴

タプル(tuple)とは、複数の値をひとまとめにして扱うための、順序付きのデータ構造です。
Pythonでは( )(丸カッコ)とカンマ,で表現します。
リストと似ていますが、一度作ったら中身を変更できない(イミュータブル)という大きな特徴があります。
タプルの基本的な性質
文章で整理すると、タプルは次のような性質を持ちます。
- 要素には順序があります(インデックスでアクセス可能)
- 要素の型はバラバラで構いません
- いったん作成した後で、要素の追加・削除・変更ができません
- for文などで反復処理ができます
代表的なタプルの例は次のようになります。
# 整数だけのタプル
numbers = (1, 2, 3)
# 型が混ざったタプル
person = ("Taro", 25, "Tokyo")
# 空のタプル
empty = ()
タプルはリストと同じように見えますが、「変更できるかどうか」という点が決定的に異なります。
タプルとリスト(list)の違い

タプルとリストの違いを、文章で押さえておきます。
どちらも「複数の要素を順序付きで並べる」という点は同じですが、次のような違いがあります。
- リスト(list)
- 変更可能(ミュータブル)
- 角カッコ[ ]で表現
- 要素の追加・削除・変更が可能
- タプル(tuple)
- 変更不可(イミュータブル)
- 丸カッコ( )で表現
- 一度作ったら中身を変えられない
次のコードで違いを体験してみます。
# リストは変更できる
lst = [1, 2, 3]
lst[0] = 100 # OK
lst.append(4) # OK
print("list:", lst)
# タプルは変更できない
tpl = (1, 2, 3)
# tpl[0] = 100 # エラーになるコード(コメントアウト)
print("tuple:", tpl)
list: [100, 2, 3, 4]
tuple: (1, 2, 3)
タプル側でtpl[0] = 100を有効にすると、TypeError: 'tuple' object does not support item assignmentのようなエラーが出ます。
タプルが便利なシーン

タプルが特に便利になる代表的なシーンを挙げます。
1つ目は、辞書のキーにしたいときです。
リストは変更できるためキーにできませんが、タプルは変更できないのでキーにできます。
2つ目は、関数から複数の値を返すときです。
合計と平均、位置と速度のように、関連する複数の値を1セットで返す場面で、タプルは自然な選択になります。
3つ目は、「変わっては困る値の集合」を表したいときです。
ゲームの初期設定、画像サイズ、座標、定数の一覧など、誤って書き換えたくないものをタプルにしておくと安心です。
タプルの作り方と基本操作
タプルの作成方法と書き方

タプルの作り方にはいくつかのパターンがあります。
丸カッコを使う基本的な書き方
numbers = (1, 2, 3)
colors = ("red", "green", "blue")
print(numbers)
print(colors)
(1, 2, 3)
('red', 'green', 'blue')
丸カッコを省略した書き方
Pythonでは、カンマで区切るだけでタプルとみなされます。
丸カッコは省略可能です。
numbers = 1, 2, 3 # (1, 2, 3) と同じ
print(numbers)
print(type(numbers)) # 型を確認
(1, 2, 3)
<class 'tuple'>
1要素だけのタプルの注意点
1要素だけのタプルには注意が必要です。
丸カッコだけではタプルにならず、カンマが必要です。
a = (1) # これは整数
b = (1,) # これはタプル
print(a, type(a))
print(b, type(b))
1 <class 'int'>
(1,) <class 'tuple'>
このように、1要素タプルは(1,)のように末尾のカンマが必須です。
要素の取得とインデックス指定

タプルの要素は、リストと同じようにインデックスで取得できます。
インデックスは0から始まります。
data = ("apple", "banana", "cherry")
print(data[0]) # 先頭の要素
print(data[1]) # 2番目の要素
print(data[2]) # 3番目の要素
apple
banana
cherry
負のインデックスを使うと、後ろから数えることもできます。
print(data[-1]) # 最後の要素
print(data[-2]) # 後ろから2番目
cherry
banana
スライスでタプルの一部を取り出す

タプルはスライス構文で一部を切り出すことができます。
nums = (0, 1, 2, 3, 4, 5)
print(nums[1:4]) # インデックス1〜3まで
print(nums[:3]) # 先頭〜インデックス2まで
print(nums[3:]) # インデックス3〜最後まで
print(nums[:]) # 全体のコピー
(1, 2, 3)
(0, 1, 2)
(3, 4, 5)
(0, 1, 2, 3, 4, 5)
スライスの結果もタプルになる点がポイントです。
スライス自体は新しいタプルを作成するので、元のタプルは変更されません。
タプルの長さ(len)の確認

タプルの要素数はlen()で取得します。
items = ("a", "b", "c", "d")
print(len(items))
4
len()はリスト・文字列などでも同様に使える共通の関数ですので、覚えておくと便利です。
タプル同士の連結と繰り返し

タプル同士は+で連結、*で繰り返しができます。
いずれも新しいタプルを生成します。
a = (1, 2)
b = (3, 4)
# 連結
c = a + b
print(c)
# 繰り返し
d = ("x",) * 3
print(d)
(1, 2, 3, 4)
('x', 'x', 'x')
もとのaやbは変更されていない点が、リストの「破壊的操作」との違いです。
in演算子で要素の存在を確認

in演算子を使えば、特定の値がタプル内に存在するかを調べられます。
colors = ("red", "green", "blue")
print("red" in colors) # 含まれているか
print("yellow" in colors) # 含まれていない場合
True
False
条件分岐と組み合わせることで、「許可された値かどうか」を安全に判定する用途に向いています。
タプルとリストの違いと使い分け
変更不可(イミュータブル)とは何か

イミュータブル(immutable)とは「変更できない」性質のことです。
タプルはイミュータブルなので、次のような操作はできません。
- 要素の値を書き換える
- 要素を追加する
- 要素を削除する
一方で、タプル自体を別のタプルで置き換えることは可能です。
tpl = (1, 2, 3)
# tpl[0] = 100 # これはエラー
# 代わりに、新しいタプルを作って代入し直す
tpl = (100,) + tpl[1:]
print(tpl)
(100, 2, 3)
このように、タプルの「中身」は変えられませんが、「変数に別のタプルを代入し直す」ことはできます。
パフォーマンスとメモリの違い
タプルとリストは、内部表現が少し異なります。
一般的に、タプルの方が「変更されない」前提で設計されているため、やや軽量です。
実際の差は小さいケースが多いですが、概ね次のような傾向があります。
- タプルはリストよりメモリ使用量が少ないことが多い
- 要素数が固定で頻繁に変更しないならタプルが向いている
- パフォーマンスクリティカルなコードでは、イミュータブルなデータ構造の方が最適化されやすい
ただし、可読性や安全性の方が重要なので、「どちらが軽いか」だけで選ぶより「意味的にどちらがふさわしいか」で選ぶ方が良いです。
辞書のキーにタプルを使える理由

Pythonの辞書のキーには、ハッシュ可能(変更されない)なオブジェクトしか使えません。
タプルはイミュータブルなのでハッシュ可能であり、キーとして利用できます。
# 緯度・経度をキーにして場所名を保存
locations = {
(35.0, 135.0): "Kyoto",
(35.7, 139.7): "Tokyo",
}
print(locations[(35.0, 135.0)])
Kyoto
同じことをリストでやろうとするとエラーになります。
# これはエラーになる例
# locations = {
# [35.0, 135.0]: "Kyoto", # TypeError: unhashable type: 'list'
# }
「値が変わらない」=「キーとして安心して使える」という関係を押さえておくと、設計の判断がしやすくなります。
関数の戻り値にタプルを使うパターン

関数から複数の値を返したいとき、タプルは非常に便利です。
Pythonでは、カンマ区切りで複数値を返すと自動的にタプルになるためです。
def calc_sum_and_avg(values):
total = sum(values)
avg = total / len(values)
# 2つの値をまとめて返す(タプルになる)
return total, avg
result = calc_sum_and_avg([1, 2, 3, 4])
print(result)
print(type(result))
(10, 2.5)
<class 'tuple'>
呼び出し側では、アンパック(後述)を使って受け取ることが多いです。
total, avg = calc_sum_and_avg([1, 2, 3, 4])
print("total:", total)
print("avg:", avg)
total: 10
avg: 2.5
タプルとリストの使い分けの目安

使い分けの指針を文章でまとめると、次のようになります。
タプルを選ぶと良い場面
- 「作った後に中身を変える必要がない」集合
- 座標やサイズ、設定値などの「ひとまとまりの固定値」
- 関数の戻り値として関連する複数の値をまとめたいとき
- 辞書のキーや集合(set)の要素にしたいとき
リストを選ぶと良い場面
- 要素を追加・削除・並べ替えたい
- ユーザー入力などで要素数が変動する
- 後から編集しながら積み上げていくデータ
「後から変える可能性があるならリスト、変わっては困るならタプル」が、実務的に分かりやすい基準です。
タプル活用の実用例
複数代入・アンパックでコードを簡潔にする
[図解作成の指示]
- 左にタプル (x, y) = (10, 20) の図
- 右に「x → 10」「y → 20」と矢印で変数に割り当てられている様子
タプルは複数の変数への同時代入(アンパック)と相性が良いです。
Pythonでは、次のような書き方が可能です。
# タプルを使った複数代入
point = (10, 20)
x, y = point # アンパック
print("x =", x)
print("y =", y)
x = 10
y = 20
一時変数なしで値を入れ替えることもできます。
a = 1
b = 2
# タプルを使った値の入れ替え
a, b = b, a
print("a =", a)
print("b =", b)
a = 2
b = 1
タプルのアンパックは、可読性が高くエラーも少なくなる書き方なので、積極的に使われます。
enumerateやzipでタプルが返る理由

ビルトイン関数enumerateやzipを使うと、イテレーション時にタプルのペア(や複数値)が返ってきます。
fruits = ["apple", "banana", "cherry"]
for i, name in enumerate(fruits):
print(i, name)
0 apple
1 banana
2 cherry
内部的には、(インデックス, 要素)という2要素のタプルが1つずつ返され、それをi, name = ...の形でアンパックしています。
zipも同様です。
xs = [1, 2, 3]
ys = [4, 5, 6]
for x, y in zip(xs, ys):
print(x, y)
1 4
2 5
3 6
ここでも、(x, y)というタプルが返され、それを2変数に展開しています。
「固定個数の関連する値の束」を返したいときにタプルが使われる典型例です。
座標や設定値をタプルで表現する例

ゲーム開発やGUIプログラミングでは、座標やサイズなどをタプルで表現することがよくあります。
# 2D座標
position = (100, 200)
# 幅と高さ
window_size = (800, 600)
# RGBカラー
white = (255, 255, 255)
print("position:", position)
print("window_size:", window_size)
print("white:", white)
position: (100, 200)
window_size: (800, 600)
white: (255, 255, 255)
このような値は「途中で変わると困る」ことが多いため、安全性の高いタプルで管理するのが自然です。
タプルを使った安全な定数定義

プログラム中の定数の集合をタプルで定義すると、誤って書き換えてしまうリスクを減らせます。
# ゲームの方向入力として許可する値をタプルで定義
DIRECTIONS = ("UP", "DOWN", "LEFT", "RIGHT")
# 許可された入力かどうかチェック
def is_valid_direction(value):
return value in DIRECTIONS
print(is_valid_direction("UP"))
print(is_valid_direction("JUMP"))
True
False
もしこれをリストで定義していた場合、どこかの処理でappendしてしまうなど、意図しない変更が発生し得ます。
タプルにしておけば、そうした事故をコンパイル時(正確には実行開始時)に防ぎやすくなります。
「これは絶対に変わらないべき値だ」と自分に、あるいは他人に伝える手段としてタプルを選ぶ、という使い方がとても有効です。
まとめ
タプルは、リストと似た「順序付きの複数要素」を扱う構造ですが、一度作ったら変更できないイミュータブルである点が最大の特徴です。
この性質のおかげで、辞書のキーに使えたり、定数や座標・設定値を安全に表現できたり、関数の戻り値やenumerate・zipなどと自然に組み合わせられます。
実務では、「変えるデータはリスト」「変えないデータはタプル」という基準を意識しながら使い分けることで、バグを減らしつつ読みやすいPythonコードを書けるようになります。
