サーチ…


構文

  • import itertools

関数を使用して反復可能オブジェクトから項目をグループ化する

グループ化する必要がある繰り返し可能なものから開始する

lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 2, 6)]

グループ化されたジェネレータを生成し、各タプルの2番目の要素でグループ化します。

def testGroupBy(lst):
    groups = itertools.groupby(lst, key=lambda x: x[1])
    for key, group in groups:
        print(key, list(group))

testGroupBy(lst)

# 5 [('a', 5, 6)]
# 2 [('b', 2, 4), ('a', 2, 5), ('c', 2, 6)]

連続する要素のグループのみがグループ化されます。 groupby for Egを呼び出す前に同じキーでソートする必要があるかもしれません(最後の要素が変更されます)

lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 5, 6)]
testGroupBy(lst)

# 5 [('a', 5, 6)]
# 2 [('b', 2, 4), ('a', 2, 5)]
# 5 [('c', 5, 6)]

groupbyによって返されたグループは、次の繰り返しの前に無効になるイテレータです。たとえば、グループをキーでソートする場合は、次のようには機能しません。グループ2がフェッチされると、グループ5は無効になります

lst = [("a", 5, 6), ("b", 2, 4), ("a", 2, 5), ("c", 2, 6)]
groups = itertools.groupby(lst, key=lambda x: x[1])
for key, group in sorted(groups):
    print(key, list(group))

# 2 [('c', 2, 6)]
# 5 []

ソートを正しく行うには、ソート前にイテレータからリストを作成します

groups = itertools.groupby(lst, key=lambda x: x[1])
for key, group in sorted((key, list(group)) for key, group in groups):
    print(key, list(group))
      
# 2 [('b', 2, 4), ('a', 2, 5), ('c', 2, 6)]
# 5 [('a', 5, 6)]

発電機のスライスを取る

Itertools "islice"では、ジェネレーターをスライスすることができます:

results = fetch_paged_results()  # returns a generator
limit = 20  # Only want the first 20 results
for data in itertools.islice(results, limit):
    print(data)

通常、ジェネレータをスライスすることはできません:

def gen():
    n = 0
    while n < 20:
        n += 1
        yield n

for part in gen()[:3]:
    print(part)

あげる

Traceback (most recent call last):
  File "gen.py", line 6, in <module>
    for part in gen()[:3]:
TypeError: 'generator' object is not subscriptable

しかし、これは動作します:

import itertools

def gen():
    n = 0
    while n < 20:
        n += 1
        yield n

for part in itertools.islice(gen(), 3):
    print(part)

通常のスライスと同様に、 startstopstep引数も使用できます。

itertools.islice(iterable, 1, 30, 3)

itertools.product

この関数は、繰り返し可能なリストのデカルト積を反復することを可能にします。

例えば、

for x, y in itertools.product(xrange(10), xrange(10)):
    print x, y

for x in xrange(10):
    for y in xrange(10):
        print x, y

可変数の引数を受け付けるすべてのPython関数と同様に、*演算子を使用して、展開するためにitertools.productにリストを渡すことができます。

このように、

its = [xrange(10)] * 2
for x,y in itertools.product(*its):
    print x, y

前述の両方の例と同じ結果が得られます。

>>> from itertools import product
>>> a=[1,2,3,4]
>>> b=['a','b','c']
>>> product(a,b)
<itertools.product object at 0x0000000002712F78>
>>> for i in product(a,b):
...     print i
...
(1, 'a')
(1, 'b')
(1, 'c')
(2, 'a')
(2, 'b')
(2, 'c')
(3, 'a')
(3, 'b')
(3, 'c')
(4, 'a')
(4, 'b')
(4, 'c')

itertools.count

前書き:

この単純な関数は、無限の数列を生成します。例えば...

for number in itertools.count():
    if number > 20:
        break
    print(number)

我々は壊れなければならないこと、あるいは永遠に印刷することに注意してください!

出力:

0
1
2
3
4
5
6
7
8
9
10

引数:

count()startstep 2つの引数を取ります:

for number in itertools.count(start=10, step=4):
    print(number)
    if number > 20:
        break

出力:

10
14
18
22

itertools.takewhile

itertools.takewhileを使用すると、シーケンスの項目を最初に条件がFalseなるまで取得できます。

def is_even(x):
    return x % 2 == 0


lst = [0, 2, 4, 12, 18, 13, 14, 22, 23, 44]
result = list(itertools.takewhile(is_even, lst))

print(result)
  

これは[0, 2, 4, 12, 18] 0、2、4、12、18 [0, 2, 4, 12, 18]出力します。

述語に違反する最初の数(すなわち、ブール値を返す関数) is_evenは、 13ことに注意してください。 takewhileが与えられた述語に対してFalseを生成する値に出会ったら、それは壊れます。

生成される出力 takewhile以下のコードから生成された出力に類似しています。

def takewhile(predicate, iterable):
    for x in iterable:
        if predicate(x):
            yield x
        else:
            break

注: takewhiledropwhileによって生成された結果を連結すると、元のiterableが生成されます。

result = list(itertools.takewhile(is_even, lst)) + list(itertools.dropwhile(is_even, lst))

itertools.dropwhile

