學習軌道
/
Python
Python
/
練習
/
Tisbury 尋寶之旅
Tisbury 尋寶之旅

Tisbury 尋寶之旅

學習練習

簡介

在 Python 中,元組 是一種_不可變_、依_序列_排列的項目集合。 和大多數集合一樣,tuples可以存放任何(或多種)資料型態,包括其他的tuples。 元組支援所有常見序列操作,但不支援可變序列操作。

可以使用for item in <tuple>語法疊代元組中的元素。 如果同時需要元素的索引和值,可以使用for index, item in enumerate(<tuple>)。 和任何序列一樣,可以使用_方括號標記法_存取tuples內的元素,索引從左邊算起是0-based index,從右邊算起則是-1-based index。 也可以使用切片標記法(<tuple>[<start>:<stop>:<step>])複製整個元組或其中的一部分。

元組的建立

元組可以用多種方式建立,可以使用tuple(<iterable>)類別建構子,也可以使用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)
將元組宣告為_字面值_:

由於tuple(<iterable>)建構子只接受_可迭代物件_(或什麼都不接受)當作引數,所以用字面值的方式建立只有一個元素的元組要容易得多。

>>> no_elements = ()
()

>>> one_element = ("Guava",)
("Guava",)

巢狀資料結構可以作為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')

存取元組內的元素

可以使用_方括號標記法_存取tuple內的元素,索引從左邊算起是0-based index,從右邊算起則是-1-based index。

student_info = ("Alyssa", "grade 3", "female", 8 )

#gender is at index 2 or index -2
>>> student_gender = student_info[2]
'female'

>>> student_gender = student_info[-2]
'female'

#name is at index 0 or index -4
>>> student_name = student_info[0]
Alyssa

>>> student_name = student_info[-4]
Alyssa

疊代元組的元素

可以使用for item in <tuple>語法,在迴圈中_疊代_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.

檢查元素是否在元組中

可以使用in運算子檢查某個元素是否在tuple中。

>>> multiple_elements_list = tuple(["Parrot", "Bird", 334782])
("Parrot", "Bird", 334782)

>>> "Parrot" in multiple_elements_list
True

說明

Azara 和 Rui 是同隊夥伴,正在參加一場海盜主題的尋寶活動。 其中一人拿著一份寶物清單和地圖座標,另一人則拿著一份地點名稱清單和地圖座標。 他們也拿到了空白地圖,上面標示著起點「你在這裡」。


Azara 的清單 Rui 的清單
寶物 座標
Amethyst Octopus 1F
Angry Monkey Figurine 5B
Antique Glass Fishnet Float 3D
Brass Spyglass 4B
Carved Wooden Elephant 8C
Crystal Crab 6A
Glass Starfish 6D
Model Ship in Large Bottle 8A
Pirate Flag 7F
Robot Parrot 1C
Scrimshawed Whale Tooth 2A
Silver Seahorse 4E
Vintage Pirate Hat 7E
地點名稱 座標 象限
Seaside Cottages ("1", "C") Blue
Aqua Lagoon (Island of Mystery) ("1", "F") Yellow
Deserted Docks ("2", "A") Blue
Spiky Rocks ("3", "D") Yellow
Abandoned Lighthouse ("4", "B") Blue
Hidden Spring (Island of Mystery) ("4", "E") Yellow
Stormy Breakwater ("5", "B") Purple
Old Schooner ("6", "A") Purple
Tangled Seaweed Patch ("6", "D") Orange
Quiet Inlet (Island of Mystery) ("7", "E") Orange
Windswept Hilltop (Island of Mystery) ("7", "F") Orange
Harbor Managers Office ("8", "A") Purple
Foggy Seacave ("8", "C") Purple

不過事情有點雜亂:Azara 的座標格式和排序似乎和 Rui 的不同,他們必須在兩份清單之間來回查看,才能弄清楚哪些寶物對應哪些地點。 身為剛起步的 Python 愛好者,他們來找你幫忙寫一個小程式(其實就是幾個函式),好把尋寶資訊整理得更有條理。

1. 擷取座標

實作get_coordinate()函式,它會接收 Azara 清單中的一個(treasure, coordinate)配對,並只回傳擷取出的地圖座標。

>>> get_coordinate(('Scrimshawed Whale Tooth', '2A'))
2A

2. 格式化座標

實作convert_coordinate()函式,它會接收格式為 "2A" 的座標,並回傳格式為("2", "A")的元組。

>>> convert_coordinate("2A")
("2", "A")

3. 比對座標

實作compare_records()函式,它會接收一個(treasure, coordinate)配對和一個(location, coordinate, quadrant)紀錄,並比對兩者的座標。 如果座標「相符」,就回傳 True;如果不同,則回傳 False。 視需要重新格式化座標,以便準確比對。

>>> compare_records(('Brass Spyglass', '4B'), ('Seaside Cottages', ('1', 'C'), 'blue'))
False

>>> compare_records(('Model Ship in Large Bottle', '8A'), ('Harbor Managers Office', ('8', 'A'), 'purple'))
True

4. 合併相符的紀錄

實作create_record()函式,它會接收 Azara 清單中的一個(treasure, coordinate)配對和 Rui 清單中的一個(location, coordinate, quadrant)紀錄,如果座標相符,就回傳(treasure, coordinate, location, coordinate, quadrant)。 如果座標_不_相符,則回傳字串 "not a match"。 視需要重新格式化座標,以便準確比對。

>>> create_record(('Brass Spyglass', '4B'), ('Abandoned Lighthouse', ('4', 'B'), 'Blue'))
('Brass Spyglass', '4B', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')

>>> create_record(('Brass Spyglass', '4B'), ('Seaside Cottages', ('1', 'C'), 'blue'))
"not a match"

5.「整理」並為所有紀錄製作報告

整理 Azara 和 Rui 合併後的紀錄,讓每筆紀錄只留下一組座標。製作一份報告,讓他們能看到一份清單,列出所有需要標到地圖上的東西。 實作clean_up()函式,它會接收一個由元組組成的元組(兩份清單的所有內容),走訪_外層_元組,從每個_內層_元組中捨去不需要的座標,並將每一筆加入 'report'。 將 'report' 格式化並回傳,使每一行都有一筆整理好的紀錄。

>>> clean_up((('Brass Spyglass', '4B', 'Abandoned Lighthouse', ('4', 'B'), 'Blue'), ('Vintage Pirate Hat', '7E', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange'), ('Crystal Crab', '6A', 'Old Schooner', ('6', 'A'), 'Purple')))

"""
('Brass Spyglass', 'Abandoned Lighthouse', ('4', 'B'), 'Blue')\n
('Vintage Pirate Hat', 'Quiet Inlet (Island of Mystery)', ('7', 'E'), 'Orange')\n
('Crystal Crab', 'Old Schooner', ('6', 'A'), 'Purple')\n
"""
透過 GitHub 編輯 連結會在新視窗或分頁中開啟
Python Exercism

準備好開始 Tisbury 尋寶之旅 了嗎?

註冊 Exercism,透過 17 個概念146 個練習 和真人引導來學習並精通 Python,全部免費。