リスト内包表記
「入れ物を作る、回す、入れる」を毎回書いている
条件に合う時刻だけを選び、1 時間後の時刻に変える処理を、これまでの書き方で比べます。
Python
hours = [8, 13, 10]
result = []
for hour in hours:
if hour < 12:
result.append(hour + 1)やっているのは「入れ物を作る」「回す」「合えば入れる」の 3 つで、条件のところ以外は毎回まったく同じです。この決まりきった形を 1 行に畳める記法が リスト内包表記 です。
Python
result = [hour + 1 for hour in hours if hour < 12]角かっこの中に for があるのが目印で、上のループと同じ [9, 11] ができます。短く書けるから偉いのではありません。角かっこを見た瞬間に「新しいリストを作っている」と伝わるところに価値があります。
左に何を書くかで、返るものが変わる
内包表記は 3 つの部品でできています。
Python
[ 式 for 変数 in もとのリスト if 条件 ]読む順番は書いてある順とは違います。まず for で何を回すかをつかみ、次に if で絞り込み、最後にいちばん左の 式 で「何を入れるか」を決めます。
この左の式が自由なところが要です。変数をそのまま書けば要素がそのまま入り、r["price"] のように書けば金額だけのリストになります。
Python
names = [r["name"] for r in records]
prices = [r["price"] for r in records if r["price"] >= 1000]1 つ目は全件の品名、2 つ目は 1000 円以上の金額です。if は書かなくても構いません。
元のリストは変わりません。内包表記も、スライスや sorted と同じ「新しく作って返す」仲間です。
if を左に書くと、別の意味になる
つまずきやすいのが if の位置です。絞り込みの if は for の うしろ に書きます。
Python
[r["name"] if r["price"] >= 1000 else "-" for r in records]こちらは第 3 章の三項演算子で、件数は減りません。条件に合わないものを捨てるのではなく、入れる値を切り替えているだけです。件数が変わってほしいのに変わらないときは、if の位置を疑います。
もう 1 つ、内包表記の中に append は書きません。[result.append(r) for r in records] と書くと、append の戻り値である None が並んだリストができます。入れる仕事は角かっこがやってくれます。
やってみよう
関数 only_food(records) を実装してください。支出の辞書が並んだリストから、category が "食費" の辞書だけを集めた新しいリストを return します。
まずは既習の for・if・append で書いて構いません。空のリストを用意し、1 件ずつ条件を調べ、合うものを追加しましょう。本文の内包表記で書く方法も選べます。内包表記を使うことは必須ではありません。取り出すのは金額や品名ではなく 辞書そのもの です。順番は元のままにし、該当が無いときは空リストを返します。
要件
- 関数名は only_food で、引数は records の1つ
- for・if・append、またはリスト内包表記で新しいリストを作る
- category が "食費" の辞書だけを、辞書のまま取り出す
- 元の並び順を保ち、該当が無いときは空リストを返す