この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:5
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: タプルの作成
SEOタイトル: Pythonタプル作成完全ガイド(単一要素/unpacking/namedtuple/辞書キー)

この記事の要点
  • タプル(1, 2, 3) または 1, 2, 3 で作る不変シーケンス
  • 単一要素タプル(1,) のように末尾カンマ必須。(1) はただの int
  • tuple() でリスト/iterable から変換: tuple([1, 2, 3])
  • アンパック: a, b = (1, 2) / 拡張 a, *rest = (1, 2, 3, 4)
  • namedtuple / typing.NamedTuple で名前付きフィールド + 型ヒント
  • タプルは immutable なので辞書のキー・集合の要素・関数引数のデフォルト値に使える
  • 比較は要素ごとに辞書順: (1, 2) < (1, 3) は True

タプルとは

タプル(tuple)は順序を持つ不変なシーケンスです。リストとほぼ同じく使えますが、作成後に要素を変更できません。括弧 () で表記しますが、本質的にはカンマで区切ることで作られます。

# 基本: 括弧で囲む
t1 = (1, 2, 3)

# 実は括弧は必須ではない(カンマがタプルを作る)
t2 = 1, 2, 3
print(type(t2))  # 

# 空タプル
t3 = ()
t4 = tuple()

単一要素タプルの罠

1 要素のタプルは 末尾カンマが必須です。これは初学者が最も間違えるポイント:

# ❌ これは int の 1(タプルではない)
x = (1)
print(type(x))  # 

# ✅ 末尾カンマで単一要素タプル
y = (1,)
print(type(y))  # 

# ✅ 括弧不要でも OK
z = 1,
print(type(z))  # 

# 文字列でも同様
s1 = ('hello')    # str
s2 = ('hello',)   # tuple

tuple() で iterable から変換

# リストから
tuple([1, 2, 3])         # (1, 2, 3)

# 文字列から(文字単位に分解)
tuple("abc")             # ('a', 'b', 'c')

# range から
tuple(range(5))          # (0, 1, 2, 3, 4)

# ジェネレータから
tuple(x * 2 for x in range(3))  # (0, 2, 4)

# 辞書から(キーのみ)
tuple({'a': 1, 'b': 2})  # ('a', 'b')

# 辞書から(items)
tuple({'a': 1, 'b': 2}.items())  # (('a', 1), ('b', 2))

アンパック(unpacking)

タプルは複数代入と同時に分解できます。Python の慣用句として広く使われます。

# 基本のアンパック
a, b = (1, 2)
print(a, b)  # 1 2

# 入れ子もOK
(a, b), c = (1, 2), 3

# スワップ
a, b = b, a

# 関数の複数戻り値
def divmod_(a, b):
    return a // b, a % b   # タプルが返る

q, r = divmod_(17, 5)      # 自動的にアンパック

# 拡張アンパック(PEP 3132、Python 3+)
first, *rest = (1, 2, 3, 4, 5)
# first=1, rest=[2, 3, 4, 5]

first, *middle, last = (1, 2, 3, 4, 5)
# first=1, middle=[2, 3, 4], last=5

# 値を捨てる
_, value = ('key', 100)

namedtuple / NamedTuple

位置だけでなく名前でアクセスしたいときに使います。データクラスより軽量、辞書よりタイプセーフ。

# 方法1: collections.namedtuple
from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])

p = Point(1, 2)
print(p.x, p.y)       # 1 2
print(p[0], p[1])     # 1 2  (位置でも OK)

# 方法2: typing.NamedTuple(型ヒント付き、3.6+)
from typing import NamedTuple

class User(NamedTuple):
    name: str
    age: int
    email: str = ""   # デフォルト値もOK

    def is_adult(self) -> bool:    # メソッドも定義可
        return self.age >= 18

u = User(name="Alice", age=30)
print(u.is_adult())   # True

# unpacking
name, age, email = u

辞書のキー・集合の要素になれる

タプルはハッシュ可能(immutable)なので、辞書のキーや集合の要素として使えます。リストは使えません。

# 座標をキーにしたグリッド
grid = {}
grid[(0, 0)] = "start"
grid[(1, 2)] = "treasure"

# 集合
visited = set()
visited.add((0, 0))
visited.add((1, 2))

# ❌ リストはハッシュ不可
# d = {[1, 2]: "x"}  # TypeError: unhashable type: 'list'

# 注意: タプル内に list があるとハッシュ不可になる
hash((1, 2, 3))         # OK
hash((1, [2, 3]))       # TypeError

タプル同士の比較

タプル同士は辞書順で比較されます。最初の要素で決着がつけばそこで決定、同じなら次の要素を見ます。

(1, 2) < (1, 3)    # True  (2 < 3)
(1, 2) < (2, 0)    # True  (1 < 2)
(1, 2, 3) < (1, 2) # False (前者の方が長い)
(1, 2) == (1, 2)   # True

# ソートで便利
people = [("Alice", 30), ("Bob", 25), ("Carol", 30)]
people.sort()
# [('Alice', 30), ('Bob', 25), ('Carol', 30)]
# → 名前優先、同名なら年齢順

# 第二キーで降順したい時
people.sort(key=lambda p: (p[1], p[0]))

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

用途推奨
異なる種類の要素のまとまり (record 的)タプル / namedtuple
同種要素の集まり(後から追加削除)リスト
関数の複数戻り値タプル
辞書のキー・集合の要素タプル必須
関数のデフォルト引数で空コレクションタプル(mutable default の罠回避)

FAQ

Q: タプルとリストどっちが速い?
A: 微妙にタプルの方が高速・小メモリですが、現代の Python では誤差レベル。意味で選ぶべきです。

Q: タプルの要素を変更したい
A: 不可能。list(t) で一旦リスト化 → 変更 → tuple(...) で戻すか、新しいタプルを作ります。

Q: 関数の引数のデフォルト値に空リストはなぜダメ?
A: ミュータブル既定値の罠。def f(x=[]) は呼び出し間で共有されます。def f(x=()) または def f(x=None): x = x or [] を使ってください。