reduce
このレッスンでできるようになること。functools.reduce を使って、リストを1つの値へ畳み込む集計を書けるようになります。
map は全部を変換し、filter は一部を残しました。reduce は「たくさんの値を1つにまとめる」道具です。左から順に2つずつ関数へ渡し、その結果を次の計算へ持ち回ります。標準の組み込み関数ではないので、使う前に import します。
from functools import reduce
amounts = [220, 640, 1280]
total = reduce(lambda acc, a: acc + a, amounts, 0)
print(total) # 2140第1引数の関数は、ここまでの計算結果 acc と次の要素を受け取り、新しい計算結果を返します。第3引数は初期値です。初期値を書いておくと、リストが空でもその値がそのまま返るので安全です。初期値を省くと空リストで TypeError になります。合計を出したいなら 0、掛け算なら 1 のように、その計算で「何もしていない状態」を初期値にします。
単純な合計なら sum(amounts) のほうが速くて読みやすく、実務でもそちらを選びます。reduce が本当に効くのは、合計以外の畳み込みです。たとえば最も高い支出を選ぶ、カテゴリごとの集計辞書を1つずつ育てる、といった処理は sum では書けません。
from functools import reduce
expenses = [
{"name": "牛乳", "amount": 220},
{"name": "書籍", "amount": 2035},
]
top = reduce(lambda acc, e: e if e["amount"] > acc["amount"] else acc, expenses)
print(top["name"]) # 書籍金額は int で持っておくと、何度畳み込んでも桁が揺れません。
要件
- functools から reduce を import する
- reduce に初期値 0 を渡して合計を畳み込む
- 空のリストを渡されたら 0 を返す
入出力例
total_amount([{"amount":220,"name":"牛乳"},{"amount":640,"name":"電車代"},{"amount":1280,"name":"コーヒー豆"}]) → 2140
total_amount([]) → 0
total_amount([{"amount":2035,"name":"書籍"},{"amount":165,"name":"ノート"}]) → 2200ヒント
編集 LuaGate編集部