filterの使い方--Python

2034 ワード

filterが高次関数と呼ばれるのは理にかなっている.
filter(self, /, *args, **kwargs)

Docstring:      filter(function or None, iterable) --> filter object  

Return an iterator yielding those items of iterable for which function(item) is true. If function is None, return the items that are true.

Docの簡単な説明から、filterの主な役割は、functionによってiterable内の要素をフィルタリングし、functionがTrueを返す要素である反復器(iterator)を返すことであることがわかる.functionがNoneに渡されると、Trueと判断できるすべての要素が返されます.
例1:
    l = [x for x in range(10)]
    print(list(filter(lambda x : x%2 == 0, l)))
    #  [2,4,6,8]

filterはiteratorを返すので、出力するときはlistで変換する必要があります.
例2:
    l = [x for x in range(0, 10)]
    print(list(filter(None, l)))
    #  [1,2,3,4,5,6,7,8,9]

例1の入力とは少し異なり、入力は0~9であり、filterの最初のパラメータがNoneに入力されたので、反復中に0がFalseと判断されてフィルタリングされ、1~9が保持される.この方法はforサイクルのデータピックアップに代わることができる.
上記の例から分かるように、filterを呼び出すとフィルタ処理がトリガーされません.filter関数を呼び出すとiteratorが返されるだけで、不活性計算であり、nextまたはlistの場合にのみ、計算プロセスが本格的に開始されます.
上は2つの基本的な使い方ですが、次にfilterのもっと高級な使い方を見てみましょう.
   
def _odd_iter():
        n = 1
        while True:
            n = n + 2
            yield n
            
    def _not_divisible(n):
        return lambda x : x%n>0
     
    def primes():
        yield 2
        it = _odd_iter()
        ftr = filter(_not_divisible(2), it) #1
        while True:
            n = next(ftr )        #2
            yield n                
            ftr = filter(_not_divisible(n), ftr ) #3
            
    for n in primes():
        if n < 100:
            print('now:',n)
        else:
            break

この例では、filterの2つの高度な使い方を見ることができます.
1.実際にfilterはfilterオブジェクトを返します.#3行は、割り当てを繰り返すことで、filterに複数のフィルタを追加できます.例では、#3行を実行するたびに、現在の素数を新しい被除数条件としてフィルタftrに加えるので、forサイクルの後続反復では、毎回1つの素数条件を増やしてフィルタに入る.
このような繰返し付与法により、filterに複数のフィルタ関数を追加することができ、フィルタ機能を極めて強化することができる.
2.filterの2番目のパラメータはiteratorに入力できます.もちろん、この場合はlistでfilterの結果を取ることはできません.next(filterオブジェクト)で次のフィルタ結果がTrueの要素を取るしかありません.