web-dev-qa-db-ja.com

itertools.productの長さを取得するにはどうすればよいですか?

itertoolsを使用して、入力パラメーターのすべての可能な組み合わせを反復する数値シミュレーションを実行しています。以下の例では、2つのパラメーターと6つの可能な組み合わせがあります。

_import itertools

x = [0, 1]
y = [100, 200, 300]

myprod = itertools.product(x, y)

for p in myprod:
    print p[0], p[1]
    # run myfunction using p[0] as the value of x and p[1] as the value of y
_

myprodのサイズ(例では6)を取得するにはどうすればよいですか? forループが始まる前にこれを印刷する必要があります。

myprodはリストではないことを理解しています。 len(list(myprod))を計算できますが、これはイテレータを消費するため、forループは機能しなくなります。

私は試した:

_myprod2=copy.deepcopy(myprod)
mylength = len(list(myprod2))
_

しかし、これも機能しません。私はそれをできた:

_myprod2=itertools.product(x,y)
mylength = len(list(myprod2))
_

しかし、それはほとんどエレガントでパイソン的ではありません!

16

reducemul を組み合わせて、任意の数のソース反復可能オブジェクトに対して Kevinの回答 を実装するには:

>>> import functools, itertools, operator
>>> iters = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> functools.reduce(operator.mul, map(len, iters), 1)
27
>>> len(list(itertools.product(*iters)))
27

ソースイテレータ自体がシーケンスではなくイテレータである場合、これは機能しないことに注意してください。同じ理由で、itertools.productの長さを取得する最初の試みが失敗しました。 Python一般的にそしてitertoolsは具体的には任意の長さ(無限を含む!)のイテレータでメモリ効率の良い方法で機能するので、事前に長さを見つけることは実際には当てはまりませんそれは対処するように設計されました。

12
jonrsharpe

どうですか:

mylength = len(x) * len(y)
2
Kevin

私が使用した代替ソリューション:

import itertools

param = (('a', 'b'), (1, 2)) # a list of lists

# Calculate all combinations
combinations = itertools.product(*param)

# Calculate number of combinations
total_combinations = 1
for i in param:
    total_combinations = total_combinations * len(i)
0
Tom Saenen