ゼロからのPython入門講座タプル

コンテナとタプル

コンテナとタプル

これまで、 整数や実数文字列 などの種類のオブジェクト を紹介してきました。また、複数のデータを順番に登録するリストや、データとデータの対応関係を登録する辞書 なども紹介しました。

数値や文字列は、物質の重さや長さ、いろいろな名前など、いろいろなデータの値をあらわすオブジェクトです。一方、 リストや辞書は、直接的なデータではなく、いろいろなデータを登録して、集約しておくために使われるオブジェクトです。リストや辞書のように、他のオブジェクトを集約することを目的としたオブジェクトのことを、

コンテナ (Container)

と呼びます。

これまで、コンテナとしてリストと辞書を紹介しましたが、ここではもう一つのコンテナである タプル を紹介します。

タプル

データにはさまざまな種類があり、中には複数のデータから構成されているものがあります。例えば、

  • 東京都の人形町駅の位置は、緯度と経度で表すと、緯度 35.686321、 経度 139.782211 という2つの数値の組み合わせから構成されます。
  • 日本での氏名は、名字と名前という2つの文字列の組み合わせから構成されます。
  • 日本の年号は、昭和・平成などの元号と、2030 などの数値の組み合わせから構成されます。
  • 色は、赤・緑・青の三原色を表す3つの数値の組み合わせで表現できます。例えば、黄色は赤 255、緑 255、 青 0 という組み合わせです。

このように、一つの情報が、複数の情報の組み合わせから構成されている、というのは非常に一般的です。

Pythonでは、このような複数のデータの組み合わせから構成されているデータを表現する場合、タプル という種類のオブジェクトを利用します。

タプル(tuple)というのはあんまり聞き慣れない言葉ですが、数学用語で などとも呼ばれ、複数の要素が順番にならんだ値を指します。

タプルオブジェクトは、複数の値をカンマ , で区切って記述します。例えば、上記の人形町駅の位置は、タプルであらわすと次のようになります。

In [2]:
ningyocho = 35.686321, 139.782211
print(ningyocho)
(35.686321, 139.782211)

緯度 35.686321 と、経度 139.782211 をカンマ , で区切って記述し、一つのタプルオブジェクトとして 変数 ningyocho に代入しています。

また、平成2年 は、平成 と言う文字列と、数値の 2 の組み合わせですから、これもカンマ , で区切って

In [3]:
kotoshi = '平成', 2
print(kotoshi)
('平成', 2)

と書けます。

タプルは、このように要素となるデータを , で区切って記述できますが、, だけだとちょっと見にくいので、通常は全体を丸括弧 () で囲んで記述します。

例えば、前述の ningyochokotoshi は、次のように書きます。

In [13]:
ningyocho = (35.686321, 139.782211)
kotoshi = ('平成', 2)

この括弧は必須ではありませんが、括弧なしでは読みにくく、間違いの元になる場合もあるので、通常は括弧をつけて記述する慣習になっています。

タプルオブジェクトの要素

タプルの要素として登録されたオブジェクトは、リスト と同じように 要素の順番 を指定して参照できます。

タプルオブジェクト[要素の順番]

要素の順番 として指定する数値のことを、リストオブジェクトと同じように インデックス と呼びます。

人形町駅の緯度と経度のタプルは

ningyocho = (35.686321, 139.782211)

でした。このタプルから、緯度と経度を取り出してみましょう。ningyocho(緯度, 経度) という形式のタプルオブジェクトですから、最初の要素が緯度、次の要素が経度です。

In [15]:
ningyocho = (35.686321, 139.782211)

ido = ningyocho[0]  # 緯度は先頭の要素
keido = ningyocho[1]  # 緯度は次の要素

print("人形町の緯度は", ido, "経度は", keido, "です")
人形町の緯度は 35.686321 経度は 139.782211 です

タプルオブジェクトの操作

リストオブジェクトの場合は、要素を参照する以外に、追加や削除、変更などの操作 を行えます。

