重要度:★★★★★
シリーズ「Pythonプログラミングの始め方」ではPythonの基礎文法を図を用いて分かりやすく解説していきます。
今回は、この「タプル(Tuple)」について「データ構造の基本」から「作り方(定義の方法)」「要素へのアクセス(参照・取得)」「タプルが使える関数」について基礎から丁寧に図解で解説をします。
この記事を読むことで次のことが「できる・わかる」ようになりますので最後までお付き合い下さい。
本サイトでの紹介内容は一例です。また、関数などの省略可能なオプション引数などについては割愛していますので、詳細や不明点などは必要に応じて公式サイトなどを参照してください。
【Python公式ドキュメント】https://docs.python.org/ja/3/library/stdtypes.html#mapping-types-dict
1. タプルを定義する

本節では、タプルを定義(生成)する方法について解説します。あらためてタプルの基本書式を確認したのち、組込み関数を使ったタプルの生成方法について説明していきます。
1.1 タプルオブジェクトの書式
タプルオブジェクトは、要素を「,」(カンマ)区切りで並べたデータ構造となります。そして全体を「()」(カッコ)で囲んで表現します。ただし、オブジェクトを定義する際には「()」は必須ではないのですが、一般的にはカッコで囲む次の書式がよく使われます。また、タプルの要素にタプルを入れ子(ネスト)構造にすることもできます。
それでは、サンプルコードで確認してみましょう。
例1.各要素を「,」で区切りながら配置し、全体を「()」でかこむ、一般的なタプルの書式です。リストと同様に要素には、数値や文字(列)といったイミュータブルなものあったり、リストなどのようにミュータブルな要素を指定することができます。
# <タプルの定義1>
# 数値や文字列を要素に指定した例
# 文字(列)
print( ('a', 'b') ) # ➀>> ('a', 'b')
# 数値
print( (123, 456) ) # ➁>> (123, 456)
# 文字列+数値の混載
print( ('a', 123) ) # ➂>> ('a', 123)
#-----------------------------------------------------------------------------
# <タプルの定義2>
# 要素には、リストやタプルを指定した例
# "リスト"を要素にする
print( ([10, 20], [30, 40]) ) # ➄>> ([10, 20], [30, 40])
# "タプル"を要素にする(ネスト構造)
print( ((10, 20), (30, 40)) ) # ➃>> ((10, 20), (30, 40))
# さまざまなオブジェクトを混載
print( (10, 20, [30, 40], 'abc') ) # ➅>> (10, 20, [30, 40], 'abc')
<タプルの定義1> 数値や文字(列)を要素に指定した例
➀ 》 (‘a’, ‘b’)
➁ 》 (123, 456)
➂ 》 (‘a’, 123)
<タプルの定義2> リストやタプルを要素に指定した例
➃ 》([10, 20], [30, 40])
➄ 》((10, 20), (30, 40))
➅ 》(10, 20, [30, 40], ‘abc’)
例2.タプルのデータ構造を定義する際には、必ずしも「()」を付加する必要はありません。次の例のように、「,」区切りで要素を並べた状態でタプルであることは認識されます。実行時にコンパイラによって自動的に()付きの表現に変換されます。<List2>
また、➂のように要素が1つだけの場合は、最後に「,」を付加することでタプルと認識されます。
# <タプルの定義3>
# ()なしで定義した例
t1 = 'a', 'b'
t2 = 123, 456
t3 = 'a', #要素が1個のみの場合
print(t1) # ➀>> ('a', 'b')
print(t2) # ➁>> ('a', 'b')
print(t3) # ➂>> ('a',)
<タプルの定義3> ()なしで定義した例
➀ 》(‘a’, ‘b’)
➁ 》(123, 456)
➂ 》(‘a’,) #要素が1つのみの場合は、最後に”,”だけ付ける
1.2 組込み関数(tuple)による生成
Pytnonの組込み関数には、タプルを定義・生成する「tuple()関数」が提供されています。引数には、リスト、Rangeオブジェクトなどのイテラブルなオブジェクトであったり、文字列を指定します。
tuple(iterable)
引数: iterable: タプルオブジェクトの要素となる値(イテラブルなオブジェクト)を指定
リスト, Range()オブジェクト, 文字列
省略可能で、省略した場合は空のタプルを返す
戻り値: タプルオブジェクト
tuple()関数 の使用例を紹介します。引数に Rangeオブジェクト やリスト・文字列を指定して効率的にタプルを生成することができます。タプルを指定することもできますが、この場合は展開されずにそのままネストする形で要素に追加されます。<List3_1>
# 組込み関数 tuple()を用いたタプルの生成
# Rangeオブジェクトを指定
print( tuple(range(-2, 2)) ) # ➀>> (-2, -1, 0, 1)
# リストを指定
print( tuple(['abc', 'def', 1]) ) # ➁>> ('abc', 'def', 1)
# 文字列を指定
print( tuple('abc') ) # ➂>> ('a', 'b', 'c')
組込み関数 tuple()を用いたタプルの生成
➀ 》(-2, -1, 0, 1)
➁ 》(‘abc’, ‘def’, 1)
➂ 》(‘a’, ‘b’, ‘c’)
ちなみに、tuple()関数の引数は1つだけ指定できます。次のように2つ以上の引数を指定しようとした場合は、「TypeError」が発生します。<List3_2>
イテラブルなオブジェクトとして引数を指定するようにします。
# tuple関数の引数に2つ以上を指定した場合
print(tuple(1, 2, 3))
# >>TypeError: tuple expected at most 1 arguments, got 3
tuple関数の引数に2つ以上を指定した場合
》TypeError: tuple expected at most 1 arguments, got 3
2. タプルを扱う

