Caution

お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。

Python辞典

  1. トップページ
  2. Python辞典
  3. functools.reduce() / functools.partial()

functools.reduce() / functools.partial()

『functools.reduce()』はイテラブルの要素を左から順に2引数関数で累積的に適用し、1つの値に集約します。『functools.partial()』は関数の一部の引数をあらかじめ固定した新しい関数(部分適用関数)を作ります。どちらも関数型プログラミングのスタイルで処理を記述するときに役立ちます。

構文
from functools import reduce, partial

# 集約(左から順に関数を適用)
reduce(function, iterable, initializer=None)

# 部分適用(引数を固定した新しい関数を生成)
partial(func, *args, **kwargs)
関数一覧
関数概要
reduce(func, iterable)イテラブルの要素を左からfuncで順に集約して1つの値を返す。
reduce(func, iterable, init)initを初期値として集約を開始する。イテラブルが空でもエラーにならない。
partial(func, *args, **kwargs)funcの一部の引数を固定した新しい関数オブジェクトを返す。
サンプルコード
from functools import reduce, partial
import operator

# reduce: リストの合計(sum()と同じ結果)
nums = [1, 2, 3, 4, 5]
total = reduce(lambda a, b: a + b, nums)
print(total)    # 15

# reduce: operatorモジュールと組み合わせる
product = reduce(operator.mul, nums)
print(product)  # 120(1×2×3×4×5)

# reduce: 初期値を指定
total2 = reduce(lambda a, b: a + b, nums, 100)
print(total2)   # 115(100 + 15)

# reduce: 最大値を求める(max()と同じ結果)
max_val = reduce(lambda a, b: a if a > b else b, [3, 1, 4, 1, 5, 9, 2, 6])
print(max_val)  # 9

# reduce: ネストしたリストをフラット化
nested = [[1, 2], [3, 4], [5, 6]]
flat = reduce(lambda a, b: a + b, nested)
print(flat)     # [1, 2, 3, 4, 5, 6]

# partial: 引数を部分的に固定する
def power(base, exp):
    return base ** exp

square = partial(power, exp=2)  # expを2に固定
cube   = partial(power, exp=3)  # expを3に固定

print(square(5))    # 25
print(cube(3))      # 27

# partial: printの区切り文字を固定
print_tsv = partial(print, sep='\t')
print_tsv('名前', '年齢', '部署')  # 名前\t年齢\t部署

# partial: 第一引数を固定
add_10 = partial(lambda a, b: a + b, 10)
print(add_10(5))    # 15
print(add_10(20))   # 30
概要

『reduce()』はPython 2では組み込み関数でしたが、Python 3では『functools』モジュールに移動しました。多くの場面ではsum()・max()・min()・any()・all()などの組み込み関数で代替できますが、より複雑な集約ロジックを1行で表現したいときにreduceが有効です。イテラブルが空でinitializerも指定しない場合はTypeErrorになるため注意が必要です

『partial()』はコールバック関数に渡す関数を特定の引数で固定したいときや、同じ関数を少しずつ違う設定で使い回したいときに便利です。lambda式でも同様のことはできますが、partialを使う方が意図が明確になります。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。