タプルは、順序 を持つ _イミュータブル_な要素の集まりです。
ほとんどのコレクション(組み込みのlist、dict、setを参照)と同じように、tuplesは任意の(あるいは複数の)データ型を保持できます。他のtuplesも含まれます。
タプルの要素は、for item in <tuple>という構文で繰り返し処理できます。
要素のインデックスと値の両方が必要なときは、for index, item in enumerate(<tuple>)を使います。
シーケンスと同じように、tuples内の要素には_ブラケット記法_でアクセスできます。左からは0-based indexの番号、右からは-1-based indexの番号を指定します。
タプルは、_スライス記法_や<tuple>.copy()を使って全体または一部をコピーでき、すべての共通のシーケンス操作をサポートします。
_イミュータブル_であるため、tuplesはミュータブルなシーケンス操作をサポートしません。
タプルは、他のコレクション型に比べて必要なメモリがとても少なく、インデックスを使ったアクセス時間は一定(O(1))です。
ただし、一度作成するとサイズ変更や並べ替え、変更ができないため、データの頻繁な変更や更新が必要な場面では柔軟性に欠けます。
頻繁な更新や拡張が必要なら、list、collections.deque、array.arrayのほうが適したデータ構造かもしれません。
タプルはいくつかの方法で作成できます。tupleクラスのコンストラクターを使う方法と、(<element_1>, <element_2>)(tupleリテラル)という宣言を使う方法があります。
tuple()コンストラクターを引数なしで、または_イテラブル_を渡して使う:>>> no_elements = tuple()
()
# The constructor *requires* an iterable, so single elements must be passed in a list or another tuple.
>>> one_element = tuple([16])
(16,)
文字列はイテラブルなので、tuple()コンストラクターの引数にstrを1つだけ渡すと、意外な結果になることがあります:
# String elements (characters) are iterated through and added to the tuple
>>> multiple_elements_string = tuple("Timbuktu")
('T', 'i', 'm', 'b', 'u', 'k', 't', 'u')
他のイテラブルも、要素が1つずつ追加されます:
>>> multiple_elements_list = tuple(["Parrot", "Bird", 334782])
("Parrot", "Bird", 334782)
>>> multiple_elements_set = tuple({2, 3, 5, 7, 11})
(2,3,5,7,11)
dictを繰り返し処理するときのデフォルトは、キーに対するものです。
辞書から作るタプルにキーと値の両方を含めるには、<dict>.items()を使います。これは(key、value)というtuplesのイテレーターを返します。
>>> source_data = {"fish": "gold", "monkey": "brown"}
>>> multiple_elements_dict_1 = tuple(source_data)
('fish', 'monkey')
>>> multiple_elements_dict_2 = tuple(source_data.items())
(('fish', 'gold'), ('monkey', 'brown'))
tuple()コンストラクターは引数として_イテラブル_(または何も)しか受け取らないため、1つの要素を持つタプルはリテラルで作るほうがずっと簡単です。
>>> no_elements = ()
()
>>> one_element = ("Guava",)
("Guava",)
一般的に、tupleリテラルを作るのに括弧は必要ありません。必要なのはカンマだけです。
ただし、ほとんどの場合、(<element_1>, <element_2>)と書くほうが読みやすいとされています。
また、空のタプルや要素が1つのタプル、関数がタプルを引数に取る場合など、曖昧さが生じる場面では括弧が必要です。
>>> elements_separated_with_commas = "Parrot", "Bird", 334782
("Parrot", "Bird", 334782)
>>> elements_with_commas_and_parentheses = ("Triangle", 60, 60, 60)
("Triangle", 60, 60, 60)
tupleの要素には、他のtuplesをはじめ、さまざまなデータ構造を含めることができます。
>>> nested_data_structures = ({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird"))
({"fish": "gold", "monkey": "brown", "parrot" : "grey"}, ("fish", "mammal", "bird"))
>>> nested_data_structures_1 = (["fish", "gold", "monkey", "brown", "parrot", "grey"], ("fish", "mammal", "bird"))
(["fish", "gold", "monkey", "brown", "parrot", "grey"], ("fish", "mammal", "bird"))
タプルはプラス+演算子で連結できます。各tupleが展開され、新しく結合されたtupleが作られます。
>>> new_via_concatenate = ("George", 5) + ("cat", "Tabby")
("George", 5, "cat", "Tabby")
#likewise, using the multiplication operator * is the equivalent of using + n times
>>> first_group = ("cat", "dog", "elephant")
>>> multiplied_group = first_group * 3
('cat', 'dog', 'elephant', 'cat', 'dog', 'elephant', 'cat', 'dog', 'elephant')
タプル内の要素は(他のシーケンス型であるstrやlistと同じように)、ブラケット記法_でアクセスできます。
インデックスは、left --> right(0から始まる)でも、right --> left(-1から始まる_)でもかまいません。
タプルは、_スライス記法_や<tuple>.copy()を使って、全体または一部をコピーすることもできます。
>>> student_info = ("Alyssa", "grade 3", "female", 8)
#name is at index 0 or index -4
>>> student_name = student_info[0]
Alyssa
>>> student_name = student_info[-4]
Alyssa
#age is at index 3 or index -1
>>> student_age_1 = student_info[3]
8
>>> student_age_2 = student_info[-1]
8
タプル内の要素は、for item in <tuple>構文を使ってループで_繰り返し処理_できます。
インデックスと値の両方が必要なときは、for index, item in enumerate(<tuple>)を使います。
>>> student_info = ("Alyssa", "grade 3", "female", 8)
>>> for item in student_info:
... print(item)
...
Alyssa
grade 3
female
8
>>> for index, item in enumerate(student_info):
... print("Index is: " + str(index) + ", value is: " + str(item) + ".")
...
Index is: 0, value is: Alyssa.
Index is: 1, value is: grade 3.
Index is: 2, value is: female.
Index is: 3, value is: 8.
タプルは、_組織的_または_概念的_に均質で、1つの情報単位として扱われるデータを含む_レコード_としてよく使われます。個々の要素が_異種の_データ型であってもかまいません。
>>> student_info = ("Alyssa", "grade 3", "female", 8)
タプルは、hashability、setへの格納、辞書のキーの作成など、均質でイミュータブルなデータのシーケンスが必要なときにも使われます。
tuplesはほとんどの場合_イミュータブル_ですが、_任意の_データ構造やオブジェクトを含めることができるため、いずれかの要素が_ミュータブルな型_である場合、_ミュータブルになる_ことがあります。
tupleの中でミュータブルなデータ型を使うと、それを含むtupleはハッシュ化できなくなります。
>>> cmyk_color_map = {
(.69, .3, .48, .1) : ("Teal 700", (59, 178, 146), 0x3BB292),
(0, .5, 1, 0) : ("Pantone 151", (247, 127, 1), 0xF77F01),
(.37, .89, 0, .44) : ("Pantone 267", (89, 16, 142), 0x59108E),
(0, 1, .46, .45) : ("Pantone 228", (140, 0, 76), 0x8C004C)
}
>>> unique_rgb_colors = {
(59, 178, 146),
(247, 127, 1),
(89, 16, 142),
(140, 0, 76),
(76, 0, 140)
}
>>> teal_700 = hash((59, 178, 146))
>>> teal_700 = hash(("Pantone 228", [(140, 0, 76), 0x8C004C]))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
タプルは_レコード_としてよく使われますが、その中のデータには_位置_や_インデックス_でしかアクセスできません。
collectionsモジュールのnamedtuple()クラスは、基本的なタプルの機能を拡張し、要素に_名前_でアクセスできるようにします。
また、dataclassを利用して、同様に名前付きの属性でアクセスする機能を提供することもできます。これにはいくつかの長所と短所があります。