タプル

概要

タプルは変化しないデータ構造を作るための型です。 リストでもデータ構造は作れますが、 構造が固定化された会員情報(ID、名前、住所など)を1つのデータとして扱うにはタプルが適しています。

タプルは初期化したあとは要素を参照したり更新することはできますが、 追加したり削除したりすることはできません。 そのため、データ構造の構成が変わってもおかしくないリストよりも、 絶対に構成が変わらないタプルのほうが決められたデータ構造を表現するのに向いています。

タプル型の特徴

タプル 」はPythonの型の一つであり、リストと似ています。 リストはひとつのインスタンスの中に複数の要素を持ち、それをインデックス番号で操作します。 タプルもそれと全く同じで、ひとつのインスタンスの中にインデックス番号で管理される要素が複数あります。

ただ、両者の大きな違いは「リストは要素の数が変わることを前提とした型」であるのに対し、 「タプルは構成が全く変わらない」ということです。 言い換えると、リストは初期化した後に要素を追加したり削除したりすることができますが、 タプルは初期化後に要素数が変わることはなく、 要素を上書き(インデックス番号を指定して代入)することもできません。

タプルが利用されるのはデータ構造の構成要素が明確な場合です。 たとえばあるお店の会員情報があるとし、それが「氏名、生年月日、住所」から構成されているとします。 タプルでこの構造を作れば要素の1つめは必ず氏名で、2つめは生年月日となります。

一方、リストで会員情報のデータ構造を作れば「氏名、生年月日、住所」と並んでいる前に、 いきなり新しく会員IDを追加するといったことができますし、住所がいらなくなったから消すといったこともできます。 これは便利なように見えるかもしれませんが、会員データを扱うプログラムが様々な箇所に及んでいると、 名前を参照したつもりが会員IDを得てしまったり、住所を得るつもりだったのにそれが消失している可能性があります。

リストはこういった決められたデータ構造自体よりも、増減する会員数を管理する型として使うと便利です。 タプルの要素はそれぞれが全く異なる情報であるのに対して、 リストの要素は値こそ違っても使われ方は全く同じものとなるのが一般的です。

image

タプル型の基本操作

作成

タプルの初期化はカッコ「()」の中に要素をコンマ区切りで並べることでおこないます。

>>> a = ('taro', '1986', 'tokyo')
>>> print(type(a))
<class 'tuple'>

要素を持たないタプルを作るには単に「()」とします。

>>> a = ()
>>> print(type(a))
<class 'tuple'>

見た目に分かりにくいのであまり推奨はしませんが、 カッコで囲まずにコンマで要素を並べるだけでもタプルは作成できます。

>>> a = 1,2,3
>>> print(a)
(1, 2, 3)
>>> print(type(a))
<class 'tuple'>

要素の取得

インデックス番号を使った要素へのアクセスはリストと全く同じです。 「タプルのインスタンス[インデックス番号]」とすることで、特定の要素を取得することができます。

>>> a = ('taro','1986','tokyo')
>>> print(a[0])
taro

あるタプルを「別のタプルとそのなかにある要素となる変数」に代入させることで、 要素をまとめて取り出すこともできます。

>>> a = ('taro','1986','tokyo')
>>> (b,c,d) = a
>>> print(b)
taro
>>> print(c)
1986
>>> print(d)
tokyo

要素の上書きはできない

リストと異なり、タプルは要素を変更することはできません。 これはappendメソッドやdel演算子などが使えないというだけでなく、 インデックス番号を指定した要素の上書きもできないということです。

>>> a = ('taro','1986','tokyo')
>>> a[1] = '1886'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

ただ、タプルが要素としてインスタンスを保つ場合は、 そのインスタンスの中身は変わる可能性があります。

>>> a = [1]
>>> b = ('hello', a)
>>> print(b)
('hello', [1])
>>> a.append(2)
>>> print(b)
('hello', [1, 2])

タプルの便利な使い方

関数の返り値

複雑な関数を作成した場合に、返り値として複数の値を返したい場合があります。 他のプログラミング言語であれば複数のデータを格納するための構造体やクラスをそのためだけに定義することがありますが、 Pythonであれば返したい複数の値をタプル化して返せます。

呼び出し元はタプルで返された値をそのまま変数に代入しても構いませんし、 タプルで返り値を受けて要素を各変数に代入させることもできます。

たとえばfor文でリストの要素の最小値と最大値を取得する関数を作るとしましょう。 返り値となる最大値と最小値をタプルで囲んで返せば、 関数の呼び出し元は最大値と最小値を同時に得られます。

def get_min_max(list_):
  min_ = list_[0]
  max_ = list_[0]
  for i in list_:
    if(i < min_): min_ = i
    if(max_ < i): max_ = i
  return (min_, max_)

a = [5,8,1,4,10,3,7]
(min_, max_) = get_min_max(a)
print('min: {}'.format(min_))
# 1
print('max: {}'.format(max_))
# 10

プログラマーによっては複数の返り値を返す際にタプルだということをあまり意識せずに、 カッコで囲まない書き方をする場合もあります。 以下のコードもカッコを省略したタプルですので、上記と同じです。

def get_min_max(list_):
  min_ = list_[0]
  max_ = list_[0]
  for i in list_:
    if(i < min_): min_ = i
    if(max_ < i): max_ = i
  return min_, max_

a = [5,8,1,4,10,3,7]
min_, max_ = get_min_max(a)

なお、返り値をタプルにした場合は、タプルの要素数の変更には気をつけて利用してください。 関数の定義と関数を使う側の定義が合致していないと、実行時にエラーが発生します。

タプルの演算子

inが使える

タプルを使う関数

zip

タプルのメソッド

タプルのメソッドはほとんど利用されません。 インスタンスの変更ができないため、変更をするためのメソッドが全く存在しないリストに似たメソッドだけを持っています。

count : 引数と同じ値を持つ要素の数を数える

index : 引数と同じ値を持つ要素のインデックス番号を得る