全6877文字

タプル

 タプルにするときは、丸カッコ()を用います。要素が1つのとき、最後のカンマを省略すると数値になります。

# タプルの宣言方法
tuple_A = (1, 2, 3)
tuple_B = 1, 2,
tuple_C = (1)
# tuple_Aの型出力
print(tuple_A , type(tuple_A))
# tuple_Bの型出力
print(tuple_B, type(tuple_B))
# tuple_Cの型出力
print(tuple_C , type(tuple_C))

 これを実行すると以下の出力になります。

(1, 2, 3) class<'tuple'>
(1, 2) class<'tuple'>
1 class<'int'>

 また、リストと同じように型が異なる要素を含むタプルを作ったり、特定の要素を参照したりすることもできます。

tuple_D = (10, '10', 'A', 'あ', 1, 2)
# インデックス1と-1の要素を指定
print(tuple_D[1], tuple_D[-1]) 
# インデックス1~3と、-2以降の要素を指定
print(tuple_D[1:3], tuple_D[-2: ]) #('10', 'A') (1, 2)
# インデックス1から2つおきの要素を指定
print(tuple_D[1::2]) #('10', 'あ', 2)

 これを実行すると、以下のようになります。

'10' 2
('10', 'A') (1, 2)
('10', 'あ', 2)

 これだけ見ると、タプルとリストの違いはカッコの形だけに思えます。しかしタプルはリストとは異なり、一度生成したらオブジェクトIDを変えずに「要素の追加・変更・削除ができない」という特徴があります。

 Pythonでは、オブジェクトという単位でデータを扱います。配列を含む変数も、すべてオブジェクトです。1つ1つのオブジェクト識別するための識別子が、オブジェクトIDです。

 タプルの要素を変更すると、オブジェクトIDが変わります。つまり、別のオブジェクトが新たに作られるということです。

 以下のコードを見てみましょう。オブジェクトIDは「id」という関数で調べられます。

#リストの場合(list_1とlist_2を生成)
list_1 = list2 = ['山田', '田中']
print(id(list_1), id(list_2)) #「1582792583176 1582792583176」が出力される
list_1 += ['佐藤', '鈴木']

#list1のオブジェクトIDを確認。変わっていないことが分かる。
print(list_1, id(list_1)) #「['山田', '田中', '佐藤', '鈴木'] 1582792583176」が出力される

#タプルの場合(taple_1とtaple_2を生成)
tuple_1 = tuple_2 = ('山田', '田中')
print(id(tuple_1), id(tuple_2)) #「1582792332808 1582792332808」が出力される
tuple_1 += ('佐藤', '鈴木')

#オブジェクトIDを確認。変わっていることが分かる。
print(tuple_1, id(tuple_1)) #「('山田', '田中', '佐藤', '鈴木') 1582794401976」が出力される

 それぞれ要素を追加する処理をしました。リストはオブジェクトIDが変わりませんが、タプルでは変化しています。

 オブジェクトIDが変化すると、混乱が起こりやすくなります。上のソースコードでは、リストの場合はlist_1とlist_2は同じオブジェクトを指していますが、タプルの場合はtuple_1とtuple_2でオブジェクトが異なることになります。どちらを参照するかで、処理の結果が変わってしまいます。

 また、タプルでは要素の上書きはできません。以下のコードを実行すると、「TypeError: 'tuple' object does not support item assignment」というエラーが出力されます。つまり、タプルは変更したくない変数の定義をするときなどに使うのが基本です。

alphabets = ("a", "b", "c", "d", "e", "f", "g", "h", "i", "j","k","l","m","n")
# 上書き
alphabets[0] = "A"   # TypeError: 'tuple' object does not support item assignment