トラック
/
Python
Python
/
演習
/
ティズベリーの宝探し
ティズベリーの宝探し

ティズベリーの宝探し

学習演習

はじめに

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,)

文字列はイテラブルなので、tuple()コンストラクターの引数に1つのstrを渡すと、意外な結果になることがあります:

# 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)
タプルを_リテラル_として宣言する:

tuple(<iterable>)コンストラクターは引数として_イテラブル_(または何もなし)しか受け取らないため、要素が1つのタプルはリテラル方式で作るほうがずっと簡単です。

>>> no_elements = ()
()

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

入れ子になったデータ構造も、他のtuplesを含め、tupleの要素として含めることができます:

>>> 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

タプルの要素を繰り返し処理する

tuple内の要素は、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.

タプルに要素が含まれているか確認する

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. 座標を取り出す

Azaraのリストから(treasure, coordinate)のペアを受け取り、取り出した地図上の座標だけを返すget_coordinate()関数を実装しましょう。

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

2. 座標を整形する

"2A"という形式の座標を受け取り、("2", "A")という形式のタプルを返すconvert_coordinate()関数を実装しましょう。

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

3. 座標を照合する

(treasure, coordinate)のペアと(location, coordinate, quadrant)のレコードを受け取り、それぞれの座標を比べるcompare_records()関数を実装しましょう。 座標が「一致」すれば**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. 一致したレコードを組み合わせる

Azaraのリストから(treasure, coordinate)のペアを、Ruiのリストから(location, coordinate, quadrant)のレコードを受け取り、座標が一致すれば(treasure, coordinate, location, coordinate, quadrant)を返すcreate_record()関数を実装しましょう。 座標が一致_しなければ_、文字列**"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()関数は、(両方のリストのすべて)を要素とするタプルのタプルを受け取ります。_外側_のタプルを順に処理し、それぞれの_内側_のタプルから不要な座標を除いて、「レポート」に追加していきます。 一行に一つのクリーンアップ済みレコードが並ぶように、「レポート」を整形して返します。

>>> 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

ティズベリーの宝探しを始める準備はできましたか?

Exercismに登録すれば、17個のコンセプト146個の演習、そして本物の人間によるメンタリングとともに、Pythonを学んでマスターできます。すべて無料です。