Menu
日本語

Pythonのタプル入門|リストとの違い・アンパック・名前付きタプル

リストではなくタプルを使うべき場面とは?イミュータブルという特性、アンパック、名前付きタプルまで、タプルが本領を発揮するケースを整理します。

タプルは「変更できないリスト」

タプルとリストは一見よく似ています。どちらも順序を持つシーケンスで、インデックス指定もイテレーションもできます。ですが、決定的な違いが1つあります。それは タプルはイミュータブル(immutable)である という点です。タプルは一度作ってしまうと、要素を追加することも、削除することも、入れ替えることもできません。

タプルは丸括弧で書きます(省略できる場面もあります):

main.py
Output
Click Run to see the output here.

要素が 1 つだけのタプルを作るときは、末尾にカンマを付けないといけません。カンマがないと、Python は括弧を単なるグループ化とみなしてしまいます。

main.py
Output
Click Run to see the output here.

空のタプルを作りたいときは () を使います:

main.py
Output
Click Run to see the output here.

イミュータブルを実際に体験してみる

タプルの中身を書き換えようとすると、Python はしっかり止めてくれます。

main.py
Output
Click Run to see the output here.

タプルからの読み取りは自由にできます。インデックスアクセス、スライス、イテレーション、in 演算子、どれも問題ありません。ただし中身を書き換えることはできない、それだけのことです。別の値が欲しければ、新しいタプルを作ればいい話です。

変更できないものが、なぜ便利なのか

イミュータブルというと制約のように聞こえますが、実はこれこそが欲しかった性質、というケースが少なくありません。

  1. 安全性。 関数にタプルを渡しても、知らないうちに中身を書き換えられる心配がありません。
  2. ハッシュ可能。 中身がイミュータブルなタプルは、辞書のキーやセットの要素として使えます。リストではこれができません。
  3. 意図が伝わる。 タプルは「形の決まったレコード」であることを示すシグナルになります。point = (3, 4) と書けば「座標2つ」という意味が point = [3, 4] よりずっとはっきり伝わります。

タプルが特に活きる場面はこんなところです。

  • 座標: (x, y)(lat, lon)
  • RGB カラー: (255, 128, 0)
  • レコード: (name, email, signup_date)
  • 関数から複数の値を返すとき

アンパック

タプルとアンパック構文は、まさに相性抜群の組み合わせです。

main.py
Output
Click Run to see the output here.

アンパックを担っているのは、実は前に置かれたカンマです。Python は名前が 2 つと、値が 2 つ入ったタプルを見て、それぞれをペアで結びつけてくれます。

これは Python らしいコードでは至るところに登場します。

main.py
Output
Click Run to see the output here.

* を使えば「残り全部」をまとめて受け取れます。

main.py
Output
Click Run to see the output here.

最初と最後の要素だけ欲しいときに便利な書き方です。

タプルを辞書のキーとして使う

タプルは(中身がハッシュ可能であれば)それ自体もハッシュ可能なので、辞書のキーとして使えます。リストではこうはいきません。

main.py
Output
Click Run to see the output here.

値の組み合わせをキーにするこのパターン、意外と使いどころが多いんです。たとえば「ユーザーXの、ある日Yでのスコア」や「地点Aから地点Bへの最適ルート」みたいなケースですね。

タプルで複数の戻り値を返す

Python で関数から複数の値を返したいときは、タプルを返すのが定番です。

main.py
Output
Click Run to see the output here.

Pythonの組み込み関数 divmod() がまさにこの挙動をしてくれます。呼び出し側でアンパック代入すると、コードがとても自然に読めますね。

位置だけでは足りないときの名前付きタプル

タプルの要素が2つ3つを超えてくると、「何番目が何の値だったっけ?」と覚えておくのが面倒になってきます。そんなときに便利なのが collections.namedtuple です。

main.py
Output
Click Run to see the output here.

タプルの各要素に名前が付きました。イミュータブルであることもタプルであることも変わらないので、アンパックやインデックスアクセスもそのまま使えます。ただ、アクセスの仕方がぐっと読みやすくなっていますよね。もっと複雑なデータを扱いたい場合は dataclasses という選択肢もありますが、これはクラスの章で改めて取り上げます。

python タプルとリストの違い:使い分けの指針

  • 構造が固定で、各位置に意味がある → タプル
  • 増えたり減ったりする可能性があるコレクション → リスト
  • 関数から複数の値を返したい → タプル
  • 辞書のキーや集合の要素にしたい → タプル(リストでは不可)
  • 中身を書き換えたい → リスト(タプルでは不可)

次のステップへ

タプルは「小さくて、構造が決まっていて、変わらない」という領域をカバーするデータ型です。次に扱う集合(set)は、これとはまったく別の役割――所属チェックの高速化と要素の重複排除――を担うデータ型です。

よくある質問

Pythonのタプルとは何ですか?

タプルは順序付きのイミュータブル(変更不可)なシーケンスです。リストに似ていますが、一度作ったら要素の追加・削除・変更はできません。point = (3, 4) のように丸カッコで書きます。

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

どちらも順序付きのシーケンスですが、リストは作成後に中身を変更できる(ミュータブル)のに対し、タプルは変更できません(イミュータブル)。タプルは、座標や関数の複数の戻り値のように、ひとまとまりの「レコード」として扱う少数の値を表すときによく使われます。

どんなときにタプルを使えばいい?

要素数が決まっていて、各位置に意味があるレコード的なデータ――座標、RGBカラー、データベースの1行など――にはタプルが向いています。また、リストは辞書のキーやセットの要素にできないので、そうした用途ではタプル一択です。それ以外で要素が増減するようなコレクションなら、基本はリストでOKです。

Coddyでコードを学ぼう

始める