Pythonで「繰り返し処理」といえば、for文やwhile文が定番です。
しかし、もっとエレガントに、かつ機能的に複数の要素を一つにまとめたいときに便利なのが、reduce()
関数です。
「でも、何となく難しそう…」と感じる方も多いかもしれません。
そこで本記事では、Python初心者から中級者に向けて、reduce()
の使い方、メリット、具体的な応用例までを分かりやすく解説します。
reduce()関数とは?基本の仕組みを理解しよう

reduce()とは?
reduce()
関数は、リストなどの複数の要素を、1つの値に「まとめる(reduce)」処理を行います。
標準ライブラリのfunctools
モジュールに含まれており、まずインポートが必要です。
インポート方法
from functools import reduce
基本の書き方
構文
reduce(関数, シーケンス, 初期値)
- 関数:2つの引数を受け取って1つの値を返す関数
- シーケンス:リストやタプルなどの複数要素
- 初期値:計算の開始値(省略可能)
基本例:合計値を求める
コード例
from functools import reduce
numbers = [1, 2, 3, 4, 5]
total = reduce(lambda x, y: x + y, numbers)
print(total)
結果
15
動作の流れ
- 1 + 2 = 3
- 3 + 3 = 6
- 6 + 4 = 10
- 10 + 5 = 15
説明:lambda x, y: x + y
という関数を使って、リストの最初から最後まで順番に足し算を繰り返し、最終的に合計値を計算しています。
もう少し詳しい例
掛け算で階乗を計算
from functools import reduce
numbers = [1, 2, 3, 4, 5]
factorial = reduce(lambda x, y: x * y, numbers)
print(factorial) # 120 (5の階乗)
文字列の結合
from functools import reduce
words = ['Hello', 'World', 'Python']
sentence = reduce(lambda x, y: x + ' ' + y, words)
print(sentence) # Hello World Python
まとめ:reduce()
は「繰り返し+集約」の操作に最適な関数です。次の章では、reduce()
を使うことで得られるメリットや、for文との違いを比較してみましょう。
なぜreduce()を使うのか?for文との違いと使い分け

reduce()を使う主な理由
メリット
- コードが短くなる(1行で処理が完結する)
- 状態管理が不要(変数を都度更新しなくて良い)
- 関数型プログラミングに近い記述ができる
- バグが入りにくい(ループ変数の管理ミスがない)
実例:最大値の取得(reduce()版 vs for文版)
reduce()
版
from functools import reduce
numbers = [3, 7, 2, 9, 4]
max_num = reduce(lambda x, y: x if x > y else y, numbers)
print(max_num)
for文版
numbers = [3, 7, 2, 9, 4]
max_num = numbers[0]
for n in numbers[1:]:
if n > max_num:
max_num = n
print(max_num)
結果
9
比較ポイント
reduce()
版:1行で完結、変数の管理不要- for文版:変数
max_num
を更新し続ける必要がある
実例:数値のリストから偶数だけを合計
reduce()
版
from functools import reduce
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_sum = reduce(
lambda acc, x: acc + x if x % 2 == 0 else acc,
numbers,
0
)
print(even_sum) # 30 (2+4+6+8+10)
for文版
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_sum = 0
for n in numbers:
if n % 2 == 0:
even_sum += n
print(even_sum) # 30
説明:reduce()
版では初期値として0を指定し、偶数の場合のみ累積値に加算しています。
いつreduce()を使うべき?
reduce()
が適している場面
- 累積的な計算(合計、積、最大値など)
- リストを1つの値にまとめたいとき
- 状態を持たない処理
for文が適している場面
- 複雑な条件分岐がある場合
- 途中で処理を中断したい場合
- 複数の値を同時に更新したい場合
まとめ:for文との違いを理解すると、使いどころが明確になります。
次の章では、reduce()
を使ったより実用的なテクニックを紹介します。
実用的なテクニックと注意すべき落とし穴
初期値の指定
初期値を指定することで、より安全で柔軟な処理ができます。
初期値ありの例
from functools import reduce
# 空のリストでも安全
empty_list = []
result = reduce(lambda x, y: x + y, empty_list, 0)
print(result) # 0(エラーにならない)
# 階乗の計算
numbers = [2, 3, 4]
factorial = reduce(lambda x, y: x * y, numbers, 1)
print(factorial) # 24 (1 × 2 × 3 × 4)
初期値なしの危険性
from functools import reduce
# これはエラーになる
try:
empty_list = []
result = reduce(lambda x, y: x + y, empty_list)
except TypeError as e:
print(f"エラー: {e}")
複雑な処理の例
辞書のマージ
from functools import reduce
dicts = [
{'a': 1, 'b': 2},
{'c': 3, 'd': 4},
{'e': 5, 'f': 6}
]
merged = reduce(lambda x, y: {**x, **y}, dicts, {})
print(merged) # {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
ネストしたリストを平坦化
from functools import reduce
nested_list = [[1, 2], [3, 4], [5, 6]]
flattened = reduce(lambda x, y: x + y, nested_list, [])
print(flattened) # [1, 2, 3, 4, 5, 6]
よくある落とし穴と注意点
落とし穴1:読みにくいlambda式
悪い例
# 複雑すぎて読みにくい
result = reduce(lambda x, y: x if (x > y and x % 2 == 0) else (y if y % 2 == 0 else x), numbers)
良い例
def get_max_even(x, y):
"""偶数の最大値を取得"""
if x % 2 == 0 and y % 2 == 0:
return max(x, y)
elif x % 2 == 0:
return x
elif y % 2 == 0:
return y
else:
return x
result = reduce(get_max_even, numbers)
落とし穴2:ビルトイン関数で十分な場合
reduce()
を使う必要がない例
# こうするより...
total = reduce(lambda x, y: x + y, numbers)
# これの方が分かりやすい
total = sum(numbers)
# こうするより...
maximum = reduce(lambda x, y: x if x > y else y, numbers)
# これの方が分かりやすい
maximum = max(numbers)
落とし穴3:副作用のある関数
悪い例
def bad_function(x, y):
print(f"処理中: {x}, {y}") # 副作用
return x + y
result = reduce(bad_function, numbers) # 予期しない出力
良い例
def pure_function(x, y):
"""副作用のない純粋な関数"""
return x + y
result = reduce(pure_function, numbers)
実践的な使用例
ログファイルの解析
コード例
from functools import reduce
# ログの行数をカウント
log_lines = [
"INFO: システム開始",
"ERROR: データベース接続エラー",
"INFO: 処理完了",
"ERROR: ファイル読み込みエラー"
]
error_count = reduce(
lambda count, line: count + 1 if 'ERROR' in line else count,
log_lines,
0
)
print(f"エラー数: {error_count}") # エラー数: 2
設定値の統合
コード例
from functools import reduce
# 複数の設定ファイルをマージ
default_config = {'timeout': 30, 'retries': 3}
user_config = {'timeout': 60}
admin_config = {'debug': True}
configs = [default_config, user_config, admin_config]
final_config = reduce(lambda x, y: {**x, **y}, configs, {})
print(final_config) # {'timeout': 60, 'retries': 3, 'debug': True}
まとめ:reduce()
はパワフルな一方で、使いすぎると可読性が下がる点に注意が必要です。うまく使いこなすことで、コードをより洗練されたものにできます。
reduce()と他の関数との組み合わせ

