サブルーチンと関数

perlにおけるサブルーチンというものはpythonには無くて、
pythonではすべては関数として定義しなければならないみたい。
なのでperlのサブルーチンを定義するのをpythonの関数を定義することに
当てはめて練習してみる。
まずは2つの数値の平均値を求める関数をつくると、

def calc_average(x, y):
    ave = (x + y) / 2
    return ave

となって使ってみると

>>> print calc_average(50, 100)
75

次はリスト内の任意の個数の数値の平均値を求める関数をつくると、

def calc_average(lis):
    ave = sum(lis) / len(lis)
    return ave

でできた。
次に引数に与えたリストの各要素に対して文字列としての長さを求めて、
それをリストにして返す関数は、

def get_length_list(lis):
    length_list = []
    for i in lis:
        length_list.append(len(i))
    return length_list

として使ってみると

>>> lis = ["I", "speak" , "English", "and", "Japanese."]
>>> get_length_list(lis)
    [1, 5, 7, 3, 9]

つづいて階乗を計算する関数を定義してみる。
ここで使うreduceという関数はreduce(関数, シークエンス)という形で使えて
シークエンスの要素に対してシークエンスを単一の値に短縮するような形で 2 つの引数をもつ関数を左から右に累積的に
適用していくらしい。よくわかりにくいので例を見ると、
reduce(labmda x, y: x+y, [1, 2, 3, 4, 5]) は ((((1+2)+3)+4)+5) という計算を行うことになるらしい。
つまり、左引数x は累計の値になり、右引数 y はシークエンスから取り出した更新値になるということらしい。
よって定義する関数は引数を1つとして、引数xがそれぞれ負の数,0,nのときの戻り値を0,1,n!とすると、

def factorial(x):
    if x < 0:
        return 0
    elif x == 0:
        return 1
    else:
        return reduce((lambda x,y: x * y),range(1, x+1))

とできて、

>>> [factorial(i) for i in range(-1, 11)]
    [0, 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]

となる。