閉じる

Pythonのタプルのアンパッキングとは?使い方と実例10選

タプルのアンパッキング(複数の変数へ一度に代入するテクニック)は、Pythonコードを短く読みやすくする強力な文法です。

本記事では、基本から注意点、そして日常で使える実例10選まで、初心者の方にも分かりやすく丁寧に解説します。

読み終えるころには自然に使いこなせるはずです。

タプルのアンパッキングとは?

意味とメリット

タプルのアンパッキングとは、並んだ値を並んだ変数へ一度に割り当てる代入方法のことです

Pythonではこのスタイルを使うことで、コードが簡潔になり、意図も明確になります。

例えば、従来は変数に順番に代入していた処理が、アンパッキングなら1行で表現できます。

さらに可読性が高まるバグの混入を減らせるといった実利も大きいため、Pythonでのコーディング効率化に直結します。

なお「タプルのアンパッキング」と呼ばれますが、実際にはタプル以外のイテラブル(シーケンス)にも使えます

基本の書き方

いちばん基本の形は、左辺に変数を並べ、右辺に値を並べるというものです。

かっこは省略可能で、右辺がタプルでなくても同じ長さのシーケンスであれば代入できます。

Python
# 基本形の例1: タプルをほどいて2つの変数に代入
a, b = (10, 20)
print(a, b)  # 10 20

# 基本形の例2: 右辺の()は省略できる
x, y, z = 1, 2, 3
print(x, y, z)  # 1 2 3

# 基本形の例3: リストでもOK(シーケンスであればよい)
r, g, b = [255, 128, 64]
print(r, g, b)  # 255 128 64
実行結果
10 20
1 2 3
255 128 64

左右の要素数が一致していることが基本ルールです。

詳細は後述の注意点を参照してください。

タプル以外のシーケンスにも使える

アンパッキングはliststrrangezipなどのイテラブルにも使えます。

文字列は1文字ずつに分解されるため、短いケースに限り便利です。

長すぎる場合はエラーや過剰な代入になるため注意しましょう。

以下は対応の一例です。

対象補足
タプル(tuple)a, b = (1, 2)もっとも基本
リスト(list)x, y = [10, 20]シーケンスならOK
文字列(str)c1, c2 = "Hi"文字ごとに分解
rangep, q, r = range(3)0,1,2を受け取る
zipの結果for a, b in zip(L1, L2)2要素タプルを展開
enumerateの結果for i, v in enumerate(L)(index, value)
dict.itemsfor k, v in d.items()(key, value)
ジェネレータa, b, c = gen()イテラブルなら可能だが消費に注意

実例を見てみます。

Python
# 文字列のアンパッキング
c1, c2 = "OK"
print(c1, c2)  # O K

# rangeで3要素を受け取る
u, v, w = range(3)
print(u, v, w)  # 0 1 2

# zipをforループで展開する
for left, right in zip([1, 2], ["a", "b"]):
    print(left, right)
実行結果
O K
0 1 2
1 a
2 b

イテラブルの長さと左辺の変数数の整合性が重要です。

合わない場合はエラーになるため、次章の*付きアンパッキングを活用しましょう。

タプルのアンパッキングの使い方と注意点

要素数は左右をそろえる

基本のアンパッキングでは、左辺の変数数と右辺の要素数が一致している必要があります

一致しない場合、ValueErrorが発生します。

Python
# 要素が3つあるのに、左辺が2つしかない
a, b = [1, 2, 3]  # これはエラー
実行結果
Traceback (most recent call last):
  ...
ValueError: too many values to unpack (expected 2)

修正するには、*付きアンパッキングで残りをまとめるか、値の数を合わせるようにしましょう。

*付きアンパッキングで残りをまとめる

Python 3では、を付けた変数に「残りの要素」をまとめて受け取れます(PEP 3132)。

この変数には必ずリストが入ります。

左辺にを使えるのは1つだけです。

Python
# 先頭と残りを受け取る
first, *rest = [10, 20, 30, 40]
print(first)  # 10
print(rest)   # [20, 30, 40]

