我有这样的字典:
config = {
'CONF_A': ['a1', 'a2', 'a3'],
'CONF_B': ['b1', 'b2'],
'CONF_C': {
'CONF_C1': ['c1'],
'CONF_C2': ['c21','c22']
}
}
我需要枚举CONF_A和CONF_B的所有值,首先使用CONF_C1中的所有值,然后使用CONF_C2中的所有值。 e.g:
('a1', 'b1', 'c1')
('a1', 'b2', 'c1')
('a2', 'b1', 'c1')
('a2', 'b2', 'c1')
('a3', 'b1', 'c1')
('a3', 'b2', 'c1')
.... same for 'c21'
.... same for 'c22'
我也需要为每一个都拥有密钥。我可以得到一个只包含CONF_A和CONF_B的配置(见下文),但我不知道如何枚举每个CONF_C元素。
>>> for x in itertools.product(*conf.itervalues()):
for k, v in itertools.izip(conf,x):
print k,v
...
CONF_A a1
CONF_B b1
CONF_A a1
CONF_B b2
CONF_A a2
CONF_B b1
CONF_A a2
CONF_B b2
CONF_A a3
CONF_B b1
CONF_A a3
CONF_B b2
N.B。 CONF_C元素的键应该是' CONF_C1'和' CONF_C2'
----编辑----
@ Patrick.Haugh为问题的第一部分提供了这个答案:
for x in product(config['CONF_A'], config['CONF_B'], chain.from_iterable(config['CONF_C'].values())):
这适用于获取笛卡儿产品,但我仍然需要重新输入密钥。当我执行以下操作时:
for k, v in itertools.izip(config, x):
我得到了密钥CONF_A,CONF_B和CONF_C。但是,值的顺序相反,例如
{'CONF_A': c1, 'CONF_B': b1, 'CONF_C': 'a1'}
此外,我试图弄清楚如何确保C的密钥与CONF_C值匹配,即
{'CONF_A': a1, 'CONF_B': b1, 'CONF_C1': 'c1'}
{'CONF_A': a1, 'CONF_B': b1, 'CONF_C2': 'c21'}
答案 0 :(得分:4)
将itertools.product
与itertools.chain
from itertools import product, chain
list(product(config['CONF_A'], config['CONF_B'], chain.from_iterable(config['CONF_C'].values())))
给我们
[('a1', 'b1', 'c1'), ('a1', 'b1', 'c21'), ('a1', 'b1', 'c22'), ('a1', 'b2', 'c1'),
('a1', 'b2', 'c21'), ('a1', 'b2', 'c22'), ('a2', 'b1', 'c1'), ('a2', 'b1', 'c21'),
('a2', 'b1', 'c22'), ('a2', 'b2', 'c1'), ('a2', 'b2', 'c21'), ('a2', 'b2', 'c22'),
('a3', 'b1', 'c1'), ('a3', 'b1', 'c21'), ('a3', 'b1', 'c22'), ('a3', 'b2', 'c1'),
('a3', 'b2', 'c21'), ('a3', 'b2', 'c22')]
编辑:
a_gen = (('CONF_A', a) for a in config['CONF_A'])
b_gen = (('CONF_B', b) for b in config['CONF_B'])
c_gen = ((k, e) for k, v in config['CONF_C'].items() for e in v)
for i in product(a_gen, b_gen, c_gen):
print(i)
给我们
(('CONF_A', 'a1'), ('CONF_B', 'b1'), ('CONF_C1', 'c1'))
(('CONF_A', 'a1'), ('CONF_B', 'b1'), ('CONF_C2', 'c21'))
(('CONF_A', 'a1'), ('CONF_B', 'b1'), ('CONF_C2', 'c22'))
(('CONF_A', 'a1'), ('CONF_B', 'b2'), ('CONF_C1', 'c1'))
(('CONF_A', 'a1'), ('CONF_B', 'b2'), ('CONF_C2', 'c21'))
(('CONF_A', 'a1'), ('CONF_B', 'b2'), ('CONF_C2', 'c22'))
(('CONF_A', 'a2'), ('CONF_B', 'b1'), ('CONF_C1', 'c1'))
(('CONF_A', 'a2'), ('CONF_B', 'b1'), ('CONF_C2', 'c21'))
(('CONF_A', 'a2'), ('CONF_B', 'b1'), ('CONF_C2', 'c22'))
(('CONF_A', 'a2'), ('CONF_B', 'b2'), ('CONF_C1', 'c1'))
(('CONF_A', 'a2'), ('CONF_B', 'b2'), ('CONF_C2', 'c21'))
(('CONF_A', 'a2'), ('CONF_B', 'b2'), ('CONF_C2', 'c22'))
(('CONF_A', 'a3'), ('CONF_B', 'b1'), ('CONF_C1', 'c1'))
(('CONF_A', 'a3'), ('CONF_B', 'b1'), ('CONF_C2', 'c21'))
(('CONF_A', 'a3'), ('CONF_B', 'b1'), ('CONF_C2', 'c22'))
(('CONF_A', 'a3'), ('CONF_B', 'b2'), ('CONF_C1', 'c1'))
(('CONF_A', 'a3'), ('CONF_B', 'b2'), ('CONF_C2', 'c21'))
(('CONF_A', 'a3'), ('CONF_B', 'b2'), ('CONF_C2', 'c22'))