牌語備忘録 -pygo

あくまでもメモです。なるべくオフィシャルの情報を参照してください。

牌語備忘録 -pygo

実用的なプログラミングツール filter()・map()・reduce() をpythonで使ってみた

http://www.python.jp/doc/release/tut/tut.html

組み込み関数には、リストで使うと非常に便利なものが三つあります: filter() 、 map() 、reduce() です。

5.1.3 実用的なプログラミングツール

とあったので試してみた

0から30までの3で割り切れる数をリスト化

#A-1
lst = []
for x in range(31):
    if x % 3 == 0:
         lst.append(x)
print lst
#[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
#A-2
print [x for x in range(31) if x % 3 == 0]
#[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
#filter() を使ってみる

"filter(function, sequence)" は、シーケンス sequence 中の要素 item から、 function(item) が真となるような要素からなるシーケンス (可能ならば sequence と同じ型の) シーケンスを返します。

Pythonチュートリアル 5.1.3 実用的なプログラミングツール
#A-3
def div(x):
    return x % 3 == 0
print filter(div, range(31))
#[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
#A-4
print filter(lambda x:x % 3 == 0, range(31))
#[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30]

0から30までの数を3の倍数にしてリスト化

#B-1
lst = []
for x in range(31):
    lst.append(x * 3)
print lst
#[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90]
#B-2
print [x * 3 for x in range(31)]
#[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90]
#map() を使ってみる

"map(function, sequence)" は、シーケンス sequence の各要素 item に対して function(item) を呼び出し、その戻り値からなるリストを返します。

Pythonチュートリアル 5.1.3 実用的なプログラミングツール
#B-3
def treble(x):
    return x * 3
print map(treble, range(31))
#[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90]
#B-4
print map(lambda x:x * 3, range(31))
#[0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90]


数値のシーケンスを文字列のシーケンスに変更する時など便利

#B-5
num_lst = map(lambda x:x * 3, range(31))
print map(str, num_lst)
#['0', '3', '6', '9', '12', '15', '18', '21', '24', '27', '30', '33', '36', '39', '42', '45', '48', '51', '54', '57', '60', '63', '66', '69', '72', '75', '78', '81', '84', '87', '90']

0から30までの数の合計

例:
465 = 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30
《"%d = %s" % (sum([n for n in range(31)]), " + ".join([str(n) for n in range(31)]))》

#C-1
num = 0
for x in range(31):
    num += x
print num
#465
#C-2(再帰)
def recursive_add(x):
    if x == 0:
        return 0
    return x + recursive_add(x - 1)
print recursive_add(30)
#465
#C-3(反復)
def iterative_add(x):
    def add_iter(a, count):
        if count == 0:
            return a
        return add_iter(a + count, count -1)
    return add_iter(0, x)
print iterative_add(30)
#465
#C-4(reduceの挙動と違う気がするけど、たぶんsum()の中身は同じ様な処理?)
print sum([x for x in range(31)])
#465
#reduce() を使ってみる

"reduce(func, sequence)" は単一の値を返します。この値は 2 つの引数をとる関数 func をシーケンス sequence の最初の二つの要素を引数として呼び出し、次にその結果とシーケンスの次の要素を引数にとり、以降これを繰り返すことで構成します。

Pythonチュートリアル 5.1.3 実用的なプログラミングツール
#C-5
def num_add(x, y):
    return x + y
print reduce(num_add, range(31))
#465
#C-6
print reduce(lambda x,y:x + y, range(31))
#465
#C-7
from operator import add
print reduce(add, range(31))
#465

reduceの動きがわかりにくいから途中経過を

0 + 1 = 1
1 + 2 = 3
3 + 3 = 6
6 + 4 = 10
10 + 5 = 15
15 + 6 = 21
21 + 7 = 28
28 + 8 = 36
36 + 9 = 45
45 + 10 = 55
55 + 11 = 66
66 + 12 = 78
78 + 13 = 91
91 + 14 = 105
105 + 15 = 120
120 + 16 = 136
136 + 17 = 153
153 + 18 = 171
171 + 19 = 190
190 + 20 = 210
210 + 21 = 231
231 + 22 = 253
253 + 23 = 276
276 + 24 = 300
300 + 25 = 325
325 + 26 = 351
351 + 27 = 378
378 + 28 = 406
406 + 29 = 435
435 + 30 = 465