python学習ノートの関数間接呼び出しlambdaおよび内蔵関数


1関数の間接呼び出し
pythonでは、すべてがオブジェクトであり、関数も他のオブジェクトと同様に、他の名前に値を付けたり、他の関数に渡したり、データ構造に埋め込んだりすることができます.
関数名は直接オブジェクトの参照です.
  • 他の名前
  • に付与
    def echo(message):
        print(message)
        
    echo('direct call')
    x = echo
    x('Indirect call')
    
  • は他の関数
  • に渡す.
    def indirect(func, arg):
        func(arg)
    
    indirect(echo, 'argument call')
    
  • 関数オブジェクトの内容をデータ構造
  • に埋め込む.
    schedule = [(echo,'spam'),(echo, 'ham')]
    for (func, arg) in schedule:
        func(arg)
    

    2関数のプロパティ
    2.1関数内省
    関数オブジェクトにも属性があります
    >> func.__name__
    'func'
    
    >> dir(func)
    ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
    
    >>dir(func.__code__)
    ['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_kwonlyargcount', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_posonlyargcount', 'co_stacksize', 'co_varnames', 'replace']
    

    2.2関数の追加属性
    関数はpythonが元々持っていた属性だけでなく、自分で属性を追加することもできます.
    func.count = 0
    func.count += 1
    

    2.3関数注記
    関数注記は通常defヘッダに記述されます
    def func(a:'spam', b:(1,10), c:float) -> int:
        return a+b+c
    
    >> func(1,2,3)
    6
    

    注記を呼び出した関数は以前と同じです.しかし、注釈が表示されるとpythonは辞書種に収集され、パラメータ名がキーになり、注釈が値になります.
    >>> func.__annotations__
    {
         'a': 'spam', 'b': (1, 10), 'c': <class 'float'>, 'return': <class 'int'>}
    

    注記を作成してもデフォルト値は使用できます
    def func(a:'spam'=4,b:(1,10)=5,c: float = 6) -> int:
        return a+b+c
    

    Lambdaでは注釈は使用できません
    3 lambda
    Lambdaは匿名関数とも呼ばれます.defのように関数変数名を必要としないからです.
    Lambda式
    lambda arg1,arg2,argN: expression using args
    

    3.1なぜlambdaを使うのか
    Lambdaは関数のスケッチとして機能し,実行するコードに関数定義を埋め込むことを可能にする.
    L = [lambda x : x**2,
        lambda x : x**3,
        lambda x : x**4]
    
    for f in L:
        print(f(2))
        
    print(L[0](3))
    

    セグメントの実行可能なコードをdefでは作成できないコードに組み込む必要がある場合、lambdaは良い役割を果たします.
    def f1(x): return x**2
    def f2(x): return x**3
    def f3(x): return x**4
    
    L = [f1,f2,f3]
    
    for f in L:
        print(f(2))
        
    print(L[0](3))
    

    またlambda関数を書くことで、関数名が他の変数名と重複することを回避できます.
    3.2ネストlambdaと役割ドメイン
    Lambdaはネスト関数の役割ドメイン検索の最大の受益者であり、通常、lambdaにdefが現れる(典型的な場合)lambdaは上位関数の変数の役割ドメインを取得することができる.
    def action(x):
        return (lambda y:x+y)
    
    >>> act = action(99)
    >>> act(2)
    101
    

    4 mapとfilter
    4.1シーケンスマッピング関数map
    プログラムは、通常、リスト内の各要素を操作し、結果を集約する必要があります.
    例えば、各リストに10を加算する
    counters = [1,2,3,4]
    
    updated=[]
    for x in counters:
        updated.append(x+10)
    

    pythonは、この操作を完了するためのツールmapを内蔵しています.
    def inc(x): return x+10
    
    list(map(inc, counters))
    

    mapは1つの関数と1つのリストを入力することを期待して、lambdaで独立して1つの関数を創立することを避けることができます
    list(map(lambda x:x+10,counters))
    

    関数に複数のパラメータが必要な場合は、操作を完了するために複数のリストを指定することもできます.
    pow(3,4)
    >> 81
    list(map(pow,[1,2,3],[2,3,4]))
    [1,8,81]
    

    mapはNリストに用いるNパラメータ道徳関数を期待する
    4.2 filter関数
    filterはフィルタの意味で、あるテスト関数に基づいていくつかの要素をフィルタします
    list(range(-5,5))
    
    list(filter((lambda x:x>0),range(-5,5)))
    

    に等しい
    res = []
    for x in range(-5,5):
        if x >0:
            res.append(x)
    

    4.3 reduce関数
    reduceは反復器を受信して処理しますが、単一の結果を返します.
    from functools import reduce
    
    >>> reduce((lambda x,y:x+y),[1,2,3,4])
    10
    >>> reduce((lambda x,y:x*y),[1,2,3,4])
    24
    

    に等しい
    L = [1,2,3,4]
    res = L[0]
    for x in L[1:]:
        res = res+x