Pythonの循環器itertools
4941 ワード
ループオブジェクトと関数オブジェクトでは、ループの機能について説明します.ループはオブジェクトのコンテナで、複数のオブジェクトが含まれています.ループを呼び出すnext()メソッド(_next_()メソッドにより、Python 3.x)では、ループがオブジェクトを順次返します.すべてのオブジェクトが尽きるまで、ループはStopIterationエラーを挙げます.
for i in iterator構造では、ループが終了するまで、ループが戻るたびにオブジェクトがiに与えられます.iter()内蔵関数を使用すると、テーブルや辞書などのコンテナをループに変えることができます.たとえば
標準ライブラリのitertoolsパッケージは、ループをより柔軟に生成するツールを提供します.これらのツールの入力の多くは既存のループです.一方、これらのツールは完全に自分でPythonを使用して実現することができ、このパッケージは比較的標準的で効率的な実現方法を提供しているだけです.これもPythonの「解決策だけが望ましい」という理念に合っている.
むげんじゅんかんき
関数ツール
関数式プログラミングは,関数自体を処理対象とするプログラミングパターンである.Pythonでは、関数もオブジェクトなので、map()、filter()、reduce()関数などの関数式の処理を簡単に行うことができます.
itertoolsには似たようなツールが含まれています.これらの関数はパラメータとして関数を受信し、結果をループに返します.
imap関数が表示されます.この関数はmap()関数の機能と似ていますが、シーケンスではなくループを返します.要素1,4,27,すなわち1*1,2*2,3*3の結果を含む.関数pow(組み込まれた乗方関数)を最初のパラメータとして使用します.pow()は,後の2つのリストの各要素に順次作用し,関数結果を収集し,返されるループを構成する.
また、次の関数も使用できます.
starmap(pow, [(1, 1), (2, 2), (3, 3)])
powは、テーブルの各tupleに順次作用します.
ifilter関数はfilter()関数と似ていますが、ループを返します.
各要素にlambda関数を順次適用し、関数がTrueを返すと元の要素が収集されます.6, 7
また、
ifilterfalse(lambda x: x > 5, [2, 3, 5, 6, 7])
上と似ていますが、Falseを返す要素を収集します.2, 3, 5
takewhile(lambda x: x < 5, [1, 3, 6, 7, 1])
関数が偽を返すと、反復シーケンスではありません.1, 3
dropwhile(lambda x: x < 5, [1, 3, 6, 7, 1])
関数が偽を返すと、反復シーケンスが開始されます.6, 7, 1
コンビネーションツール
既存のループを組み合わせることで,新しいループを得ることができる.
chain([1,2,3],[4,5,7])#は2つのループを接続して1つになる.1, 2, 3, 4, 5, 7
product([1,2],[1,2])#複数のループセットのデカルト積.ネストされたループに相当
permutations('abc',2)#abcd'からab,bcなどの2つの要素を選択します.すべての結果を並べ替えて、新しいループに戻ります.
なお、上記の組合せの順序、すなわちab,baはいずれも返される.
combinations('abc',2)#abcd'からab,bcなどの2つの要素を選択します.すべての結果を並べ替えて、新しいループに戻ります.
なお,上記の組合せは順序,すなわちab,baを問わず,1つのabのみを返す.
combinations_with_replacement('abc',2)#は上記と似ていますが、選択した要素を2回繰り返すことができます.すなわちaa,bb,ccが多くなった
groupby()
key関数を元のループの各要素に作用します.key関数の結果に基づいて、同じ関数の結果を持つ要素を新しいループに分けます.各新しいループは、関数の結果をラベルとして返します.
これはまるで人の身長が循環器として使われているようだ.身長が180より大きい場合は「tall」を返すkey関数を使用できます.身長が160以下なら「short」に戻る.中間のは「middle」を返します.最終的に、すべての身長は3つの循環器、すなわち「tall」、「short」、「middle」に分けられる.
なおgroupbyの機能は、UNIXのuniqコマンドと同様である.グループ化する前にsorted()を使用して元のループの要素をソートし、key関数に基づいて並べ替え、同じグループの要素を先に位置に近づける必要があります.
その他のツール
compress('ABCD',[1,1,1,0])#は、[1,1,1,0]の真偽値の場合に基づいて、最初のパラメータ'ABCD'の要素を選択します.A, B, C
islice()はslice()関数に似ていますが、ループを返します.
izip()はzip()関数に似ていますが、ループを返します.
まとめ
itertoolsのツールはすべて自分で実現することができます.itertoolsは、より成形されたソリューションを提供するだけです.
for i in iterator構造では、ループが終了するまで、ループが戻るたびにオブジェクトがiに与えられます.iter()内蔵関数を使用すると、テーブルや辞書などのコンテナをループに変えることができます.たとえば
for i in iter([2, 4, 5, 6]):
print(i)
標準ライブラリのitertoolsパッケージは、ループをより柔軟に生成するツールを提供します.これらのツールの入力の多くは既存のループです.一方、これらのツールは完全に自分でPythonを使用して実現することができ、このパッケージは比較的標準的で効率的な実現方法を提供しているだけです.これもPythonの「解決策だけが望ましい」という理念に合っている.
# import the tools
from itertools import *
むげんじゅんかんき
count(5, 2) # 5 , 2, 5, 7, 9, 11, 13, 15 ...
cycle('abc') # , a, b, c, a, b, c ...
repeat(1.2) # 1.2, , 1.2, 1.2, 1.2, ...
repeat :
repeat(10, 5) # 10, 5
関数ツール
関数式プログラミングは,関数自体を処理対象とするプログラミングパターンである.Pythonでは、関数もオブジェクトなので、map()、filter()、reduce()関数などの関数式の処理を簡単に行うことができます.
itertoolsには似たようなツールが含まれています.これらの関数はパラメータとして関数を受信し、結果をループに返します.
from itertools import *
rlt = imap(pow, [1, 2, 3], [1, 2, 3])
for num in rlt:
print(num)
imap()
とmap()
の違いは、imap()
が無限配列に作用し、両配列の長さが一致しない場合、短いものに準じることである.>>> for x in itertools.imap(lambda x, y: x * y, [10, 20, 30], itertools.count(0)):
... print x
...
0
40
90
imap関数が表示されます.この関数はmap()関数の機能と似ていますが、シーケンスではなくループを返します.要素1,4,27,すなわち1*1,2*2,3*3の結果を含む.関数pow(組み込まれた乗方関数)を最初のパラメータとして使用します.pow()は,後の2つのリストの各要素に順次作用し,関数結果を収集し,返されるループを構成する.
また、次の関数も使用できます.
starmap(pow, [(1, 1), (2, 2), (3, 3)])
powは、テーブルの各tupleに順次作用します.
ifilter関数はfilter()関数と似ていますが、ループを返します.
ifilter(lambda x: x > 5, [2, 3, 5, 6, 7]
各要素にlambda関数を順次適用し、関数がTrueを返すと元の要素が収集されます.6, 7
また、
ifilterfalse(lambda x: x > 5, [2, 3, 5, 6, 7])
上と似ていますが、Falseを返す要素を収集します.2, 3, 5
takewhile(lambda x: x < 5, [1, 3, 6, 7, 1])
関数が偽を返すと、反復シーケンスではありません.1, 3
dropwhile(lambda x: x < 5, [1, 3, 6, 7, 1])
関数が偽を返すと、反復シーケンスが開始されます.6, 7, 1
コンビネーションツール
既存のループを組み合わせることで,新しいループを得ることができる.
chain([1,2,3],[4,5,7])#は2つのループを接続して1つになる.1, 2, 3, 4, 5, 7
for i in chain(dropwhile(lambda s:s>2,[1,2,3,4,5]),takewhile(lambda s:s>3,[4,5,1,2,3,4,5])):
print i
1
2
3
4
5
4
5
product([1,2],[1,2])#複数のループセットのデカルト積.ネストされたループに相当
>>> for m, n in product([1,2], [1, 2]):
... print m,n
...
1 1
1 2
2 1
2 2
permutations('abc',2)#abcd'からab,bcなどの2つの要素を選択します.すべての結果を並べ替えて、新しいループに戻ります.
なお、上記の組合せの順序、すなわちab,baはいずれも返される.
>>> for i in permutations('abc', 2) :
... print i
...
('a', 'b')
('a', 'c')
('b', 'a')
('b', 'c')
('c', 'a')
('c', 'b')
combinations('abc',2)#abcd'からab,bcなどの2つの要素を選択します.すべての結果を並べ替えて、新しいループに戻ります.
なお,上記の組合せは順序,すなわちab,baを問わず,1つのabのみを返す.
>>> for i in combinations('abc', 2) :
... print i
...
('a', 'b')
('a', 'c')
('b', 'c')
combinations_with_replacement('abc',2)#は上記と似ていますが、選択した要素を2回繰り返すことができます.すなわちaa,bb,ccが多くなった
groupby()
key関数を元のループの各要素に作用します.key関数の結果に基づいて、同じ関数の結果を持つ要素を新しいループに分けます.各新しいループは、関数の結果をラベルとして返します.
これはまるで人の身長が循環器として使われているようだ.身長が180より大きい場合は「tall」を返すkey関数を使用できます.身長が160以下なら「short」に戻る.中間のは「middle」を返します.最終的に、すべての身長は3つの循環器、すなわち「tall」、「short」、「middle」に分けられる.
>>> def height_class(h):
... if h > 180:
... return "tall"
... elif h < 160:
... return "short"
... else:
... return "middle"
...
>>> friends = [191, 158, 159, 165, 170, 177, 181, 182, 190]
>>> friends = sorted(friends, key = height_class)
>>> friends
[165, 170, 177, 158, 159, 191, 181, 182, 190]
>>> for m, n in groupby(friends, key = height_class):
... print(m)
... print(list(n))
...
middle
[165, 170, 177]
short
[158, 159]
tall
[191, 181, 182, 190]
なおgroupbyの機能は、UNIXのuniqコマンドと同様である.グループ化する前にsorted()を使用して元のループの要素をソートし、key関数に基づいて並べ替え、同じグループの要素を先に位置に近づける必要があります.
friends = [191, 158, 159, 165, 170, 177, 181, 182, 190]
>>> for m, n in groupby(friends, key = height_class):
... print(m)
... print(list(n))
...
tall
[191]
short
[158, 159]
middle
[165, 170, 177]
tall
[181, 182, 190]
その他のツール
compress('ABCD',[1,1,1,0])#は、[1,1,1,0]の真偽値の場合に基づいて、最初のパラメータ'ABCD'の要素を選択します.A, B, C
islice()はslice()関数に似ていますが、ループを返します.
izip()はzip()関数に似ていますが、ループを返します.
まとめ
itertoolsのツールはすべて自分で実現することができます.itertoolsは、より成形されたソリューションを提供するだけです.