Python:如何从一系列数字范围创建组合列表

时间:2013-08-24 21:04:42

标签: python

对于n长度的数值列表,e。 G。 [1, 3, 1, 2, ...],我想创建一个列表,列出range[x+1]中所有可能的值组合,其中x是列表中的值。输出可能如下所示:

for list[1, 3, 2] return all possible lists of range[x+1] values:
    # the sequence of the list is unimportant
[
[0,0,0],[1,0,0],[0,1,0],[0,2,0],[0,3,0],[0,0,1],[0,0,2],[1,1,0],
[1,2,0],[1,3,0],[1,0,1],[1,0,2],[0,1,1],[0,2,1],[0,3,1],[0,1,2],
[0,2,2],[0,3,2],[1,1,1],[1,2,1],[1,3,1],[1,1,2],[1,2,2],[1,3,2]
]

因此,在此示例中,我正在寻找[e1, e2, e3]

e1 in [0,1], e2 in [0,1,2,3] and e3 in [0,1,2]的所有变体形式

6 个答案:

答案 0 :(得分:5)

Python的itertools模块有一个可以满足您需求的工具:

import itertools
p = itertools.permutations([0, 1, 2, 3])
p_as_list = list(p)

编辑:由于您的需求非常具体,您可以从拥有自己的功能中获益,这个功能与此相似:(注意我还没有完成实现,也许有人可能会对此进行改进):

def magic_permutations (*args):
    lists = []
    larg = len(args)
    for i in range(larg):
        lists.append([])
    i = 0
    for nums in args: 
        for num in nums:
            if i >= larg:
                i = 0
            lists[i].append(num)
            i += 1
    return lists

编辑:我第一次误解了你的问题,所以我会为此道歉。不过我会留下这个。

答案 1 :(得分:5)

itertools.product与动态指定的迭代器列表一起使用:

vals = [1,3,2]
for item in itertools.product(*[range(x+1) for x in vals]):
    print item

输出:

(0, 0, 0)
(0, 0, 1)
(0, 0, 2)
(0, 1, 0)
(0, 1, 1)
(0, 1, 2)
(0, 2, 0)
(0, 2, 1)
(0, 2, 2)
(0, 3, 0)
(0, 3, 1)
(0, 3, 2)
(1, 0, 0)
(1, 0, 1)
(1, 0, 2)
(1, 1, 0)
(1, 1, 1)
(1, 1, 2)
(1, 2, 0)
(1, 2, 1)
(1, 2, 2)
(1, 3, 0)
(1, 3, 1)
(1, 3, 2)

答案 2 :(得分:3)

要获得问题中显示的确切序列(虽然顺序不同,但这不是问题)请使用此功能:

import itertools as it

def combs(lst):
    return [list(e) for e in it.product(*(range(x+1) for x in lst))]

结果如预期:

combs([1, 3, 2])

=> [[0, 0, 0], [0, 0, 1], [0, 0, 2], [0, 1, 0], [0, 1, 1], [0, 1, 2],
    [0, 2, 0], [0, 2, 1], [0, 2, 2], [0, 3, 0], [0, 3, 1], [0, 3, 2],
    [1, 0, 0], [1, 0, 1], [1, 0, 2], [1, 1, 0], [1, 1, 1], [1, 1, 2],
    [1, 2, 0], [1, 2, 1], [1, 2, 2], [1, 3, 0], [1, 3, 1], [1, 3, 2]]

答案 3 :(得分:2)

for ii in itertools.product(range(2),range(4),range(3):
    print ii
(0, 0, 0)
(0, 0, 1)
(0, 0, 2)
(0, 1, 0)
(0, 1, 1)
(0, 1, 2)
(0, 2, 0)
(0, 2, 1)
(0, 2, 2)
(0, 3, 0)
(0, 3, 1)
(0, 3, 2)
(1, 0, 0)
(1, 0, 1)
(1, 0, 2)
(1, 1, 0)
(1, 1, 1)
(1, 1, 2)
(1, 2, 0)
(1, 2, 1)
(1, 2, 2)
(1, 3, 0)
(1, 3, 1)
(1, 3, 2)

答案 4 :(得分:2)

它的顺序不一样,但我认为这就是你想要的:

def xrangeCombinations(input):
    if len(input) > 1:
        for i in xrange(input[-1] + 1):
            for j in xrangeCombinations(input[:-1]):
                yield j + [i]
    else:
        for i in xrange(input[-1] + 1):
            yield [i]

for i in xrangeCombinations([1, 3, 2]):
    print i

产生输出:

[0, 0, 0]
[1, 0, 0]
[0, 1, 0]
[1, 1, 0]
[0, 2, 0]
[1, 2, 0]
[0, 3, 0]
[1, 3, 0]
[0, 0, 1]
[1, 0, 1]
[0, 1, 1]
[1, 1, 1]
[0, 2, 1]
[1, 2, 1]
[0, 3, 1]
[1, 3, 1]
[0, 0, 2]
[1, 0, 2]
[0, 1, 2]
[1, 1, 2]
[0, 2, 2]
[1, 2, 2]
[0, 3, 2]
[1, 3, 2]

这个解决方案可能比替代方案慢,所以如果速度是一个问题,你应该改进它。

答案 5 :(得分:1)

如果您不介意最后获取元组,请使用numpy

>>> import numpy as np
>>> e1=np.array([0,1])
>>> e2=np.array([0,1,2])
>>> e3=np.array([0,1,2,3])
>>> g=np.meshgrid(e1,e2,e3) #you need numpy ver>1.7.0, change the order of final result by changing the order of e1, e2, e3
>>> zip(*[item.flatten() for item in g])
[(0, 0, 0), (0, 0, 1), (0, 0, 2), (0, 0, 3), (1, 0, 0), (1, 0, 1), (1, 0, 2), (1, 0, 3), (0, 1, 0), (0, 1, 1), (0, 1, 2), (0, 1, 3), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 1, 3), (0, 2, 0), (0, 2, 1), (0, 2, 2), (0, 2, 3), (1, 2, 0), (1, 2, 1), (1, 2, 2), (1, 2, 3)]