Quantcast
Channel: dictionaryタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 99

辞書型データのvalueの直積を返したい

$
0
0

やりたいこと

pythonで、辞書が持つvalue同士の直積を、対応するkeyを変えずに辞書としてそれぞれ出力したい。

具体的には

{'A':[1,2,3],'B':[4,5]}

という辞書が存在するときに

[{'A':1,'B':4},{'A':1,'B':5},{'A':2,'B':4},{'A':2,'B':5},{'A':3,'B':4},{'A':3,'B':5}]

といった具合のリストが得られるようにしたい。

前提知識

itertools.product()で直積を求められます。

https://docs.python.org/ja/3/library/itertools.html#itertools.product

実装

test1.py
importitertoolstest1={'A':[1,2,3],'B':[4,5]}product=[xforxinitertools.product(*test1.values())]result=[dict(zip(test1.keys(),r))forrinproduct]forrinresult:print(r)
console
{'A': 1, 'B': 4}
{'A': 1, 'B': 5}
{'A': 2, 'B': 4}
{'A': 2, 'B': 5}
{'A': 3, 'B': 4}
{'A': 3, 'B': 5}

valueの型が異なっていてもOK

test2.py
importitertoolstest2={'A':['TEST',1,2.5],'B':[[3,4],5]}product=[xforxinitertools.product(*test2.values())]result=[dict(zip(test1.keys(),r))forrinproduct]forrinresult:print(r)
console
{'A': 'TEST', 'B': [3, 4]}
{'A': 'TEST', 'B': 5}
{'A': 1, 'B': [3, 4]}
{'A': 1, 'B': 5}
{'A': 2.5, 'B': [3, 4]}
{'A': 2.5, 'B': 5}

注意点

直積を求めたい辞書のvalueはlist型でなければなりません。
例えば以下の様な辞書を変換しようとするとエラーとなります。

test3.py
importitertoolstest3={'A':1,'B':[2,3],'C':[4,5,6]}product=[xforxinitertools.product(*test3.values())]result=[dict(zip(test1.keys(),r))forrinproduct]forrinresult:print(r)
console
Traceback (most recent call last):
  File "test3.py", line 5, in <module>    product = [x for x in itertools.product(*test1.values())]
TypeError: 'int' object is not iterable

この様な場合は一旦valueを舐めてlistでなければlistに変換してあげれば良いです。

test4.py
importitertoolstest4={'A':1,'B':[2,3],'C':[4,5,6]}test4_after=dict([(key,valiftype(val)islistelse[val])forkey,valintest4.items()])product=[xforxinitertools.product(*test4_after.values())]result=[dict(zip(test4_after.keys(),r))forrinproduct]forrinresult:print(r)
console
{'A': 1, 'B': 2, 'C': 4}
{'A': 1, 'B': 2, 'C': 5}
{'A': 1, 'B': 2, 'C': 6}
{'A': 1, 'B': 3, 'C': 4}
{'A': 1, 'B': 3, 'C': 5}
{'A': 1, 'B': 3, 'C': 6}

key値を捨てる場合

key値を捨ててvalueの直積だけ欲しい場合はzipの部分を消せばOK。

test5.py
importitertoolstest5={'A':[1,2],'B':[4,5,6]}product=[xforxinitertools.product(*test5.values())]forrinproduct:print(r)
console
(1, 4)
(1, 5)
(1, 6)
(2, 4)
(2, 5)
(2, 6)

Viewing all articles
Browse latest Browse all 99

Trending Articles