Python の関数型っぽいプログラミング

Python はかなり関数型っぽいということがやっと分かったので、Scheme と比べつつ様子を探ってみたい。まずは Lisp ではよく高階関数の例として取り上げられるものをいくつか取り上げてみた。

関数の合成。

;; Scheme
(define (compose f g)
  (lambda (x)
    (f (g x))))

# Python
def compose(f, g):
    def __fg(x):
        return f(g(x))
    return __fg


つづいて二つのリスト(あるいは配列)の各要素ごとの和を返す関数。

;; Scheme
(define (sum-element lst1 lst2)
  (map + lst1 lst2))

# Python
def sum_element(lst1, lst2):
    return map(operator.add, lst1, lst2)

実際に使う場合は、どちらも関数として定義することはないだろうけど。Python で map() と operator.add がなかったらかなり冗長になってしまうと思う。zip() とリスト内包表記を使えばまだ良いかもしれない。

最後にリストの積を返す関数。Scheme

;; Scheme
(define (accumulate-list lst)
  (fold + 0 lst))

# Python
def accumulate_list(lst):
    return reduce(operator.add, lst, 0)

# Python (手続き的処理、高階関数なし)
def _accumulate_list(lst):
    acc = 0
    for x in lst:
        acc += x
    return acc


Python を学んでいた当初は、高階関数という概念はよく知らなかったので、上記のような書き方はせずに、ループ構文を使ったり、リスト内包表記などで書いていたのだが、高階関数に慣れれば場合によっては上記のようなコードの方がずっと分かりやすい。Guido は map や reduce などは嫌いっぽいが、やっぱり便利なんで残して欲しい。あと operator モジュール重要。