itertools.dropwhileを使用すると、条件が最初にFalse後にシーケンスからアイテムを取得できます。

def is_even(x):
    return x % 2 == 0


lst = [0, 2, 4, 12, 18, 13, 14, 22, 23, 44]
result = list(itertools.dropwhile(is_even, lst))

print(result)
  

これは[13, 14, 22, 23, 44] 13,14,22,23,44 [13, 14, 22, 23, 44]出力します。

この例は、 takewhile例と同じtakewhileが、 dropwhileを使用してdropwhileます

述語に違反する最初の数(すなわち、ブール値を返す関数) is_evenは、 13ことに注意してください。その前のすべての要素は破棄されます。

生成される出力 dropwhile以下のコードから生成された出力に類似しています。

def dropwhile(predicate, iterable):
    iterable = iter(iterable)
    for x in iterable:
        if not predicate(x):
            yield x
            break
    for x in iterable:
        yield x

takewhiledropwhileによって生成された結果の連結は元のiterableを生成します。

result = list(itertools.takewhile(is_even, lst)) + list(itertools.dropwhile(is_even, lst))

両方のイテレーターが使い果たされるまで2つのイテレーターを圧縮する

組み込み関数zip()と同様に、 itertools.zip_longestは2つのitertools.zip_longestうちの短い方の端を超えて反復を続けます。

from itertools import zip_longest
a = [i for i in range(5)] # Length is 5
b = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] # Length is 7
for i in zip_longest(a, b):
    x, y = i  # Note that zip longest returns the values as a tuple
    print(x, y)

オプションのfillvalue引数を渡すことができます(デフォルトは'' )。

for i in zip_longest(a, b, fillvalue='Hogwash!'):
    x, y = i  # Note that zip longest returns the values as a tuple
    print(x, y)

Python 2.6と2.7では、この関数はitertools.izip_longestと呼ばれていitertools.izip_longest

Itertoolsモジュールの組み合わせ方法

itertools.combinationsは、リストのk-コンビネーションシーケンスのジェネレータを返します。

言い換えれば 、入力リストのすべての可能なk-wise組み合わせのタプルのジェネレータを返します。

例えば:

リストがある場合:

a = [1,2,3,4,5]
b = list(itertools.combinations(a, 2))
print b

出力:

[(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5), (3, 4), (3, 5), (4, 5)]

上記の出力は、入力リストaのすべての可能な対の組み合わせのタプルのリストに変換された生成器でa

3つのすべての組み合わせを見つけることもできます:

a = [1,2,3,4,5]
b = list(itertools.combinations(a, 3))
print b

出力:

[(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 4),
 (1, 3, 5), (1, 4, 5), (2, 3, 4), (2, 3, 5),
 (2, 4, 5), (3, 4, 5)]

複数のイテレータを連鎖させる

itertools.chainを使用して、複数のジェネレータの値をitertools.chainに出力する単一のジェネレータを作成します。

from itertools import chain
a = (x for x in ['1', '2', '3', '4'])
b = (x for x in ['x', 'y', 'z'])
' '.join(chain(a, b))

結果:

'1 2 3 4 x y z'

別のコンストラクタとして、クラスメソッドchain.from_iterableを使用できます。このメソッドは、単一のパラメータとしてiterableの繰り返し可能なものをとります。上記と同じ結果を得るには:

' '.join(chain.from_iterable([a,b])

chainは任意の数の引数を取ることができますが、 chain.from_iterable無制限のiterableを連結する唯一の方法です。

itertools.repeat

n回繰り返す:

>>> import itertools
>>> for i in itertools.repeat('over-and-over', 3):
...    print(i)
over-and-over
over-and-over
over-and-over

繰り返し可能な数値の累積合計を得る

Python 3.x 3.2

accumulateと、数の累積合計(または積) accumulate得られます。

>>> import itertools as it
>>> import operator

>>> list(it.accumulate([1,2,3,4,5]))
[1, 3, 6, 10, 15]

>>> list(it.accumulate([1,2,3,4,5], func=operator.mul)) 
[1, 2, 6, 24, 120]

イテレータの要素を循環させる

cycleは無限の反復子です。

>>> import itertools as it
>>> it.cycle('ABCD')
A B C D A B C D A B C D ...

したがって、無限ループを避けるためにこれを使用する場合は、境界を与えるように注意してください。例:

>>> # Iterate over each element in cycle for a fixed range
>>> cycle_iterator = it.cycle('abc123')
>>> [next(cycle_iterator) for i in range(0, 10)]
['a', 'b', 'c', '1', '2', '3', 'a', 'b', 'c', '1']

itertools.permutations

itertools.permutationsは、反復可能な要素の連続したr長の置換を持つジェネレータを返します。

a = [1,2,3]
list(itertools.permutations(a))
# [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)]

list(itertools.permutations(a, 2))
[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]

リストの場合はa重複要素を持って、その結果の順列は、あなたが使用することができ、重複した要素を持っていますsetユニークな順列を取得します:

a = [1,2,1]
list(itertools.permutations(a))
# [(1, 2, 1), (1, 1, 2), (2, 1, 1), (2, 1, 1), (1, 1, 2), (1, 2, 1)]

set(itertools.permutations(a))
# {(1, 1, 2), (1, 2, 1), (2, 1, 1)}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow