python二维递归

时间:2016-10-18 10:15:48

标签: python python-3.x recursion combinations

我有一对列表的键及其可能的值,这些值是从命令行解析的。例如:

[('-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

1 个答案:

答案 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上执行笛卡尔产品(如开头所述)并再次在zipkeys上执行item笛卡尔积的1}}。