閉じる

【Python】タプル入門:使い方・基本操作・リストとの違いを解説

Pythonのタプルは、リストとよく似ていますが「変更できない」という重要な特徴を持っています。

この性質のおかげで、バグを防いだり、辞書のキーに使えたりと、実務で役立つ場面が多くあります。

本記事では、タプルの基本から実用的な使い方、リストとの違いと使い分けまで、図解とサンプルコードを交えながら詳しく解説します。

タプルとは

タプル(tuple)の基本と特徴

タプル(tuple)とは、複数の値をひとまとめにして扱うための、順序付きのデータ構造です。

Pythonでは( )(丸カッコ)とカンマ,で表現します。

リストと似ていますが、一度作ったら中身を変更できない(イミュータブル)という大きな特徴があります。

タプルの基本的な性質

文章で整理すると、タプルは次のような性質を持ちます。

  • 要素には順序があります(インデックスでアクセス可能)
  • 要素の型はバラバラで構いません
  • いったん作成した後で、要素の追加・削除・変更ができません
  • for文などで反復処理ができます

代表的なタプルの例は次のようになります。

Python
# 整数だけのタプル
numbers = (1, 2, 3)

# 型が混ざったタプル
person = ("Taro", 25, "Tokyo")

# 空のタプル
empty = ()

タプルはリストと同じように見えますが、「変更できるかどうか」という点が決定的に異なります。

タプルとリスト(list)の違い

タプルとリストの違いを、文章で押さえておきます。

どちらも「複数の要素を順序付きで並べる」という点は同じですが、次のような違いがあります。

  • リスト(list)
    • 変更可能(ミュータブル)
    • 角カッコ[ ]で表現
    • 要素の追加・削除・変更が可能
  • タプル(tuple)
    • 変更不可(イミュータブル)
    • 丸カッコ( )で表現
    • 一度作ったら中身を変えられない

次のコードで違いを体験してみます。

Python
# リストは変更できる
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つ目は、「変わっては困る値の集合」を表したいときです。

ゲームの初期設定、画像サイズ、座標、定数の一覧など、誤って書き換えたくないものをタプルにしておくと安心です。

タプルの作り方と基本操作

タプルの作成方法と書き方

タプルの作り方にはいくつかのパターンがあります。

丸カッコを使う基本的な書き方

Python
numbers = (1, 2, 3)
colors = ("red", "green", "blue")

print(numbers)
print(colors)
実行結果
(1, 2, 3)
('red', 'green', 'blue')

丸カッコを省略した書き方

Pythonでは、カンマで区切るだけでタプルとみなされます。

丸カッコは省略可能です。

Python
numbers = 1, 2, 3         # (1, 2, 3) と同じ
print(numbers)
print(type(numbers))      # 型を確認
実行結果
(1, 2, 3)
<class 'tuple'>

1要素だけのタプルの注意点

1要素だけのタプルには注意が必要です。

丸カッコだけではタプルにならず、カンマが必要です。

Python
a = (1)      # これは整数
b = (1,)     # これはタプル

print(a, type(a))
print(b, type(b))
実行結果
1 <class 'int'>
(1,) <class 'tuple'>

このように、1要素タプルは(1,)のように末尾のカンマが必須です。

要素の取得とインデックス指定

タプルの要素は、リストと同じようにインデックスで取得できます。

インデックスは0から始まります。

Python
data = ("apple", "banana", "cherry")

print(data[0])   # 先頭の要素
print(data[1])   # 2番目の要素
print(data[2])   # 3番目の要素
実行結果
apple
banana
cherry

負のインデックスを使うと、後ろから数えることもできます。

Python
print(data[-1])  # 最後の要素
print(data[-2])  # 後ろから2番目
実行結果
cherry
banana

スライスでタプルの一部を取り出す

タプルはスライス構文で一部を切り出すことができます。

Python
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()で取得します。

Python
items = ("a", "b", "c", "d")

print(len(items))
実行結果
4

len()はリスト・文字列などでも同様に使える共通の関数ですので、覚えておくと便利です。

タプル同士の連結と繰り返し

タプル同士は+で連結、*で繰り返しができます。

いずれも新しいタプルを生成します。

Python
a = (1, 2)
b = (3, 4)

# 連結
c = a + b
print(c)

# 繰り返し
d = ("x",) * 3
print(d)
実行結果
(1, 2, 3, 4)
('x', 'x', 'x')

もとのabは変更されていない点が、リストの「破壊的操作」との違いです。

in演算子で要素の存在を確認

in演算子を使えば、特定の値がタプル内に存在するかを調べられます。

Python
colors = ("red", "green", "blue")

print("red" in colors)      # 含まれているか
print("yellow" in colors)   # 含まれていない場合
実行結果
True
False

