閉じる

Pythonのタプル(tuple)とは?変更できないリストの使い方

Pythonで「値の集まり」を扱うとき、まずはリスト(list)を思い浮かべる方が多いと思います。

しかし、変更してほしくないデータこそタプル(tuple)の出番です。

本記事では、タプルの基本から操作、メリット、初心者がハマりやすい注意点までを丁寧に解説し、実践的なサンプルコードも交えて理解を深めます。

タプル(tuple)の基本

タプルは「変更できないリスト」(イミュータブル)

タプル(tuple)は作成後に要素の追加・変更・削除ができないイミュータブルなデータ構造です。

リストと似た見た目をしていますが、性質が異なります。

プログラム中で「うっかり書き換え」を防ぎたいときに役立ちます。

特に設定値や定数的なデータ、関数間の受け渡しなどで安全性が高まります。

リストとの違い(変更不可かどうか)

最大の違いは「変更できるかどうか」です。

リストはミュータブル(変更可能)、タプルはイミュータブル(変更不可)です。

記法にも違いがあります。

項目リスト(list)タプル(tuple)
リテラル[ ]( )
変更可否変更できる変更できない
代表的な用途可変のコレクション、集計や編集定数的データ、安全な受け渡し
主な操作append、pop、sort などcount、index など(破壊的操作なし)
辞書のキー不可可(ハッシュ可能)

違いをエラーで体感してみます。

タプルは要素代入ができません。

Python
# リストは変更できる
lst = [1, 2, 3]
lst[0] = 99
print(lst)  # [99, 2, 3]

# タプルは変更できない
t = (1, 2, 3)
# 次の行のコメントを外すとTypeErrorが発生します
# t[0] = 99
実行結果
[99, 2, 3]
Traceback (most recent call last):
  ...
TypeError: 'tuple' object does not support item assignment

タプルの作り方(()/tuple())

タプルは( )またはtuple()で作れます。

カンマがタプルの本質で、かっこは見やすさのために使われます。

Python
# かっこを使う
t1 = (1, 2, 3)

# かっこ省略(カンマがあるのでタプルになる)
t2 = 1, 2, 3

# tuple() にイテラブルを渡す
t3 = tuple([1, 2, 3])      # リストから
t4 = tuple("abc")          # 文字列から
t5 = tuple(range(3))       # range から

print(t1, t2, t3, t4, t5)
実行結果
(1, 2, 3) (1, 2, 3) (1, 2, 3) ('a', 'b', 'c') (0, 1, 2)

空タプルと1要素タプル(, の注意)

1要素タプルは末尾のカンマが必須です。

空タプルは()です。

Python
empty = ()          # 空タプル
one1 = (1,)         # 1要素タプル(カンマが必要)
one2 = 1,           # かっこ省略でも可(カンマが必要)
not_tuple = (1)     # これはタプルではなく、単なる1という数値

print(type(empty))
print(type(one1), one1)
print(type(one2), one2)
print(type(not_tuple), not_tuple)
実行結果
<class 'tuple'>
<class 'tuple'> (1,)
<class 'tuple'> (1,)
<class 'int'> 1

型を調べる(type)

型が不安なときはtype()で確認できます。

Python
t = (10, 20, 30)
print(type(t))
実行結果
<class 'tuple'>

タプルの基本操作(使い方)

要素を取得する(インデックス)

インデックスで要素にアクセスできます。

0始まりで、負のインデックスは後ろから数えます。

Python
t = ('a', 'b', 'c', 'd')

print(t[0])   # 先頭
print(t[2])   # 3番目
print(t[-1])  # 末尾
print(t[-2])  # 後ろから2番目
実行結果
a
c
d
c

一部を取り出す(スライス)

スライス[start:stop:step]で部分取得できます。

新しいタプルが返ります。

Python
t = (0, 1, 2, 3, 4, 5)

