Python標準ライブラリのジェネレータ関数を羅列する(1)

5335 ワード

実際の符号化では、ジェネレータ関数を実装する必要があるかもしれませんが、実装前に標準ライブラリで何が利用できるかを知る必要があります.そうしないと、ホイールを再発明し、栗を挙げて無限等差数列を実装する可能性があります.最初のstart=0、公差step=2です.リスト形式で実装できないのは明らかです.そうしないと、メモリがオーバーフローするに違いありません.ジェネレータを直接書くことができますが、なぜ内蔵しないのでしょうか.
import itertools

gen = itertools.count(start, step)  #    gen       
for _ in range(100):  #          100    
     print(next(gen))

Python 3のitertoolsモジュールは複数のジェネレータ関数を提供し,使用と組み合わせて多くの使い方を実現できる.上で使用するitertools.count関数が返すジェネレータは複数の数を生成できます.パラメータが入力されない場合はitertools.count関数は、ゼロから始まる整数数列を生成します.しかし、オプションのstartとstep値を提供することができます.
複数のジェネレータを組み合わせて使用すると、上記の例に条件を加えると、生成された等差数列の最大値は100を超えず、itertoolsが明らかになる.countはできません.itertoolsの下の別のジェネレータ関数itertoolsを使用できます.takewhile()
import itertools

gen = itertools.takewhile(lambda n: n < 100, itertools.count(0, 2))  
for value in gen:  
     print(value)

itertools.takewhile関数は別のジェネレータを使用するジェネレータを生成し、指定した条件計算結果がFalseの場合に停止します.
実際、Python標準ライブラリには、純粋なテキストファイルを行単位で反復するオブジェクトや優れたosなど、多くのジェネレータが提供されています.walk関数.この関数はディレクトリツリーを巡る過程でファイル名を生成するので,再帰検索ファイルシステムはforループのように簡単である.他にもitertoolsやfunctoolsモジュールの中には、カテゴリ別に挙げましょう
1、フィルタ用のジェネレータ関数
モジュール
関数#カンスウ#
説明
itertools
compress(it,selector_it)
2つの反復可能なオブジェクトを並列に処理します.selector_itの中の要素は真の値で、itの中の対応する要素を産出します
itertools
dropwhile(predicate,it)
itを処理し、predicateの計算結果が真値の要素をスキップし、残りの要素を生成します(これ以上チェックしません).
(内蔵)
filter(predicate, it)
itの各要素をpredicateに渡し、predicate(item)が真値を返すと、対応する要素が生成されます.predicateがNoneの場合、真の要素のみが生成されます.
itertools
filterfalse(predicate,it)
filter関数の役割と似ていますが、predicateの論理は逆です.predicateが偽値を返すと対応する要素が生成されます.
itertools
islice(it,stop)またはislice(it,start,stop,step=1)
itのスライスは、s[:stop]またはs[start:stop:step]に類似した役割を果たすが、itは任意の反復可能なオブジェクトであり、この関数は不活性な動作を実現する.
itertools
takewhile(predicate,it)
predicateが真値を返すと対応する要素が生成され、すぐに停止し、チェックを続行しません.
各関数の使い方をコンソールで説明します
>>> def vowel(c):
... return c.lower() in 'aeiou'
...
>>> list(filter(vowel, 'Aardvark'))
['A', 'a', 'a']
>>> import itertools
>>> list(itertools.filterfalse(vowel, 'Aardvark'))
['r', 'd', 'v', 'r', 'k']
>>> list(itertools.dropwhile(vowel, 'Aardvark'))
['r', 'd', 'v', 'a', 'r', 'k']
>>> list(itertools.takewhile(vowel, 'Aardvark'))
['A', 'a']
>>> list(itertools.compress('Aardvark', (1,0,1,1,0,1)))
['A', 'r', 'd', 'a']
>>> list(itertools.islice('Aardvark', 4))
['A', 'a', 'r', 'd']
>>> list(itertools.islice('Aardvark', 4, 7))
['v', 'a', 'r']
>>> list(itertools.islice('Aardvark', 1, 7, 2))
['a', 'd', 'a']

2、マッピング用のジェネレータ関数
モジュール
関数#カンスウ#
説明
itertools
accumulate(it, [func])
産出累計の合計funcが提供されている場合は、最初の2つの要素を渡し、計算結果と次の要素を渡します.
(内蔵)
enumerate(iterable, start=0)
2つの要素からなる元祖を産出し、構造は(index,item)であり、indexはstartからカウントされ、itemはiterableから取得される.
(内蔵)
map(func, it1, [it2, ..., itN])
itの各要素をfuncに伝え、結果を生み出す.N個の反復可能なオブジェクトが入力された場合、funcはN個のパラメータを受け入れることができ、各反復可能なオブジェクトを並列に処理する必要がある.
itertools
starmap(func, it)
itの各要素をfuncに伝え、結果を生み出す.入力した反復可能オブジェクトは、反復可能な要素iitを生成し、func(*iit)という形式でfuncを呼び出す必要があります.
まずaccumulate(it,[func])関数の使い方を単独で実証しましょう.この使い方は柔軟です.
>>> sample = [5, 4, 2, 8, 7, 6, 3, 0, 9, 1]
>>> import itertools
>>> list(itertools.accumulate(sample)) #     
[5, 9, 11, 19, 26, 32, 35, 35, 44, 45]
>>> list(itertools.accumulate(sample, min)) #      
[5, 4, 2, 2, 2, 2, 2, 0, 0, 0]
>>> list(itertools.accumulate(sample, max)) #      
[5, 5, 5, 8, 8, 8, 8, 8, 9, 9]
>>> import operator
>>> list(itertools.accumulate(sample, operator.mul)) #     
[5, 20, 40, 320, 2240, 13440, 40320, 0, 0, 0]
>>> list(itertools.accumulate(range(1, 10), operator.mul)) #  1!   10!,         
[1, 2, 6, 24, 120, 720, 5040, 40320, 362880]

次に、他のマッピングジェネレータ関数について説明します.
>>> list(enumerate('albatroz', 1)) #   1   ,          
[(1, 'a'), (2, 'l'), (3, 'b'), (4, 'a'), (5, 't'), (6, 'r'), (7, 'o'), (8, 'z')]
>>> list(map(operator.mul, range(11), range(11))) #   0   10,           
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>> list(map(operator.mul, range(11), [2, 4, 8])) #                    ,                    
[0, 4, 16]
>>> list(map(lambda a, b: (a, b), range(11), [2, 4, 8])) #          zip   
[(0, 2), (1, 4), (2, 8)]
>>> list(itertools.starmap(operator.mul, enumerate('albatroz', 1))) #  1   ,         ,            
['a', 'll', 'bbb', 'aaaa', 'ttttt', 'rrrrrr', 'ooooooo', 'zzzzzzzz']
>>> list(itertools.starmap(lambda a, b: b / a, enumerate(itertools.accumulate(sample), 1))) #      
[5.0, 4.5, 3.6666666666666665, 4.75, 5.2, 5.333333333333333, 5.0, 4.375, 4.888888888888889, 4.5]

未完待続~