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 で持っておくと、何度畳み込んでも桁が揺れません。

要件

  1. functools から reduce を import する
  2. reduce に初期値 0 を渡して合計を畳み込む
  3. 空のリストを渡されたら 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編集部
main.py
学習モード

メモ

reduce

⌘S で保存