map()との組み合わせ
例:数値の2乗の合計
from functools import reduce
numbers = [1, 2, 3, 4, 5]
# まず各数値を2乗し、その後合計
squared_sum = reduce(
lambda x, y: x + y,
map(lambda x: x ** 2, numbers)
)
print(squared_sum) # 55 (1+4+9+16+25)
filter()との組み合わせ
例:偶数のみの積
from functools import reduce
numbers = [1, 2, 3, 4, 5, 6]
# 偶数をフィルタしてから積を計算
even_product = reduce(
lambda x, y: x * y,
filter(lambda x: x % 2 == 0, numbers),
1
)
print(even_product) # 48 (2 × 4 × 6)
リスト内包表記との比較
同じ処理を3つの方法で
from functools import reduce
numbers = [1, 2, 3, 4, 5]
# 方法1: reduce + map
result1 = reduce(lambda x, y: x + y, map(lambda x: x * 2, numbers))
# 方法2: リスト内包表記 + sum
result2 = sum([x * 2 for x in numbers])
# 方法3: for文
result3 = 0
for x in numbers:
result3 += x * 2
print(result1, result2, result3) # すべて30
どの方法が良い?
- 簡単な場合:
sum()
やリスト内包表記 - 複雑な累積処理:
reduce()
- デバッグしやすさ重視:for文
まとめ:reduce()を効果的に使いこなそう!
重要なポイント
reduce()
の基本
- 複数の要素を1つの値にまとめる関数
functools
モジュールからインポートが必要- 累積的な計算に特に有効
使い分けのガイドライン
- 単純な合計や最大値:ビルトイン関数(
sum()
,max()
など) - 複雑な累積処理:
reduce()
- 複雑な条件分岐:for文
注意すべきポイント
- 初期値を指定して安全な処理を心がける
- lambda式が複雑になったら名前付き関数を使う
- 可読性を重視し、適材適所で使う
パフォーマンスについて
大きなデータでの比較
import time
from functools import reduce
# 大きなリスト
big_numbers = list(range(1000000))
# reduce版
start = time.time()
result1 = reduce(lambda x, y: x + y, big_numbers)
time1 = time.time() - start
# sum版
start = time.time()
result2 = sum(big_numbers)
time2 = time.time() - start
print(f"reduce: {time1:.4f}秒")
print(f"sum: {time2:.4f}秒")
# 通常、sumの方が高速
実践での使用指針
用途 | 推奨方法 | 理由 |
---|---|---|
数値の合計 | sum() | 専用関数で高速 |
最大値・最小値 | max() , min() | 専用関数で分かりやすい |
複雑な累積処理 | reduce() | 柔軟性が高い |
文字列結合 | join() | 専用メソッドで効率的 |
カスタム集約 | reduce() | 自由度が高い |
コメント