1

对于长度为 n 的数值列表,例如[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]from的所有变体e1 in [0,1], e2 in [0,1,2,3] and e3 in [0,1,2]

4

6 回答 6

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

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

于 2013-08-24T21:07:59.990 回答
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)
于 2013-08-24T21:58:10.140 回答
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]]
于 2013-08-24T21:54:52.477 回答
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]

此解决方案可能比其他解决方案慢,因此如果速度是一个问题,您可能应该改进它。

于 2013-08-24T22:16:15.130 回答
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)
于 2013-08-24T21:40:05.090 回答
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)]
于 2013-08-24T22:19:07.630 回答