# 先頭・末尾を取りつつ、中間はまとめて受け取る
head, *middle, tail = (1, 2, 3, 4, 5)
print(head, middle, tail)  # 1 [2, 3, 4] 5

# 要素が少なくても動く(空リストになる)
x, *xs = [99]
print(x, xs)  # 99 []
実行結果
10
[20, 30, 40]
1 [2, 3, 4] 5
99 []

不要な値は_で捨てる

使わない値はアンダースコア_に代入して捨てるのが慣習です(PEP 8でも示唆)。

複数捨てるときは_を繰り返しても構いませんが、読みやすさのために_, _程度に留めましょう。

Python
# 2つめの値は使わない
user_id, _ = (42, "ignore")
print(user_id)  # 42

# 先頭だけ使い、残りは捨てる
first, *_ = [1, 2, 3, 4]
print(first)  # 1
実行結果
42
1

「捨てる」という意思表示ができ、読み手に優しいコードになります。

ネストしたタプルをほどく

アンパッキングは入れ子の構造にも使えます。

左辺の構造を右辺の構造に合わせるのがコツです。

Python
# ネストした構造を1度に展開する
(x, (y1, y2)) = (10, (20, 30))
print(x, y1, y2)  # 10 20 30

# forループでのネスト展開
pairs = [(1, (2, 3)), (4, (5, 6))]
for a, (b, c) in pairs:
    print(a, b, c)
実行結果
10 20 30
1 2 3
4 5 6

つまずきやすいエラー例

初心者が遭遇しやすいエラーと対処をまとめます。

Python
# 1) 数が合わない
a, b = [1, 2, 3]  # ValueError

# 2) *を2つ以上使う(左辺) -> 構文エラー
*a, *b, c = [1, 2, 3, 4]  # SyntaxError

# 3) アンパックできない値(非イテラブル) -> 型エラー
x, y = 10  # TypeError

# 4) dictをそのままアンパック -> キーのみが対象
d = {"k1": 1, "k2": 2}
k1, k2 = d  # 'k1', 'k2'が入る。値は入らない点に注意
実行結果
Traceback (most recent call last):
  ...
ValueError: too many values to unpack (expected 2)

  File "<stdin>", line 2
SyntaxError: two starred expressions in assignment

Traceback (most recent call last):
  ...
TypeError: cannot unpack non-iterable int object

「数を合わせる」「*は1つ」「右辺はイテラブル」の3点を覚えておけば、ほとんどのエラーを避けられます。

タプルのアンパッキング 実例10選

同時代入で変数を初期化する

複数の初期値を1行で代入できます。

意図が一目で分かり、後から読む人にも優しい書き方です。

Python
# 3つの変数を同時に初期化
width, height, depth = 1920, 1080, 32
print(width, height, depth)

# 同じ値を代入したい場合のイディオム
x = y = z = 0  # これはアンパッキングではないが、初期化でよく使う
print(x, y, z)
実行結果
1920 1080 32
0 0 0

値の入れ替えを1行で行う

一時変数なしでスワップできます。

Pythonらしい書き方で、もっとも有名なユースケースです。

Python
a, b = 1, 2
a, b = b, a  # 入れ替え
print(a, b)  # 2 1
実行結果
2 1

一時変数を使うより安全で短いため、バグの混入を減らせます。

関数の複数戻り値を受け取る

関数がタプルを返せば、呼び出し側は自然に分解して受け取れます。

Python
def bbox(points):
    """与えられた2D座標群から、(min_x, min_y, max_x, max_y)を返す"""
    xs = [x for x, _ in points]
    ys = [y for _, y in points]
    return min(xs), min(ys), max(xs), max(ys)  # タプル(のように)返す

pts = [(1, 2), (3, 0), (5, 4)]
min_x, min_y, max_x, max_y = bbox(pts)  # 4変数に展開
print(min_x, min_y, max_x, max_y)
実行結果
1 0 5 4

戻り値の意味が変数名で明確になるため、コメントを減らしても意図が伝わります。

divmodで商と余りを受け取る

divmod(a, b)(商, 余り)を返します。

整数計算で頻出です。

Python
q, r = divmod(23, 5)
print(q, r)  # 商4、余り3
実行結果
4 3

