プログラミング

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番目の値を変更しています。個数は増えません。

  1. 最初は2個の点数
  2. appendで70を追加し、3個になる
  3. 0番目の80を85へ変更する
  4. 個数は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"])
ノート
ペン
消しゴム

価格は説明用に決めた例です。

解説

  1. products は、3個の辞書を持つリストです。
  2. for文が、辞書を1個ずつ product へ渡します。
  3. product["name"] が、その商品の名前を取り出します。
  4. printで表示し、次の商品へ進みます。

価格も表示する改造なら、for文の中を print(f"{product['name']}: {product['price']}円") に変更します。最初の行は「ノート: 180円」です。辞書全体ではなく、必要なキーの値を選んでいる点が大切です。

まとめ:何を一まとまりにしたいかで選ぼう

順番に並べたい値にはリスト、名前付きの項目をまとめたいときには辞書。さらに、1人分を辞書、クラス全員をリストにするように組み合わせられます。

最初から複雑な形にせず、1人分、2人分と増やして表示を確かめると、入れ子の構造も読みやすくなります。

前の記事:Python超入門⑤ 関数

次の記事:Python超入門⑦ エラー処理とファイル保存

← 記事一覧へ戻る