本節では、生成したタプルへの「アクセス方法」と「扱い方」について解説をしていきます。
リストと似たデータ構造のため、類似した部分もありますがタプル特有の操作方法もありますので、リストとの違いについて意識しながら読み進めて頂ければと思います。
2.1 要素の参照と取得
先にも触れたように、イミュータブルなオブジェクトであるタプルは、後から要素を追加したり、変更するといったことはできません。それ以外は、リストと同様に扱うことで、要素の参照や取得が可能となります。
要素へのアクセス方法は、インデックスによる「個別要素へのアクセス」または、スライスを利用した「複数要素への一括アクセス」の2つがあります。
2.1.1 個別要素の参照と取得
個別要素には、識別番号(インデックス)が割り振られています。要素のへのアクセスはこのインデックスを指定して行います。インデックスは「先頭から」「末尾から」の2通りの基準があります。(リスト同様)
各要素へのアクセスは、次の書式のようにインデックスを指定して行うことができます。
【タプルの参照】
タプルオブジェクト[index]
引数: index: 参照したい要素のインデックスを指定する
基準の取り方により先頭から指定、末尾から指定の2通りある
- 先頭基準:要素の先頭から0、1、2、3、4・・・
- 末尾基準:要素の末尾から-1、-2、-3、-4、-5・・・
戻り値: タプルの各種要素
また、タプルの多重構造のアクセスも可能で、リスト同様に扱うことができます。たとえば、2重構造(タプルの要素にタプル)の場合は次のような書式でアクセスします。
【タプル(多重構造)の参照】
タプルオブジェクト[index1][index2]
引数: index1: 外側(親要素)のインデックスを指定する
引数: index2: 内側(子要素)のインデックスを指定する
戻り値: タプルの各種要素
※各位インデックスは、先頭・末尾基準が可能(単純タプル構造と同様)
それでは、具体例をコードで確認してみましょう。<List4>
インデックス指定で、各要素の参照をしています。多重構造(2次)のタプルは、➅➆のように ”[]”(カッコ)を並べて指定します。要素にリストをもつタプルもまた、同様にリストの中身をインデックスで指定ができます。➃➄
# インデックスによる要素の参照
# タプル(基本型)
# 先頭基準
print( (10, 20, 30, 40, 50)[0] ) # ➀>> 10
print( (10, 20, 30, 40, 50)[4] ) # ➁>> 50
# 末尾基準
print( (10, 20, 30, 40, 50)[-1] ) # ➂>> 50
#-------------------------------------------
# タプル(要素がリスト)
print( ([10, 20], [30, 40])[0] ) # ➃>> [10, 20]
print( ([10, 20], [30, 40])[1][0] ) # ➄>> 30
#-------------------------------------------
# タプル(多重型)
print( ((10, 20), (30, 40))[0]) # ➅>> (10, 20)
print( ((10, 20), (30, 40))[1][1]) # ➆>> 40
インデックスによる要素の参照
基本型
➀ 》10
➁ 》50
➂ 》50
要素にリストをもつタプル
➃ 》[10, 20]
➄ 》30
ネスト構造のタプル
➅ 》(10, 20)
➆ 》40
定義されたタプルの要素を更新しようすると「TypeError」が発生することも確認してください。(➀,➁)ひとつ注意が必要なのが、要素にリストをもつタプルです。この場合は、要素ごと変更しようとすると同様にエラーが発生しますが(➂)、要素(リスト)の中身(リストの要素)の変更は普通に出来てしまいます。(➃)
# タプルの更新(エラーの確認)
(10, 20, 30, 40, 50)[1] = 90 # ➀>> TypeError TypeError: 'tuple' object does not support item assignment
((10, 20), (30, 40))[1][1] = 90 # ➁>> TypeError TypeError: 'tuple' object does not support item assignment
# 要素にリストを持つタプルの場合 -----------------------------------
t1 = ([10, 20], [30, 40])
t1[1] = 90 # ➂>> TypeError TypeError: 'tuple' object does not support item assignment
# タプルの要素であるリストに対する更新処理なので変更できる
t1[1][1] = 90
print(t1) # ➃>> ([10, 20], [30, 90])
タプルの更新(エラーの確認)
➀ 》TypeError: ‘tuple’ object does not support item assignment
➁ 》TypeError: ‘tuple’ object does not support item assignment
➂ 》TypeError: ‘tuple’ object does not support item assignment
タプルの要素であるリストに対する更新処理なので変更できる
➃ 》([10, 20], [30, 90])
2.1.2 スライスによる一括参照(取得)
タプルにおいても「スライス」というインデックスの記述スタイルが使えます。スライスを使うことで、複数の要素を一括指定して効率的にアクセスできます。
「スライス」の書式は次の通りで、アクセスした要素の範囲を、「開始位置」と「終了位置」の間に「:」(コロン)を挟んで指定します。「開始位置」と「終了位置」は省略することができ、省略した場合は、それぞれ「先頭から」「末尾まで」または、「全要素」となります。
➀. タプルオブジェクト[開始位置:終了位置]
➁. タプルオブジェクト[開始位置:終了位置:ステップ]
スライスにはステップ指定の有無により2つの書式があります
➀はステップさせない場合、➁はさせる場合です
引数1: 開始位置: 開始位置のインデックス(省略可能)
引数2: 終了位置: 終了位置のインデックス(省略可能)
引数3: ステップ: 範囲内のステップ数(増分値)の指定(省略可能)
※引数1~3はいずれも省略した場合は、全ての要素が対象になります。
戻り値: 新しいタプル
「引数3:step」では、範囲内におけるステップ幅を指定することができます。戻り値は、新たなタプルオブジェクトが戻ります。
それでは、スライスの具体例をコードで確認します。
開始・終了位置・ステップ数をそれぞれ指定(省略)した場合の操作例です。スライスでは、元のタプルは変更せず、新しいタプルを返します。(➄)
# スライスの使用例
words = ("blue", "red", "green", "yellow", "pink", "black", "white")
#---------------------------------------
# 終了位置を省略した場合「インデックス3~末尾迄の要素」
print(words[3:]) # ➀>> ('yellow', 'pink', 'black', 'white')
# 開始位置を省略した場合「先頭~インデックス3の要素」
print(words[:3]) # ➁>> ('blue', 'red', 'green')
# インデックス3~5の要素
print(words[3:5]) # ➂>> ('yellow', 'pink')
# インデクス1~7の範囲で1個飛ばしの要素を抽出
print(words[1:7:2]) # ➃>> ('red', 'yellow', 'black')
#---------------------------------------
# 元のタプルは変更されない
print(words) # ➄>> ('blue', 'red', 'green', 'yellow', 'pink', 'black', 'white')
終了位置/開始位置の設定と省略
➀ 》(‘yellow’, ‘pink’, ‘black’, ‘white’)
➁ 》(‘blue’, ‘red’, ‘green’)
➂ 》(‘yellow’, ‘pink’)
ステップ幅を設定
➃ 》(‘red’, ‘yellow’, ‘black’)
スライスによって元のタプルに影響しない
➄ 》(‘blue’, ‘red’, ‘green’, ‘yellow’, ‘pink’, ‘black’, ‘white’)
2.1.3 タプルの連続(シーケンシャル)参照
タプルは「イテラブルオブジェクト」です、公式ドキュメントではシーケンス型として分類されています。(図6)イテラブルとは、オブジェクトの構成要素に連続的(シーケンシャル)にアクセスできるもののことをいいます。
要素に連続的(シーケンシャル)にといわれてもイメージしにくいですよね。実際のコード例で確認してみましょう。<List7>
たとえば、次は、For-in文句 内包表記 で用いて包含する要素の数だけ自動的にループを回しながら、順番に要素にアクセスしています。
<2.1.1>や<2.1.2>のように、インデックスを用いる必要はありません。
t1 = ("A", "B", "C", "D")
t2 = ("key1", "key2", "key3", "key4")
# ------------------------------------------------
# タプルをイテラブルに展開する
# For-inステートメントによる展開(1)-----------------------------
for elem in t1:
print(elem) # ➀>> A B C D
# For-inステートメントによる展開(2)-----------------------------
# 内包表記によるタプル→リストへの変換
print([elem for elem in t1]) # ➁>> ['A', 'B', 'C', 'D']
# 内包表記によるタプル→辞書への変換
print({ key:val for val, key in enumerate(t2, 1)}) # ➂>> {'key1': 1, 'key2': 2, 'key3': 3, 'key4': 4}
タプルをイテラブル(シーケンシャル)に展開する
For-in ステートメントによる展開
➀ 》A B C D
内包表記による ”タプル” から ”リスト” への変換
➁ 》[‘A’, ‘B’, ‘C’, ‘D’]
内包表記による ”タプル” から ”辞書” への変換
➂ 》{‘key1’: 1, ‘key2’: 2, ‘key3’: 3, ‘key4’: 4}
2.2 パック(zip関数)とアンパック
タプル特有の操作方法に「パック」と「アンパック」があります。パックは、複数のリストを「組込み関数zip()」でタプルに変換することを言います。また、アンパックはタプルを1式で分解することを言います。
これも定義だけではわかりずらいので、具体例を示しましょう。<List8>
【アンパック】: 同じ要素数のタプル同士を「=」で割り当てると、左辺の各要素(変数)に右辺の要素が割り当てられます。タプルは「()」なしで表現できるので➁のようにも記述することができます。
また、アンパックを使うことで、➂のように1ステートメントで、変数の値の交換を行うことができます。
# タプルのアンパック
# ➀.タプル同士の割り当てができる
(a, b) = ('a1', 'b1')
print(a, b) # ➀>> a1 b1
# ➁. タプルなので()を省略して記述できる
a, b = 'a2', 'b2'
print(a, b) # ➁>> a2 b2
#-----------------------------------------------
c = 100
d = 200
# ➂. アンパックにて、変数の入れ替える
print(c, d) # ➂_1>> 100 200
d, c = c, d
print(c, d) # ➂_2>> 200 100
タプルのアンパック
➀ 》a1 b1
➁ 》a2 b2
➂_1 》100 200
➂_2 》200 100 # アンパックで変数の入れ替えを1ステートメントで対応
【パック】:複数のリストをzip()関数に渡すと zipオブジェクト が生成されます。zipオブジェクトの実体は、同じインデックス同士でタプルにまとめられた多重構造(2次)となります。(➁) また、イテラブルな性質もありますので、➂のように For-in構文 で展開することできます。
zip object at 0x000001644D54A3C8
# zip()関数による、タプルへのパック
list1 = [11, 12, 13]
list2 = [21, 22, 23]
list3 = [31, 32, 33]
# ➀.zipオブジェクト
print(zip(list1, list2, list3)) # ➀>> <zip object at 0x000001644D54A3C8>
# ➁.zipオブジェクトの実体は、タプルの多重構造(2次)
print(list(zip(list1, list2, list3))) # ➁>> [(11, 21, 31), (12, 22, 32), (13, 23, 33)]
# ➂.zipオブジェクトは、イテラブルなのでFor-inで要素を展開できる
for num1, num2, num3 in zip(list1, list2, list3):
print(num1, num2, num3)
# ➂>> 11 21 31
# >> 12 22 32
# >> 13 23 33
タプルのパック(ZIPオブジェクト)
➀ 》<zip object at 0x000001644D54A3C8>
➁ 》[(11, 21, 31), (12, 22, 32), (13, 23, 33)] # ZIPオブジェクトはタプルの多重構造
➂ 》11 21 31 # ZIPオブジェクトは、イテラブルなのでFor-inで要素を展開可能
12 22 32
13 23 33
以上がタプルの各要素にアクセスするための基本事項についてでした。同じデータ構造の「リスト」との違いについて整理しておきましょう。
3. 組込み関数・メソッド、演算子の活用

