一連の入力パラメーターのデカルト積をテストするためのコードを記述しようとしています。
私はitertools
を見てきましたが、そのproduct
関数は正確に私が望んでいるものではありません。任意の数のキーを持つディクショナリを取得する簡単な方法はありますかand各値に任意の数の要素があり、次の順列を持つディクショナリを生成しますか?
入力:
options = {"number": [1,2,3], "color": ["orange","blue"] }
print list( my_product(options) )
出力例:
[ {"number": 1, "color": "orange"},
{"number": 1, "color": "blue"},
{"number": 2, "color": "orange"},
{"number": 2, "color": "blue"},
{"number": 3, "color": "orange"},
{"number": 3, "color": "blue"}
]
私が間違った場所を探していたと言ってくれて@dfanに感謝します。私はそれを今持っています:
_from itertools import product
def my_product(inp):
return (dict(Zip(inp.keys(), values)) for values in product(*inp.values())
_
[〜#〜] edit [〜#〜]:数年後、さらにPython経験、より良い解決策はkwargs
ではなく入力の辞書;呼び出しスタイルは元の_itertools.product
_に似ています。また、ジェネレータ式を返す関数ではなく、ジェネレータ関数を記述すると、コードがより明確になると思います。
_def product_dict(**kwargs):
keys = kwargs.keys()
vals = kwargs.values()
for instance in itertools.product(*vals):
yield dict(Zip(keys, instance))
_
dictを渡す必要がある場合は、list(product_dict(**mydict))
を使用します。任意の入力クラスではなくkwargs
を使用した注目すべき変更の1つは、少なくともPython 3.6になるまで、キー/値が順序付けされないようにすることです。
Python 3バージョンの Sethの答え 。
import itertools
def dict_product(dicts):
"""
>>> list(dict_product(dict(number=[1,2], character='ab')))
[{'character': 'a', 'number': 1},
{'character': 'a', 'number': 2},
{'character': 'b', 'number': 1},
{'character': 'b', 'number': 2}]
"""
return (dict(Zip(dicts, x)) for x in itertools.product(*dicts.values()))
ちなみに、これは順列ではありません。順列は、リストの再配置です。これは、リストからの可能な選択の列挙です。
編集:それがデカルト積と呼ばれたことを思い出した後、私はこれを思いつきました:
import itertools
options = {"number": [1,2,3], "color": ["orange","blue"] }
product = [x for x in apply(itertools.product, options.values())]
print [dict(Zip(options.keys(), p)) for p in product]
# I would like to do
keys,values = options.keys(), options.values()
# but I am not sure that the keys and values would always
# be returned in the same relative order. Comments?
keys = []
values = []
for k,v in options.iteritems():
keys.append(k)
values.append(v)
import itertools
opts = [dict(Zip(keys,items)) for items in itertools.product(*values)]
結果は
opts = [
{'color': 'orange', 'number': 1},
{'color': 'orange', 'number': 2},
{'color': 'orange', 'number': 3},
{'color': 'blue', 'number': 1},
{'color': 'blue', 'number': 2},
{'color': 'blue', 'number': 3}
]