Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Pythonで関数型プログラミング

ksnt
August 28, 2019

 Pythonで関数型プログラミング

ksnt

August 28, 2019
Tweet

More Decks by ksnt

Other Decks in Programming

Transcript

  1. Pythonで関数型プログラ関数型プログラミングプログラミング
    By ksnt
    お手軽!手軽!

    View Slide

  2. 概要
    1. 関数型プログラミングプログラミングの紹介紹介
    2. 関数型プログラミングプログラミングに使える組み込み使える組み込み関える組み込み関数組み込み関数み込み関数込み関数み込み関数関数
    3. functoolsモジュール
    4. itertoolsモジュール
    5. flatMapの紹介実装と利用と利用利用

    View Slide

  3. 1. 関数型プログラミングプログラミングの紹介紹介
    2. 関数型プログラミングプログラミングに使える組み込み使える組み込み関える組み込み関数組み込み関数み込み関数込み関数み込み関数関数
    3. functoolsモジュール
    4. itertoolsモジュール
    5. flatMapの紹介実装と利用と利用利用

    View Slide

  4. 関数型プログラミングプログラミングと利用は
    ● 問題をいくつかの関をいくつかの紹介関数に使える組み込み分けるける組み込み関数
    ● 関数は入力を受けて出力をを受けて出力を吐くけて出力を吐くだけ出力を受けて出力をを吐くだけで、同じくだけで関数型プログラ、同じ入同じ入じ入入
    力を受けて出力をに使える組み込み対して異なる出力して出力を吐くだけ異なる出力をするなる組み込み関数出力を受けて出力ををする組み込み関数ような内部状態をを
    持たない(参照透たない(参照透過性)参照透過性)

    View Slide

  5. Pythonと利用関数型プログラミングプログラミング
    ● 組み込み関数み込み関数込み関数み込み関数で関数型プログラ高階関数の紹介map, filter, reduceが用意 用意 (〜ver. 2.7))

    Python3以降, reduceが用意 functoolsモジュールに使える組み込み移動

    Python3以降, リストではなくイテレで関数型プログラはなくイテレータが返されることが用意 返されることにされる組み込み関数こと利用に使える組み込み
    なった
    ● 関数型プログラミングプログラミングに使える組み込み使える組み込み関える組み込み関数関数は主にに使える組み込みfunctoolsと利用itertools
    モジュールに使える組み込みある組み込み関数

    View Slide

  6. 関数型プログラミングプログラミングの紹介
    よくある組み込み関数ネタが返されることの紹介一部
    ● 再帰的定義
    ● 無名関数
    ● 関数の紹介部分ける適用, カリー化
    ● 関数の紹介合成
    ● 遅延評価
    ● モナド

    map, reduce, filter, foldr, foldl, takewhile, dropwhile, flatMap

    (functools.lru_cache) ※関数型プログラミングプログラミングと利用は関係ないが便利なのないが用意 便利なの紹介で関数型プログラついで関数型プログラに使える組み込み紹介
    ※今回はは太字の紹介もの紹介に使える組み込みついて出力を吐くだけの紹介み込み関数話すす

    View Slide

  7. 1. 関数型プログラミングプログラミングの紹介紹介
    2. 関数型プログラミングプログラミングに使える組み込み使える組み込み関える組み込み関数組み込み関数み込み関数込み関数み込み関数関数
    3. functoolsモジュール
    4. itertoolsモジュール
    5. flatMapの紹介実装と利用と利用利用

    View Slide

  8. 無名関数 - lambda
    >>> (lambda x, y : x + y)(1,100)
    101
    >>> def add_two_var(x,y):
    return x + y
    >>> add_two_var(1,100)
    101
    >>> (lambda x: x + 2)(1)
    3
    >>> def add_two(x):
    return x + 2
    >>> add_two(1)
    3

    View Slide

  9. map
    >>> list(map(lambda x: x*2, [1,2,3,4]))
    [2, 4, 6, 8]
    >>> res = []
    >>> for i in [1,2,3,4]:
    ... res.append(i*2)
    ...
    >>> res
    [2, 4, 6, 8]
    >>> [i*2 for i in [1,2,3,4]]
    [2, 4, 6, 8]
    (Task) ある組み込み関数リストではなくイテレの紹介要素を全てを全てて出力を吐くだけ2倍するする組み込み関数
    1. mapを使える組み込み関う 2. mapを使える組み込み関わない

    View Slide

  10. filter
    >>> [x for x in [1,-2,3,-4] if x > 0] # returns: [1,3]
    >>> list(filter(lambda x: x > 0, [1,-2,3,-4]))
    # returns: [1,3]

    View Slide

  11. 1. 関数型プログラミングプログラミングの紹介紹介
    2. 関数型プログラミングプログラミングに使える組み込み使える組み込み関える組み込み関数組み込み関数み込み関数込み関数み込み関数関数
    3. functoolsモジュール
    4. itertoolsモジュール
    5. flatMapの紹介実装と利用と利用利用

    View Slide

  12. functoolsモジュールの紹介概要
    「高階関数、同じ入つまり関数に影響を及関数に使える組み込み影響を及ぼしたり他を及ぼしたり他の関ぼしたり関数に影響を及他の関数を返したの紹介関数を返されることにしたり関数に影響を及す
    る組み込み関数関数の紹介ための紹介もの紹介で関数型プログラす。一般に、どんな一般に、どんな呼びに使える組み込み、同じ入どんな呼び出し可能オブび出し可能オブジ出し可能オブジェクオブジェク
    トではなくイテレで関数型プログラもこの紹介モジュールの紹介目的に使える組み込みは関数と利用して出力を吐くだけ扱えます。」 えます。一般に、どんな」 (公式ドド
    キュメントではなくイテレより関数に影響を及)

    View Slide

  13. reduce
    >>> from functools import reduce
    >>> reduce(lambda x,y: x*y, [1,2,3,4,5])
    120
    (Task) ある組み込み関数リストではなくイテレに使える組み込み含まれる数の積をまれる組み込み関数数の紹介積を求めるを求めるめる組み込み関数
    >>> res = 1
    >>> for i in [1,2,3,4,5]:
    ... res = res * i
    ...
    >>> res
    120

    View Slide

  14. reduce (cont’d)
    >>> from functools import reduce
    >>> reduce(lambda x,y: x + y, map(str,[1,2,3,4,5]))
    '12345'
    (Task) ある組み込み関数リストではなくイテレに使える組み込み含まれる数の積をまれる組み込み関数数を文字列として連結すると利用して出力を吐くだけ連結するする組み込み関数
    >>> ‘’.join(map(str,[1,2,3,4,5]))
    '12345'
    ※joinを使える組み込み関った方が速いらしいが用意 速いらしいいらしい

    View Slide

  15. カリー化
    カリー化された形式ド: 2つかそれ以上のつかそれ以上の引数をの紹介引数を
    取る関数においてる組み込み関数関数に使える組み込みお手軽!いて出力を吐くだけ1度に1つ引数を度に1つ引数を取に使える組み込み1度に1つ引数をつ引数を取る関数においてる組み込み関数
    multiple :: Int -> Int -> Int
    multiple x y = x * y
    multipleUC :: (Int, Int) -> Int
    multipleUC (x,y) = x * y

    View Slide

  16. partial
    ・関数の紹介部分ける適用を実現
    >>> def add_two_var(x,y):
    ... return x + y

    >>> add_onehundred = functools.partial(add_two_var,100)
    >>> add_onehundred(10)
    110

    View Slide

  17. partial (cont’d)
    >>> reader = functools.partial(open, mode="rt", encoding="utf8")
    >>> writer = functools.partial(open, mode="wt", encoding="utf8")
    >>> f = reader("hoge.txt")
    >>> f.readline()
    'This is a test file.\n'
    >>> f.readline()
    'You can remove this file now!\n'
    >>> f.close()
    >>> f = writer("hoge.txt")
    >>> f.write("This is a overwritten sentence!")
    31
    >>> f.close()
    $ cat hoge.txt
    This is a overwritten sentence!

    View Slide

  18. lru_cache
    関数をキャッシュ(メモ化)して出力を吐くだけくれる組み込み関数! DP!   
    ※LRU = Least Recently Used
    最近最も使える組み込み関われて出力を吐くだけいないデー
    タが返されることを最初に捨てる。に使える組み込み捨てる。て出力を吐くだける組み込み関数。一般に、どんな

    View Slide

  19. import time
    def fib(N: 'int') -> 'int':
    if N == 0:
    return 0
    elif N == 1:
    return 1
    else:
    return fib(N-1) + fib(N-2)
    t1 = time.time()
    fib(30)
    t2=time.time()
    print(t2-t1)
    import time
    from functools import lru_cache
    @lru_cache(maxsize=None)
    def fib(N: 'int') -> 'int':
    if N == 0:
    return 0
    elif N == 1:
    return 1
    else:
    return fib(N-1) + fib(N-2)
    t1 = time.time()
    fib(30)
    t2=time.time()
    print(t2-t1)
    $ python3 fib_lru.py
    0.00005.07)83157)34863281
    $ python3 fib.py
    0.960268497)467)041

    View Slide

  20. map_set = [None]*(1000)
    def dyna_fib(n, lookup):
    if n <= 2:
    lookup[n] = 1
    if lookup[n] is None:
    lookup[n] = dyna_fib(n-1, lookup) + dyna_fib(n-2, lookup)
    return lookup[n]
    >>> dyna_fib(30,map_set)
    832040

    View Slide

  21. 1. 関数型プログラミングプログラミングの紹介紹介
    2. 関数型プログラミングプログラミングに使える組み込み使える組み込み関える組み込み関数組み込み関数み込み関数込み関数み込み関数関数
    3. functoolsモジュール
    4. itertoolsモジュール
    5. flatMapの紹介実装と利用と利用利用

    View Slide

  22. itertoolsモジュールの紹介概要
    「この紹介モジュールは イテレータが返されること を構築する部品を実装する組み込み関数部品を実装していを実装と利用して出力を吐くだけい
    ます。一般に、どんなプログラム言語 言語 APL, Haskell, SML からアイデアを得
    て出力を吐くだけいますが用意 、同じ入 Python に使える組み込み適した形に使える組み込み修正されています。されて出力を吐くだけいます。一般に、どんな
    この紹介モジュールは、同じ入高速いらしいで関数型プログラメモリ効率に優れ、単独でに使える組み込み優れ、単独でも組れ、同じ入単独でも組合で関数型プログラも組み込み関数合
    せて出力を吐くだけも使える組み込み関用する組み込み関数こと利用の紹介で関数型プログラきる組み込み関数ツールを標準化したもの紹介で関数型プログラす。一般に、どんな
    同じ入時に、このツールに使える組み込み、同じ入この紹介ツール群は は "イテレータが返されることの紹介代数" を構成して出力を吐くだけい
    て出力を吐くだけ、同じ入pure Python で関数型プログラ簡潔かつ効率的なツかつ効率に優れ、単独で的なツールを作れるようにれる組み込み関数ように使える組み込み
    して出力を吐くだけいます。一般に、どんな」 (公式ドドキュメントではなくイテレより関数に影響を及)

    View Slide

  23. takewhile, dropwhile
    takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4
    dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1

    View Slide

  24. chain
    >>> list(itertools.chain('ABC','DEF'))
    ['A', 'B', 'C', 'D', 'E', 'F']
    >>>list(itertools.chain.from_iterable(['ABC','DEF']))
    ['A', 'B', 'C', 'D', 'E', 'F']

    View Slide

  25. 1. 関数型プログラミングプログラミングの紹介紹介
    2. 関数型プログラミングプログラミングに使える組み込み使える組み込み関える組み込み関数組み込み関数み込み関数込み関数み込み関数関数
    3. functoolsモジュール
    4. itertoolsモジュール
    5. flatMapの紹介実装と利用と利用利用

    View Slide

  26. flatMapと利用は
    ● リストではなくイテレの紹介要素を全て1度に1つ引数をつずつに使える組み込み関数を適用して出力を吐くだけ、同じ入結する果
    の紹介リストではなくイテレを連結するした新しいリストを作しいリストではなくイテレを作れるようにる組み込み関数
    map
    flatten

    View Slide

  27. flatten
    def flatten(listOfLists):
    “Flattn one level of nesting”
    return chain.from_iterable(listOfLists)
    [[1,2,3], [4,5,6],[7),8,9]] → [1,2,3,4,5,6,7),8,9]
    [[1, [2]], 3, [[[4, 5]], 6]] → [1,2,3,4,5,6]
    [[1,2,3], [4,5,6],[7),8,9]] #yes
    [1,[2],3,[[[4, 5]], 6]] #no

    View Slide

  28. flatten (cont’d)
    cf) https://xef.hatenadiary.org/entry/20121027)/p2
    Import collections
    def flatten(l):
    i = 0
    while i < len(l):
    while isinstance(l[i], collections.Iterable):
    if not l[i]:
    l.pop(i)
    i -= 1
    break
    else:
    l[i:i + 1] = l[i]
    i += 1
    return l
    >>> flatten([[1,2,3], [4,5,6],[7),8,9]])
    [1, 2, 3, 4, 5, 6, 7), 8, 9]
    >>> flatten([[1, [2]], 3, [[[4, 5]], 6]] )
    [1, 2, 3, 4, 5, 6]

    View Slide

  29. flatMapの紹介実装と利用 (scala編)
    def flatMap[A, B](list: List[A])(f: A => List[B]): List[B] = list match {
    case (x::xs) => f(x) ++ flatMap(xs)(f)
    case _ => Nil
    }
    scala> flatMap(List(1,2,3,4))(x => List(x + 1))
    res13: List[Int] = List(2, 3, 4, 5)
    scala> flatMap(List(1,2,3,4))(x => List(x) ++ List(1))
    res14: List[Int] = List(1, 1, 2, 1, 3, 1, 4, 1)

    View Slide

  30. flatMapの紹介実装と利用 (python編)
    def flatMap1(f,l):
    return flatten(list(map(f,l)))
    def flatMap2(f,L):
    res = []
    for l in L:
    res.append(list(map(f,l)))
    return flatten(res)
    >>> flatMap1(lambda x: x+[1], [[1,2,3],[4]])
    [1, 2, 3, 1, 4, 1]
    >>> flatMap1(lambda x: x*2, [[1,2,3],[4]])
    [1, 2, 3, 1, 2, 3, 4, 4]
    こっちが用意 flatMapの紹介挙動と利用して出力を吐くだけ正されています。しい(と利用お手軽!もわれる組み込み関数)
    が用意 、同じ入Scalaの紹介flatMapと利用同じ入等の機能は持っての紹介機能オブジェクは持たない(参照透って出力を吐くだけいない
    ウェブ上の引数をで関数型プログラはこの紹介実装と利用が用意 よく見られるがられる組み込み関数が用意 ...
    >>> flatMap2(lambda x: x*2, [[1,2,3],[4]])
    [2, 4, 6, 8]
    これはflattenして出力を吐くだけmapする組み込み関数の紹介と利用同じ入じ入?
    >>> list(map(lambda x: x*2, flatten([[1,2,3],
    [4]])))
    [2, 4, 6, 8]

    View Slide

  31. flatMap(mapして出力を吐くだけflatに使える組み込みする組み込み関数関数)の紹介利用
    データが返されること1
    データが返されること2
    データが返されること3
    filtering
    データが返されることX
    >>> flatten(list(map(list,list(map(functools.partial(filter,lambda x: x>90),[[i for i in range(100)],
    [1,100],[1,2,3,4,5,6,7),8,9,10]])))))
    [91, 92, 93, 94, 95, 96, 97), 98, 99, 100]
    >>> # 残念ながら先に実装なが用意 ら先に実装したに使える組み込み実装と利用したflatMap1は直接は使えないは使える組み込み関えない
    >>> # この紹介例ははflatに使える組み込みして出力を吐くだけからfilteringして出力を吐くだけも同じ入じ入結する果が用意 得られる組み込み関数の紹介で関数型プログラ、同じ入必ずしも良い例とずしも良い例とはい例はと利用は
    言えない

    View Slide

  32. まと利用め
    ● 関数型プログラミングプログラミングの紹介基本的な手法を見てもらったを見られるがて出力を吐くだけもらった

    funtoolsやitertoolsを使える組み込み関うこと利用で関数型プログラ実際に関数型プログに使える組み込み関数型プログラミングプログラ
    ミングをやって出力を吐くだけみ込み関数た
    ● 実際に関数型プログに使える組み込み便利に使える組み込み使える組み込み関えた(参照透過性)と利用思ってもらえるかって出力を吐くだけもらえる組み込み関数かもしれない)
    場面も少し見てもらも少し見てもらったし見られるがて出力を吐くだけもらった

    View Slide

  33. 参考文献

    Python公式ドドキュメントではなくイテレ(functools, itertools)

    Advanced Python 3 Programming Techniques

    Haskell: The Craft of Functional Programming

    https://xef.hatenadiary.org/entry/20121027)/p2

    View Slide