辞書を走査

このレッスンで作るもの — 辞書のキーと値を items() で全部取り出し、キー = 値 の形に並べた文字列を組み立てます。

辞書を走査する

前回は辞書を組み立てました。今度は中身を最初から最後までたどります。この「全部を順番に見る」ことを 走査 と呼びます。

辞書をそのまま for に渡すと、取れるのは キーだけ です。

record = {"name": "りんご", "price": 120, "category": "食費"} for key in record: print(key)

表示は namepricecategory の 3 行です。値がほしければ record[key] と書いて取りに行きます。動きますが、毎回取りに行くのは手間です。

items でキーと値を同時に取る

record.items() を使うと、キーと値の組が順番に取れます。for の変数を 2 つ書くのがポイントです。

record = {"name": "りんご", "price": 120, "category": "食費"} for key, value in record.items(): print(key, value)

1 周目は key"name"value"りんご"、2 周目は "price"120、3 周目は "category""食費" になります。第 5 章の enumeratezip と同じ、変数を 2 つ並べる書き方です。

items()() を忘れて record.items と書くと、走査ではなくメソッドそのものを指してしまい、for の中で意図しない動きになります。かっこまでが名前だと思って書きます。

キーだけほしいときは record.keys()、値だけほしいときは record.values() もあります。3 つの使い分けは下記のとおりです。

diagram (will load when visible)

並ぶ順番は決まっている

辞書は「順番を持たない」と説明されることがありますが、いまの Python では 書いた順、入れた順 が保たれます。{"name": ..., "price": ..., "category": ...} と作った辞書を items() で回せば、必ず namepricecategory の順です。

順番が保証されるおかげで、辞書から作った文字列は毎回同じ並びになります。テストで結果を比較できるのはこの性質のためです。

動きを追ってみる

{"name": "りんご", "price": 120} から name = りんごprice = 120 の 2 行を作る流れを追います。

  1. 空のリスト lines を用意する
  2. 1 周目で key"name"value"りんご" になり、"name = りんご"append する
  3. 2 周目で "price = 120"append する
  4. "\n".join(lines) で 2 行を改行でつなぐ
def record_lines(record): lines = [] for key, value in record.items(): lines.append(f"{key} = {value}") return "\n".join(lines)

f"{key} = {value}" は第 2 章の f-string です。value120 のような int でも、f-string の中では自動的に文字列として埋め込まれるので str() は要りません。

"\n".join(lines) は「リストの各要素を改行でつなぐ」という意味です。要素が 1 つなら改行は入らず、空リストなら空文字 "" が返ります。末尾に余計な改行が付かないのが join の便利なところです。

join は「区切り文字.join(リスト)」の順で書きます。lines.join("\n") は逆で、エラーになります。つなぐ側が主語だと覚えます。

よくある間違い

  1. for key, value in record と書くitems() を付けずに 2 つ受け取ろうとすると ValueError になります。辞書をそのまま回すと 1 周ごとにキーが 1 つ返るだけなので、2 つに分けられません。
  2. + でつなぐときに int を混ぜるkey + " = " + valuevalue120 だと TypeError です。f-string を使うか str(value) で変換します。
  3. 末尾に改行を足してしまう — ループの中で + "\n" を付けると最後の行にも改行が残ります。join を使えばこの問題は起きません。

やってみよう

関数 record_lines(record) を実装してください。辞書 recorditems() で走査し、1 組ごとに キー = 値 という 1 行を作って、改行 \n でつないだ文字列を return します。

= の前後には半角スペースを 1 つずつ入れます。末尾に改行は付けません。空の辞書 {} を渡されたときは空文字 "" を返してください。キーの並びは辞書に入っている順のままにし、並べ替えはしません。

要件

  1. 関数名は record_lines で、引数は record の1つ
  2. items() でキーと値を同時に取り出して走査する
  3. 1行は「キー = 値」の形で、= の前後に半角スペースを1つずつ入れる
  4. 行の区切りは改行で、末尾には改行を付けない。空の辞書のときは空文字を返す

入出力例

record_lines({"category":"食費","name":"りんご","price":120}) → "name = りんご price = 120 category = 食費" record_lines({"name":"ノート","price":200}) → "name = ノート price = 200" record_lines({"price":0})"price = 0" record_lines({})"" record_lines({"category":"娯楽","name":"映画","price":1800}) → "category = 娯楽 name = 映画 price = 1800"

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.py
main.py
学習モード

メモ

辞書を走査

⌘S で保存