条件分岐と組み合わせることで、「許可された値かどうか」を安全に判定する用途に向いています。

タプルとリストの違いと使い分け

変更不可(イミュータブル)とは何か

イミュータブル(immutable)とは「変更できない」性質のことです。

タプルはイミュータブルなので、次のような操作はできません。

  • 要素の値を書き換える
  • 要素を追加する
  • 要素を削除する

一方で、タプル自体を別のタプルで置き換えることは可能です。

Python
tpl = (1, 2, 3)

# tpl[0] = 100  # これはエラー

# 代わりに、新しいタプルを作って代入し直す
tpl = (100,) + tpl[1:]
print(tpl)
実行結果
(100, 2, 3)

このように、タプルの「中身」は変えられませんが、「変数に別のタプルを代入し直す」ことはできます

パフォーマンスとメモリの違い

タプルとリストは、内部表現が少し異なります。

一般的に、タプルの方が「変更されない」前提で設計されているため、やや軽量です。

実際の差は小さいケースが多いですが、概ね次のような傾向があります。

  • タプルはリストよりメモリ使用量が少ないことが多い
  • 要素数が固定で頻繁に変更しないならタプルが向いている
  • パフォーマンスクリティカルなコードでは、イミュータブルなデータ構造の方が最適化されやすい

ただし、可読性や安全性の方が重要なので、「どちらが軽いか」だけで選ぶより「意味的にどちらがふさわしいか」で選ぶ方が良いです。

辞書のキーにタプルを使える理由

Pythonの辞書のキーには、ハッシュ可能(変更されない)なオブジェクトしか使えません。

タプルはイミュータブルなのでハッシュ可能であり、キーとして利用できます。

Python
# 緯度・経度をキーにして場所名を保存
locations = {
    (35.0, 135.0): "Kyoto",
    (35.7, 139.7): "Tokyo",
}

print(locations[(35.0, 135.0)])
実行結果
Kyoto

同じことをリストでやろうとするとエラーになります。

Python
# これはエラーになる例
# locations = {
#     [35.0, 135.0]: "Kyoto",    # TypeError: unhashable type: 'list'
# }

「値が変わらない」=「キーとして安心して使える」という関係を押さえておくと、設計の判断がしやすくなります。

関数の戻り値にタプルを使うパターン

関数から複数の値を返したいとき、タプルは非常に便利です。

Pythonでは、カンマ区切りで複数値を返すと自動的にタプルになるためです。

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'>

呼び出し側では、アンパック(後述)を使って受け取ることが多いです。

Python
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では、次のような書き方が可能です。

Python
# タプルを使った複数代入
point = (10, 20)
x, y = point   # アンパック

print("x =", x)
print("y =", y)
実行結果
x = 10
y = 20

一時変数なしで値を入れ替えることもできます。

Python
a = 1
b = 2

# タプルを使った値の入れ替え
a, b = b, a

print("a =", a)
print("b =", b)
実行結果
a = 2
b = 1

タプルのアンパックは、可読性が高くエラーも少なくなる書き方なので、積極的に使われます。

enumerateやzipでタプルが返る理由

ビルトイン関数enumeratezipを使うと、イテレーション時にタプルのペア(や複数値)が返ってきます

Python
fruits = ["apple", "banana", "cherry"]

for i, name in enumerate(fruits):
    print(i, name)
実行結果
0 apple
1 banana
2 cherry

内部的には、(インデックス, 要素)という2要素のタプルが1つずつ返され、それをi, name = ...の形でアンパックしています。

zipも同様です。

Python
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プログラミングでは、座標やサイズなどをタプルで表現することがよくあります。

Python
# 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)

このような値は「途中で変わると困る」ことが多いため、安全性の高いタプルで管理するのが自然です。

タプルを使った安全な定数定義

プログラム中の定数の集合をタプルで定義すると、誤って書き換えてしまうリスクを減らせます。

Python
# ゲームの方向入力として許可する値をタプルで定義
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してしまうなど、意図しない変更が発生し得ます。

タプルにしておけば、そうした事故をコンパイル時(正確には実行開始時)に防ぎやすくなります。

「これは絶対に変わらないべき値だ」と自分に、あるいは他人に伝える手段としてタプルを選ぶ、という使い方がとても有効です。

まとめ

タプルは、リストと似た「順序付きの複数要素」を扱う構造ですが、一度作ったら変更できないイミュータブルである点が最大の特徴です。

この性質のおかげで、辞書のキーに使えたり、定数や座標・設定値を安全に表現できたり、関数の戻り値やenumeratezipなどと自然に組み合わせられます。

実務では、「変えるデータはリスト」「変えないデータはタプル」という基準を意識しながら使い分けることで、バグを減らしつつ読みやすいPythonコードを書けるようになります。

リスト・辞書・セット

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!