コース進捗 コース目次 24レッスン中 24件を公開中
Pythonの基礎
データとコレクション
信頼できるプログラムを作る
オブジェクトでモデル化する
プロフェッショナルなPython
上級Python
リストはトレー、タプルは封をしたカード
値が1つだけでは足りないことがあります。学習トピックをいくつも並べたり、7日分の記録を持ったり、(曜日, 分数)という1件の記録を作ったりしたいからです。Pythonには、順序のあるまとまりを作る2つの便利な形があります。
- リスト 中身を出し入れできる
- タプル 位置の役目を固定する
- シーケンス 順番どおりに読める
どちらもシーケンスです。要素の順序を保ち、位置は0から始まり、len()、in、インデックス、スライスを使えます。
topics = ["文字列", "リスト", "辞書"]
print(len(topics))
print(topics[0])
print(topics[-1])
print(topics[1:3])
print("リスト" in topics)
3
文字列
辞書
['リスト', '辞書']
True
スライスは終了位置の直前で止まり、新しい外側のシーケンスを作ります。存在しない1つの位置はIndexErrorですが、スライスは末尾を越えても安全です。
リストは増やしたり減らしたりできる
リストは角かっこで書き、**変更可能(mutable)**です。同じリストの中身を変えられます。
queue = ["文字列", "リスト"]
queue.append("タプル")
queue.extend(["辞書", "集合"])
queue.insert(1, "復習")
print(queue)
['文字列', '復習', 'リスト', 'タプル', '辞書', '集合']
append(x)は1つの要素を加えます。extend(things)はthings内の要素を1つずつ加えます。["A", "B"]をappendすれば、入れ子のリスト1つです。extendなら文字列2つが追加されます。
値を指定して消すならremove()、位置を指定して消し、消した値も受け取るならpop()です。
queue = ["文字列", "復習", "リスト"]
queue.remove("復習")
finished = queue.pop(0)
print(finished)
print(queue)
文字列
['リスト']
境界の注意:remove("ない値")はValueError、空リストのpop()はIndexErrorです。値がないことも普通にあるなら、先にinや空でないことを確認します。
2枚の名札が同じトレーを指すことがある
代入してもリストはコピーされません。同じトレーへ別の名札を付けるだけです。
-
リストは1つ
["文字列", "リスト"] - plan 1枚目の名札
- alias 2枚目の名札
- 変更は1回 どちらからも見える
alias = planでは、1つの変更可能なオブジェクトを共有します。plan = ["文字列", "リスト"]
alias = plan
snapshot = plan.copy()
alias.append("タプル")
print(plan)
print(snapshot)
print(alias is plan)
print(snapshot is plan)
['文字列', 'リスト', 'タプル']
['文字列', 'リスト']
True
False
isは「まったく同じオブジェクト?」、==は「中身が等しい?」という質問です。copy()やplan[:]は、新しい外側のリストを作ります。ただし、これは浅いコピーです。入れ子の変更可能な要素は共有されます。
week = [["月", 20], ["火", 30]]
snapshot = week.copy()
week.append(["水", 40])
week[0][1] = 99
print(snapshot)
print(week)
[['月', 99], ['火', 30]]
[['月', 99], ['火', 30], ['水', 40]]
新しい水曜日のトレーはweekだけにあります。一方、2つの外側のリストは同じ月曜日の内側トレーを指し続けるため、どちらにも99が見えます。
タプルは1件の記録の形を守る
タプルは通常、丸かっこで書きます。変更不可能なシーケンスなので、append()、remove()、要素への代入はできません。
- 月曜日 位置0
- 45分 位置1
- 固定の組 2つの役目を保つ
record = ("月曜日", 45)
day, minutes = record
print(day)
print(minutes)
月曜日
45
通常のアンパックでは、要素と受け取る名前の個数を一致させます。1要素のタプルにはカンマが必要です。("リスト",)はタプル、("リスト")は文字列です。タプル自体は変わりませんが、その中に変更可能なリストがあれば、そのリストは変えられます。タプルは「内側まですべて凍らせる箱」ではありません。
ミニ制作:3日間の学習記録
study_log.pyを作ります。組み込み機能だけで動く完成プログラムです。曜日の記録は固定のタプル、記録全体とトピック待ち行列はリストです。スナップショットによって、別名ではなくコピーを作れたことも確かめます。
study_log = [
("月曜日", 20),
("火曜日", 35),
("水曜日", 35),
]
topic_queue = ["文字列", "リスト", "辞書"]
original_plan = topic_queue.copy()
finished = topic_queue.pop(0)
topic_queue.append("集合")
total = 0
for day, minutes in study_log:
total += minutes
print(f"{day}:{minutes}分")
average = total / len(study_log)
print(f"合計:{total}分")
print(f"平均:{average:.1f}分")
print(f"完了:{finished}")
print(f"最初:{original_plan}")
print(f"現在:{topic_queue}")
print(f"スナップショットは安全:{original_plan == ['文字列', 'リスト', '辞書']}")
python3 study_log.pyで実行し、次の出力を確認します。
月曜日:20分
火曜日:35分
水曜日:35分
合計:90分
平均:30.0分
完了:文字列
最初:['文字列', 'リスト', '辞書']
現在:['リスト', '辞書', '集合']
スナップショットは安全:True
このプログラムには必ず3件あるので、平均の割り算は安全です。空の記録も許すなら、割る前に「空の平均」をどうするか決める必要があります。
3つの小さなミッション
- appendかextendか。
["タプル", "集合"]を両方の方法で追加し、どちらが入れ子になるか予想します。 - コピー探偵。
[["月", 10]]をコピーしてから、内側の10を変更します。両方から変化が見える理由を説明します。 - タプル調査。
(topic, minutes, done)を作り、3つの名前へアンパックして1文を表示します。
第7章へ進む準備
- インデックスとスライスでシーケンスを読める
append()、extend()、remove()、pop()を使い分けられる- 別名参照がリストの変更を共有する理由を説明できる
- 浅いコピーを作り、入れ子の境界を説明できる
- 変わるリストと、形を固定するタプルを選べる
- 1要素のタプルを作り、記録を正しくアンパックできる
- 学習記録を実行し、「スナップショットは安全:True」を確認できる
次章では、番号の代わりに意味のある辞書のキーを使い、「同じものは1つだけ」が大切な場面で集合を使います。