os.path.splitextで名前と拡張子を分ける

ファイル名処理の定番です。

拡張子にはドット込みで入る点に注意します。

Python
import os

filename, ext = os.path.splitext("report_2025-09.csv")
print(filename)  # report_2025-09
print(ext)       # .csv
実行結果
report_2025-09
.csv

forループで座標(x, y)を展開する

2次元座標のリストを処理する際に読みやすく書けます。

Python
points = [(0, 0), (1, 2), (2, 4)]
for x, y in points:  # (x, y)を同時に展開
    print(f"({x}, {y})")
実行結果
(0, 0)
(1, 2)
(2, 4)

enumerateの(インデックス, 値)を展開する

enumerate(index, value)のペアを返すので、アンパッキングで扱いやすくなります。

Python
names = ["Alice", "Bob", "Carol"]
for i, name in enumerate(names, start=1):
    print(i, name)
実行結果
1 Alice
2 Bob
3 Carol

dict.itemsの(キー, 値)を展開する

辞書の項目をキーと値に分けるのは非常に一般的です。

右辺の構造が明確なので可読性が高いです。

Python
config = {"host": "localhost", "port": 5432}
for key, value in config.items():
    print(f"{key} = {value}")
実行結果
host = localhost
port = 5432

zipで複数リストを同時にループする

複数のリストをペアにし、1回のループで処理できます。

Python
ids = [101, 102, 103]
scores = [88, 92, 77]

for sid, score in zip(ids, scores):
    print(sid, score)
実行結果
101 88
102 92
103 77

長さが異なる場合は短い方に揃う点に注意してください。

先頭・中間・末尾を取り出す(first, *middle, last)

先頭と末尾を取りつつ、中間をまとめて処理できる便利なイディオムです。

Python
data = [10, 20, 30, 40, 50]
first, *middle, last = data
print(first)   # 10
print(middle)  # [20, 30, 40]
print(last)    # 50
実行結果
10
[20, 30, 40]
50

よくある質問(初心者向け)

要素数が合わない時の対処は?

基本は*付きアンパッキングを使うのが簡単で安全です。

例えばa, *rest = seqhead, _, tail = seqのように書けば、短いケースから長いケースまで対応できます。

必ず1つだけを使う点に注意してください。

どうしても個数が固定で扱いたいなら、事前にlen(seq)を確認したり、スライスで明示的に切り出してから代入するのも有効です。

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

タプルは不変(immutable)、リストは可変(mutable)です。

どちらもアンパッキングできますが、意味づけが異なります。

変わらない固定の組(例えば(x, y)座標や設定の組)にはタプル、後で追加・変更・削除するコレクションにはリストが適します。

観点タプル(tuple)リスト(list)
可変性変更不可変更可能
代表的用途不変のレコード、関数の複数戻り値順序ある可変の集合
速度・メモリやや軽量やや重め(機能が多い)
アンパッキング可能可能

「変えないもの=タプル」「変える可能性があるもの=リスト」を目安に使い分けるとよいでしょう。

*を使う時の読みやすさのコツは?

  • 役割が伝わる名前にする: first, *middle, lasthead, *tailのように慣用的な語彙を使うと意図が伝わります。
  • 捨てるなら_: head, *_, tailのように、不要な値は_で明示します。
  • *は1つだけ: 左辺に複数置くとSyntaxErrorになります。
  • 極端に長い右辺は避ける: 可読性が落ちる場合は、一旦変数に入れる、スライスするなど段階的に書くと見やすくなります。

まとめ

タプルのアンパッキングは、Pythonの可読性と生産性を大きく上げる基礎テクニックです。

基本は「左右の数を合わせる」こと、柔軟に扱いたいときは「*付きアンパッキング」を使うこと、不要な値は「_で捨てる」ことを押さえれば、実務でも迷いなく使えます。

タプルだけでなくリストや文字列、zipenumerateの結果にも適用でき、関数の複数戻り値やスワップ、ループ処理の明確化など、実例で見た通り活躍の幅は広いです。

今日から少しずつ導入して、コードを短く読みやすくしていきましょう。

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

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

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

URLをコピーしました!