In [43]:
sample = [1, 2, 3] # リストオブジェクトの作成
sample[0] = 'a' #  要素の更新
print(sample)
['a', 2, 3]

しかし、タプルオブジェクトの場合、リストオブジェクトのように要素を変更することはできません。タプルオブジェクトの要素を変更する場合は、リストオブジェクトのように要素を変更するのではなく、あたらしくタプルオブジェクト全体を作り直す必要があります。

たとえば、color という変数に、色の情報として黄色 (255, 255, 0) が設定されているとします。

In [44]:
color = (255, 255, 0)  # 黄色
print(color)
(255, 255, 0)

color の色を、黄色 (255, 255, 0) から赤 (255, 0, 0) に変更したい場合でも、リストオブジェクトのように値を更新することはできません。次のようなエラーになります。

In [45]:
color[1] = 0  # 緑色を 0 に変更
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-45-8f192bf0a20a> in <module>
----> 1 color[1] = 0  # 緑色を 0 に変更

TypeError: 'tuple' object does not support item assignment

color の値を変更する場合は、タプルの要素を変更するのではなく、次のようにタプル全体を設定します。

In [46]:
color = (255, 0, 0)  # 赤
print(color)
(255, 0, 0)

タプルとリスト

タプルオブジェクトとリストオブジェクトはよく似ています。

どちらも他のデータを格納できるコンテナオブジェクトで、格納した要素は数値をインデックスとして参照できます。リストにはデータを追加したり削除したりできますが、タプルは変更できません。タプルとリストの見た目もよく似ています。

list_values = [1, 2, 3]  # リスト
tuple_values = (1, 2, 3) # タプル

リストとタプルはどのように使い分ければよいのでしょうか?

前述のように、タプルは

複数のデータの組み合わせから構成されているデータ

のためのオブジェクトです。

次の例は、学校である生徒の定期テストの結果をデータとして記述しています。

sugaku = 50  # 数学の点数
kokugo = 60  # 国語の点数
eigo = 70  # 英語の点数

exam_scores = (sugaku, kokugo, eigo)

exam_scores は、ある生徒の成績を

(数学の点数, 国語の点数, 英語の点数)

という決まったルールで記述した、固定的な形式のデータです。

このように、複数の要素から構成される独立したデータ をあらわすときは、タプルを使用します。

もう一つの例として、テストの点数を、教科ごとにまとめたデータを考えてみましょう。

sugaku_scores = [82, 12, 12, 94, 86, 5]
kokugo_scores = [99, 64, 99, 39, 56, 1, 77, 57, 82, 75, 5, 74, 3]
eigo_scores = [16, 81, 82, 47, 80, 48, 10, 72, 81, 7]

ここで定義した変数 sugaku_scoreskokugo_scoreseigo_scores は、それぞれ数学、国語、英語の、全受験者の点数をまとめたリストです。それぞれの教科では受験者数が違うため、要素数も全て異なっています。

このように、一つの独立したデータではなく、独立したデータをたくさん集約してまとめておきたい、という用途には、リストが適しています。

もちろん、タプルを使わず、常にリストを使用することもできますが、その場合次のようなデメリットが考えられます。

  • exam_scores のようにタプルで作られたデータは、あとからプログラムを参照する人に 「これは複数の値から構成されるデータだ」 という情報を伝え、プログラムの意図を理解する助けになります。リストにしてしまうと、間違った意図を伝えることになります。

  • タプルは個別のデータをあらわすオブジェクトなので、非常にたくさんのオブジェクトが使用されても効率的に処理できるようになっています。
    テストの例で考えれば、受験者が100万人いた場合は exam_scores のようなデータが100万個作られることになります。タプルの場合には100万件のデータを作っても最小限の負荷で抑えられますが、リストで同じデータを100万個作ると、タプルと比べて大きな負荷がかかります。



【Copyright © 2001-2020 python.jp】 【Privacy Policy】 python_japan