元組是一種 不可變 的集合,其中的項目依 順序 排列。
和大多數集合一樣(請見內建的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,)
字串是可疊代的,所以把單一str當作引數傳給tuple()建構子,可能會出現意想不到的結果:
# String elements (characters) are iterated through and added to the tuple
>>> multiple_elements_string = tuple("Timbuktu")
('T', 'i', 'm', 'b', 'u', 'k', 't', 'u')
其他可疊代物件的元素也會被逐一加入:
>>> 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()建構子只接受 可疊代物件(或什麼都不接受)當作引數,所以用字面值的方式建立單元素元組要簡單得多。
>>> no_elements = ()
()
>>> one_element = ("Guava",)
("Guava",)
一般來說,建立tuple字面值時不需要括號,只需要逗號。
不過,在大多數情況下,使用(<element_1>, <element_2>)被認為可讀性更高。
在容易產生歧義的情況下也需要括號,例如空元組、單元素元組,或是函式以元組作為引數時。
>>> 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(從零開始),或從**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.
元組經常被當作 記錄 使用,裡面包含的資料在 組織上 或 概念上 是同質的,並被視為單一的資訊單位,即使個別元素的資料型態是 異質的。
>>> 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來提供類似的具名屬性功能,不過各有其優缺點。