我有一对列表的键及其可能的值,这些值是从命令行解析的。例如:
[('-a',['1','2','3']), ('-b',['1','2'])]
我的目标是按如下方式生成组合:
prefix -a=1 -b=1 suffix
prefix -a=1 -b=2 suffix
prefix -a=2 -b=1 suffix
prefix -a=2 -b=2 suffix
prefix -a=3 -b=1 suffix
prefix -a=3 -b=2 suffix
问题是,列表可以是任何长度,子列表中的值也是如此。
可能的解决方案是使用某种递归,到目前为止我写的并没有给我我想要的东西:
def runner(args, comd=""):
for i in range(len(args)):
op, vals = args[i]
for val in vals:
comd = op + "=" + val + " " + runner(args[1:], comd)
if i == len(args) - 1:
print ("prefix " + comd + " suffix")
return comd
答案 0 :(得分:3)
你想要做两个列表的cartesian product。使用itertools.product()
来执行此操作。例如:
>>> my_list = [('-a',['1','2','3']), ('-b',['1','2'])]
>>> from itertools import product
>>> list(product(my_list[0][1], my_list[1][1]))
[('1', '1'), ('1', '2'), ('2', '1'), ('2', '2'), ('3', '1'), ('3', '2')]
它从两个列表中提供list
的所有组合tuple
。
现在,出现问题,下面是示例代码:
my_list = [('-a',['1','2','3']), ('-b',['1','2'])]
keys, value_list = zip(*my_list)
for item in product(*value_list):
val_list = ['{}={}'.format(key, val) for key, val in zip(keys, item)]
print 'prefix {} suffix'.format(' '.join(val_list))
# Output:
prefix -a=1 -b=1 suffix
prefix -a=1 -b=2 suffix
prefix -a=2 -b=1 suffix
prefix -a=2 -b=2 suffix
prefix -a=3 -b=1 suffix
prefix -a=3 -b=2 suffix
<强>解释强>
zip([iterable, ...])
返回元组列表,其中第i个元组包含来自每个参数序列或迭代的第i个元素。返回的列表的长度被截断为最短参数序列的长度。例如,在上面的代码中:
>>> keys, value_list = zip(*my_list) # zipping the unwrapped "my_list"
>>> keys # value of keys
('-a', '-b')
>>> value_list # value of values_list
(['1', '2', '3'], ['1', '2'])
然后我在values_list
上执行笛卡尔产品(如开头所述)并再次在zip
和keys
上执行item
笛卡尔积的1}}。