タプルには、これまでに解説してきた「タプルを定義・生成する」「要素にアクセスする(参照・取得)する」以外にいくつかの「組込み関数」「メソッド」「演算子」が活用できます。本節の最後に、タプルの応用操作について解説したいと思います。
3.1 組込み関数・メソッド(タプルオブジェクト)
次の組込み関数の引数に、タプルを指定することで要素の演算を行うことができます。
sum(s) : 全要素の合計値を算出する
max(s) : 要素の最大値を調べる
min(s) : 要素の最小値を調べる
len(s) : 要素数の数を調べる
引数: s: シーケンス型のオブジェクト(ここではタプル)
戻り値: 演算結果
使用例をコードで確認してみます。<List9>
num = (15, 21, 59, 9, 42, 68)
# 組込み関数 --------------------------------------
# 合計値
print(sum(num)) # ➀>> 214
# 要素の最大値
print(max(num)) # ➁>> 68
# 要素の最小値
print(min(num)) # ➂>> 9
# 要素数
print(len(num)) # ➃>> 6
組込み関数の活用
➀ 》21 # sum:合計
➁ 》68 # max:最大値
➂ 》9 # min:最小値
➃ 》6 # len: 要素数
また、タプル(シーケンシャル型オブジェクト)で使えるメソッドも存在します。
タプルはイミュータブルなので要素の変更はできません。よって、メソッドで操作できる機能は要素の検索のみで index()メソッド と count()メソッド の2だけとなります。それぞれ書式は以下の通りです。
<特定の要素が出現するインデックスを検索する>
タプルオブジェクト.index(x, i, j)
引数: x: 調査対象の要素の値を指定する
引数: i: 調査対象の範囲(開始位置) 省略可能
引数: j: 調査対象の範囲(終了位置) 省略可能
戻り値: インデックス
<特定の要素が出現する回数を調べる>
タプルオブジェクト.count(x)
引数: x: 調査対象の要素の値を指定する
戻り値: 要素(x)の数
これらのメソッドは、タプル専用というわけではなく、リストでも同様に操作でいます。(リストオブジェクトの index() cont() )
これらの具体例をコードで確認してみます。<List10>
t_num = (15, 9, 59, 9, 42, 68)
# タプルオブジェクトのメソッド --------------------------------------
# index()メソッド
print(t_num.index(9)) # ➀>> 1
print(t_num.index(9, 2, 5)) # ➁>> 3
# count()メソッド
print(t_num.count(9)) # ➂>> 2
タプルのメソッド活用
➀ 》1 # index()メソッド
➁ 》3
➂ 》2 # count()メソッド
3.2 演算子でタプルを操作する
タプルを含むシーケンス型のオブジェクトでは、次のような演算子が利用できます。
演算子 | 使用例 | 説明 |
---|---|---|
in | x in s | タプル(s)の要素の中に、特定の値(x)が含まれる場合は、「True」そうでなければ 「False」が返る |
not in | s not in t | タプル(s)の要素の中に、特定の値(x)が含まれる場合は、「False」そうでなければ 「True」が返る |
+ | s + t | タプル(s)に別のタプル(t)を連結する |
* | s * n (n * s) | タプル(s)をn回繰り返し連結する |
順番に確認していきましょう。「in」[not in] 演算子は、要素に特定の値が含まれているか検索する演算子です。含まれていれば「True(False)」を返します。
また、タプル同士を連結する「+演算子」や要素を繰り返して連結する「*演算子」もあります。これらは、オリジナルのタプルは変更せずにそのコピーに対して演算して戻します。
それでは、使用例をコードで確認してみます。<List11>
t_str = ('ABC', 'DEF', 'FHI')
t_num = (123, 456, 789)
# in演算子 ----------------------------------------------------
print('ABC' in t_str) # ➀>> True
print('Python' in t_str) # ➁>> False
# +演算子によるタプルの連結 -----------------------------------
print( t_str + t_num ) # ➂>> ('ABC', 'DEF', 'FHI', 123, 456, 789)
print(t_str) # >> ('ABC', 'DEF', 'FHI')
print(t_num) # >> (123, 456, 789)
# *演算子によるタプルの連結繰り返し ---------------------------
print(t_num * 3) # ➃>> (123, 456, 789, 123, 456, 789, 123, 456, 789)
print(t_num) # >> (1, 2, 3)
in演算子
➀ 》True
➁ 》False
+演算子によるタプルの連結
➂ 》(‘ABC’, ‘DEF’, ‘FHI’, 123, 456, 789)
*演算子によるタプルの繰り返し連結
➃ 》(123, 456, 789, 123, 456, 789, 123, 456, 789)
3.3 タプルを比較する
タプル同士を比較するには「==」と「is」演算子があります。両者の書式は以下の通りです。
演算子 | 使用例 | 説明 |
---|---|---|
== | s == t | タプル(s)とタプル(t)は同じ要素(値とインデックス)をもつ場合は 「True」そうでなければ「False」が返る |
is | s is t | タプル(s)とタプル(t)が、同じオブジェクトであれば「True」 そうでなければ「Flase」が返る |
具体例で両者の違いを確認してみます。まったく同じ要素(インデックスも同じ)をもつ「タプルオブジェクトA」と「タプルオブジェクトB」があったとして、それぞれに変数を割り当てた場合の両演算子の違いについて確認しています。<List12>
# 2つの同じ要素をもつオブジェクトを定義 ------------
TupleA = (1, 2, 3)
TupleB = (1, 2, 3)
#---------------------------------------------------
print(TupleA == TupleB) # ➀>> True
print(TupleA is TupleB) # ➁>> False
# 同じオブジェクトを "TupleC" 割り当てる
TupleC = TupleA
print(TupleA == TupleC) # ➂>> True
print(TupleA is TupleC) # ➃>> True
# オブジェクトIDを確認する
print(id(TupleA)) # ➄>> 2870183696888
print(id(TupleB)) # ➅>> 2870183697928
print(id(TupleC)) # ➆>> 2870183696888
比較演算子
➀ 》True
➁ 》False
➂ 》True
➃ 》True
オブジェクトIDの確認
➄ 》2870183696888 # TuppleAのID 環境・実行ごとに異なる
➅ 》2870183697928 # TuppleBのID 環境・実行ごとに異なる
➆ 》2870183696888 # TuppleCのID 環境・実行ごとに異なる
同じ要素を持つオブジェクトであってもAとBは別物です (➁と➄,➅)。その一方で、AとCは同一のオブジェクトを割り当てる(指している)ため、当然ながら同一オブジェクトです。(➂, ➄,➆)
以上のように、「is演算子」はオブジェクトレベルでの比較を行います。「==演算子」はオブジェクトの中身の比較を行います。
4. まとめ

いかがでしたでしょうか?
今回は、Pythonを代表するデータ構造の1つである「タプル」について解説してきました。同じようなデータ構造に「リスト」がありますが、タプルは一度定義したオブジェクトを後から変更・更新できない(イミュータブル)という特徴があります。
安易に変更したくないデータを管理するにはタプルを使いましょう。一方で、リストようりも処理が高速であるといったメリットもあります。
その他、ポイントをまとめておきます。
➀. タプルは要素を「,(カンマ)」で区切り「(,)(カッコ)」で囲むことで定義できる。またtupule()関数 で生成することもできる。
➁. 要素へのアクセスは、インデックス(個別、スライスによる範囲指定)指定もできるし、イテラブルに全要素を順番に参照することできる。
➂. シーケンス型のオブジェクトに属する「タプル」では、オブジェクト配下の関数・メソッドや演算子を利用することができる。リストと同様であるが、イミュータブルであるが故にその数は制限される。
今回の記事を是非、お役立てくださいますと幸いです。
最後までお読みいただきありがとうございました。