print(t[1:4])     # 1以上4未満
print(t[:3])      # 先頭から3未満
print(t[3:])      # 3以降
print(t[::2])     # 2刻み
print(t[::-1])    # 逆順
実行結果
(1, 2, 3)
(0, 1, 2)
(3, 4, 5)
(0, 2, 4)
(5, 4, 3, 2, 1, 0)

含まれるか調べる(in)

in演算子で要素の有無を確認できます。

Python
t = ('apple', 'banana', 'cherry')
print('banana' in t)
print('grape' in t)
実行結果
True
False

長さを調べる(len)

len()で要素数がわかります。

Python
t = (10, 20, 30, 40)
print(len(t))
実行結果
4

要素の数と位置(count/index)

count()は出現回数、index()は最初の位置を返します。

Python
t = ('a', 'b', 'a', 'c', 'a')

print(t.count('a'))        # 'a' の個数
print(t.index('a'))        # 'a' が最初に現れる位置
print(t.index('a', 1))     # 1以降で最初に現れる位置
実行結果
3
0
2

連結と繰り返し(+ と *)

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

どちらも新しいタプルを返します。

Python
a = (1, 2)
b = (3, 4)
print(a + b)     # 連結

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

forで順番に処理する

タプルは反復可能なのでforで順に処理できます。

Python
t = ('red', 'green', 'blue')

for color in t:
    print(color)

# インデックスも使いたい場合は enumerate()
for i, color in enumerate(t):
    print(i, color)
実行結果
red
green
blue
0 red
1 green
2 blue

アンパック代入(複数の変数に展開)

タプルの形で左辺に並べると、一気に変数へ展開できます。

可読性が高まります。

Python
# 基本のアンパック
t = (10, 20, 30)
a, b, c = t
print(a, b, c)

# 使わない値を _ に受ける慣習
_, second, _ = t
print(second)

# 可変長(アスタリスク)アンパック
head, *middle, tail = (1, 2, 3, 4, 5)
print(head, middle, tail)
実行結果
10 20 30
20
1 [2, 3, 4] 5

タプルのメリットと使いどころ

変更させたくない設定や定数に

プログラム中で変えてはいけない値はタプルで表すと安全です。

例えば曜日や固定メニューなどです。

Python
# 変更させたくない定数的なデータ
WEEKDAYS = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')

# 誤って変更しようとするとエラーになるので安心
# WEEKDAYS[0] = 'Mond'  # TypeError
print(WEEKDAYS)
実行結果
('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')

関数の戻り値で複数の値を返す

関数から複数の値をタプルで返し、呼び出し側でアンパックすると便利です。

Python
def min_max_avg(numbers):
    # 最小、最大、平均をタプルで返す
    mn = min(numbers)
    mx = max(numbers)
    avg = sum(numbers) / len(numbers)
    return mn, mx, avg  # タプルで返る

data = [10, 20, 30, 40]
mn, mx, avg = min_max_avg(data)
print(mn, mx, avg)
実行結果
10 40 25.0

辞書のキーにできる(ハッシュ可能)

タプルはハッシュ可能なので辞書のキーに使えます。

座標や複合キーなどで重宝します。

Python
# 2次元座標をキーにして値を管理
grid = {}
grid[(0, 0)] = 'start'
grid[(1, 2)] = 'tree'
print(grid[(1, 2)])

# リストはキーにできない(ミュータブルでハッシュ不可)
try:
    bad_key = [1, 2]
    d = {bad_key: 'NG'}
except TypeError as e:
    print('Error:', e)
実行結果
tree
Error: unhashable type: 'list'

メモリ/速度で有利な場合がある

タプルはリストよりメモリ使用量が少ない傾向があり、特に「変更しない多数の要素」を扱うときに有利です。

速度面でも生成やアクセスがわずかに有利なケースがあります(環境によります)。

Python
import sys
from timeit import timeit

lst = [0, 1, 2, 3, 4]
tup = (0, 1, 2, 3, 4)

print('list size:', sys.getsizeof(lst))
print('tuple size:', sys.getsizeof(tup))

