Python超入門⑥ リストと辞書でデータをまとめよう
listとdictを使い、複数の値や、名前と値の組み合わせをまとめて扱います。
3人分の点数を保存したいとき、score1、score2、score3 と変数を作る方法もあります。でも、30人になったら大変ですよね。
そこで使うのがリストと辞書です。今回は、点数の一覧から始めて、「名前と点数」を人ごとにまとめられるところまで進めます。
準備:順番で選ぶか、名前で選ぶか
Python 3で各コード例を別々に実行してください。変数、if文、for文を使います。
最初に、2つの使い分けだけ押さえましょう。
| したいこと | 向いているもの | 取り出し方 |
|---|---|---|
| 点数や商品を順番に並べる | リスト list |
何番目かを指定する |
| 1人の名前・点数などをまとめる | 辞書 dict |
"name" などのキーを指定する |
キーは、辞書から値を取り出すための目印です。言葉だけだとまだ分かりにくいので、実際に作ってみましょう。
1. リストで複数の点数をまとめる
scores = [80, 95, 70]
print(scores)
print(scores[0])
print(scores[1])
print(len(scores))
[80, 95, 70]
80
95
3
[ ] の中へ値をカンマで区切って並べると、リストになります。中に入っている1つひとつの値を要素と呼びます。
scores[0] の0は、要素の位置を示すインデックスです。ここは最初につまずきやすいところですが、最初の位置は1ではなく0です。
| インデックス | 0 | 1 | 2 |
|---|---|---|---|
| 値 | 80 | 95 | 70 |
len(scores) は要素の個数を返します。この例では3個ですが、使えるインデックスは0から2です。
最後の位置を超えるとどうなる?
このリストに対して scores[3] を使うと、存在しない4個目を探すため IndexError になります。
「個数は3だから3番を取ればよい」と考えると、1つずれるんですね。最後の要素は、この例なら scores[2]、末尾から指定するなら scores[-1] で取り出せます。ただし、空のリストではどちらも取り出せません。
2. 値の追加と変更は、操作が違う
scores = [80, 95]
scores.append(70)
print(scores)
scores[0] = 85
print(scores)
[80, 95, 70]
[85, 95, 70]
append() はリストの末尾へ要素を追加するメソッドです。メソッドは、このように scores.append(...) と、対象の後ろへドットを付けて使う処理です。
一方、scores[0] = 85 は、すでにある0番目の値を変更しています。個数は増えません。
- 最初は2個の点数
- appendで70を追加し、3個になる
- 0番目の80を85へ変更する
- 個数は3個のまま
scores = scores.append(70) とは書かないでください。appendは元のリストを変更し、戻り値は None です。代入すると、scoresからリストを扱えなくなります。リストの操作の公式説明
3. 平均点を計算してみよう
scores = [80, 95, 70]
total = 0
for score in scores:
total += score
if len(scores) > 0:
average = total / len(scores)
print(f"平均は{average:.1f}点です")
else:
print("点数がまだありません")
平均は81.7点です
score は今回取り出した1人分、scores は点数全体です。よく似た名前ですが役割が違うので、複数形の s にも注目してください。
| 今回のscore | 足した後のtotal |
|---|---|
| 80 | 80 |
| 95 | 175 |
| 70 | 245 |
245を3で割ると、81.666…です。f文字列の :.1f は、小数点以下1桁で表示する指定。計算に使う average 自体を81.7へ変更するわけではありません。
空のリストも考える理由
scores = [] は、要素がないリストです。このとき len(scores) は0になります。
0で割ることはできないので、平均を計算する前に個数を確認しています。データが必ず入っている例だけでなく、「まだ何も入力されていない」状態も考えると、実際のアプリに近づきますね。
4. 辞書は、キーと値の組み合わせ
student = {
"name": "Aoi",
"score": 80,
"passed": True
}
print(student["name"])
print(student["score"])
Aoi
80
辞書は { } で囲み、キー: 値 の組をカンマで区切って並べます。
"name"というキーに、"Aoi"という値"score"というキーに、80という値"passed"というキーに、Trueという値
リストのように「2番目は何だったっけ」と思い出さなくても、キーで取り出せるのが便利なところです。
ここではキーに文字列を使っています。Pythonの辞書では他の種類も使えますが、使えるものには条件があります。まずは、この文字列キーの使い方から覚えましょう。辞書の公式説明
5. キーがある場合と、ない場合
値を変更・追加する
student = {"name": "Aoi", "score": 80}
student["score"] = 90
student["class"] = "A"
print(student["score"])
print(student["class"])
90
A
"score" は存在するので値の変更、"class" は新しいキーなので追加です。同じキーに別の値を代入すると、前の値が置き換わります。
必ずある情報と、なくてもよい情報を分ける
student = {"name": "Aoi", "score": 80}
print(student["name"])
print(student.get("nickname", "未設定"))
Aoi
未設定
student["nickname"] と直接取り出すと、キーがないため KeyError になります。get() なら、キーがないときの代わりの値を指定できます。
ただし、「エラーになるから全部getにする」とは限りません。必須の情報が欠けているなら、問題として気づく方がよいこともあります。ニックネームのような任意の項目なのか、名前のような必須の項目なのかで使い分けましょう。
6. リストの中へ辞書を入れる
ここで2つを組み合わせます。1人の情報を辞書にし、その辞書をリストへ並べます。
students = [
{"name": "Aoi", "score": 80},
{"name": "Ren", "score": 65}
]
for student in students:
print(f"{student['name']}: {student['score']}点")
Aoi: 80点
Ren: 65点
1周目の student はAoiの辞書、2周目はRenの辞書です。
例えば students[0]["score"] は、まず0番目の辞書を取り出し、その辞書の "score" を取り出すので80になります。一度に読めなければ、students[0] と ["score"] を分けて考えてください。
7. 代入しただけでは、リストはコピーされない
値をまとめられるようになったら、もう1つ知っておきたいことがあります。
scores = [80, 95]
other_scores = scores
other_scores[0] = 0
print(scores)
[0, 95]
「変更したのはother_scoresなのに!」と驚くところです。この代入では、2つの名前が同じリストを指しています。別々のリストを作ったわけではありません。
数値だけの、この例のリストを独立させたいなら次のようにします。
scores = [80, 95]
other_scores = scores.copy()
other_scores[0] = 0
print(scores)
print(other_scores)
[80, 95]
[0, 95]
ただし、copy() は内側の辞書やリストまで再帰的に複製する方法ではありません。リストの中へ辞書を入れた場合などは、内側のデータが共有されることがあります。今回は「代入だけでは別物にならない」ところを押さえておきましょう。
8. 練習:3つの商品をまとめて表示しよう
商品名と価格を持つ辞書を3個作り、リストへ入れてください。for文ですべての商品名を表示します。
模範解答
products = [
{"name": "ノート", "price": 180},
{"name": "ペン", "price": 120},
{"name": "消しゴム", "price": 100}
]
for product in products:
print(product["name"])
ノート
ペン
消しゴム
価格は説明用に決めた例です。
解説
productsは、3個の辞書を持つリストです。- for文が、辞書を1個ずつ
productへ渡します。 product["name"]が、その商品の名前を取り出します。- printで表示し、次の商品へ進みます。
価格も表示する改造なら、for文の中を print(f"{product['name']}: {product['price']}円") に変更します。最初の行は「ノート: 180円」です。辞書全体ではなく、必要なキーの値を選んでいる点が大切です。
まとめ:何を一まとまりにしたいかで選ぼう
順番に並べたい値にはリスト、名前付きの項目をまとめたいときには辞書。さらに、1人分を辞書、クラス全員をリストにするように組み合わせられます。
最初から複雑な形にせず、1人分、2人分と増やして表示を確かめると、入れ子の構造も読みやすくなります。
前の記事:Python超入門⑤ 関数