2013-08-24 60 views
1

有關n長度的數值列表,例如: G。 [1, 3, 1, 2, ...],我想創建一個列表,其中x是列表中的一個值,其值爲range[x+1]的所有可能組合的列表。輸出可能是這個樣子:Python:如何從一系列數字範圍創建組合列表

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 in [0,1], e2 in [0,1,2,3] and e3 in [0,1,2]尋找的[e1, e2, e3]所有變化

+0

什麼是'x'在你的榜樣?長度列表'x = 3'? –

+0

@Yuval看到有問題的添加評論 – Cole

回答

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) 
+0

在快速掃描中,這似乎是我的最愛!他們都很棒。此外,這個例子讓我很容易看到如何將它變成一個lambda函數。 – Cole

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 

編輯:我第一次誤解了你的問題,所以我會爲此道歉。但我會留下這個。

+2

沒有給出想要的答案。如果'p = itertools.permutations([1,3,2])','len(list(p))'只有6. – Cole

+0

我現在明白你的意思了,除了我堅持實現。 – boxmein

+1

我不知道爲什麼這會得到這麼多upvotes;這只是錯誤的。你有正確的模塊,但功能錯誤。 – nneonneo

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) 
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]] 
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] 

這種解決方案可能是比替代品慢,所以如果速度是一個問題,你應該改善它。

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)]