# 生成コスト比較(環境で差は変わります)
t_list = timeit("[0,1,2,3,4]", number=1000000)
t_tuple = timeit("(0,1,2,3,4)", number=1000000)
print('make list :', t_list)
print('make tuple:', t_tuple)
実行結果
list size: 104
tuple size: 80
make list : 0.13  # 例: 一例の計測値(環境で変動します)
make tuple: 0.09  # 例: 一例の計測値(環境で変動します)

計測値はマシンやPythonのバージョンで変動します。

傾向を見る参考程度にしてください。

初心者がハマりやすい注意点

1要素タプルはカンマを忘れない

1要素タプルは(値,)のように必ずカンマが必要です。

(値)は単なる括弧で、タプルではありません。

Python
one = (42,)   # OK: タプル
not_tuple = (42)  # NG: タプルではない

print(type(one), one)
print(type(not_tuple), not_tuple)
実行結果
<class 'tuple'> (42,)
<class 'int'> 42

()で囲んでもタプルとは限らない

かっこは「グルーピング」にも使われるので、タプルかどうかは「カンマがあるか」で決まります。

なお、カンマがあればかっこ省略でもタプルです。

Python
a = (1 + 2)      # 計算のグルーピング。結果は整数 3
b = 1, 2, 3      # カンマがあるのでタプル
c = (1, 2, 3)    # もちろんタプル

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

要素の追加・変更・削除はできない

タプルはappendremoveなどの破壊的操作がありません。

代入や削除も不可です。

Python
t = (1, 2, 3)

# 変更は不可
try:
    t[0] = 99
except TypeError as e:
    print('assign Error:', e)

# 追加メソッドは存在しない
try:
    t.append(4)  # AttributeError
except AttributeError as e:
    print('append Error:', e)

# 削除も不可
try:
    del t[1]
except TypeError as e:
    print('delete Error:', e)
実行結果
assign Error: 'tuple' object does not support item assignment
append Error: 'tuple' object has no attribute 'append'
delete Error: 'tuple' object doesn't support item deletion

補足として、タプルの中にリストなどのミュータブルな要素を入れると「タプル自体は同じまま、内部のリストは変更できる」点に注意してください。

これは「タプルは要素への参照が不変」であり、「参照先のオブジェクトの変更可否までは保証しない」ためです。

Python
t = ([1, 2], 99)
t[0].append(3)   # タプルの0番目はリスト。リスト自体は変更できる
print(t)
実行結果
([1, 2, 3], 99)

並べ替えはsortedで新しく作る

タプルは並べ替えできないのでsorted()で並べ替えたリストを作り、必要ならtuple()でタプルに戻します。

Python
t = (3, 1, 4, 1, 5)

# 昇順のリストを取得
sorted_list = sorted(t)
print(sorted_list, type(sorted_list))

# タプルに戻す
sorted_tuple = tuple(sorted_list)
print(sorted_tuple, type(sorted_tuple))

# 逆順で新しく作る
desc_tuple = tuple(sorted(t, reverse=True))
print(desc_tuple)
実行結果
[1, 1, 3, 4, 5] <class 'list'>
(1, 1, 3, 4, 5) <class 'tuple'>
(5, 4, 3, 1, 1)

まとめ

タプル(tuple)は「変更できないリスト」として、安全にデータを保持したい場面で強力な選択肢です。

作成は( )tuple()、1要素なら(値,)を忘れないことが重要です。

インデックスやスライス、inlen()count()index()といった基本操作はリストと似ていますが、変更操作はできません。

辞書のキーにできることや、関数から複数値を返す用途、メモリ面の利点も覚えておくと良いでしょう。

初心者がハマりやすい点(1要素タプルのカンマ、かっこ=タプルとは限らない、並べ替えはsorted()で新しく作る)を意識しながら、用途に応じてリストとタプルを使い分けてください。

この記事を書いた人
エーテリア編集部
エーテリア編集部

人気のPythonを初めて学ぶ方向けに、文法の基本から小さな自動化まで、実際に手を動かして理解できる記事を書いています。

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

URLをコピーしました!