如何在一组数组中找到所有元素组合?

时间:2012-03-25 03:02:56

标签: python algorithm

我正在使用以下内容简化更大的复杂问题......

给定三个整数数组,返回每个元素的所有可能组合的最有效方法是什么?请注意,每个数组中的每个值始终位于相同的位置,因此[A,B,C]将与[C,B,A]相同。我想要的结果是一个数组数组,每个哈希包含一个组合。例如:

假设:

var array1 = [1,2]
var array2 = [a,b]
var array3 = [foo,bar]

结果将是:

[
  [1,a,foo],
  [2,a,foo],
  [1,b,foo],
  [2,b,foo],
  [1,a,bar],
  [2,a,bar],
  [1,b,bar],
  [2,b,bar]
]

5 个答案:

答案 0 :(得分:8)

在Python中,使用itertools.product

itertools.product(array1, array2, array3)

如果需要序列,则将其包装在list中,而不仅仅是可迭代的。

如果您想了解它是如何完成的,这是itertools文档中提供的“等效”代码:

def product(*args, **kwds):
    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
    pools = map(tuple, args) * kwds.get('repeat', 1)
    result = [[]]
    for pool in pools:
        result = [x+[y] for x in result for y in pool]
    for prod in result:
        yield tuple(prod)

尽管该版本的代码效率不高。

PyPy version of itertools中还有一个Python实现。

答案 1 :(得分:4)

itertools.product直接解决了这个问题,速度非常快:

>>> from itertools import product
>>> list(product([1,2], ['a', 'b'], ['foo', 'bar']))
[(1, 'a', 'foo'), (1, 'a', 'bar'), (1, 'b', 'foo'), (1, 'b', 'bar'), (2, 'a', 'foo'), (2, 'a', 'bar'), (2, 'b', 'foo'), (2, 'b', 'bar')]

答案 2 :(得分:3)

这是在Python中执行此操作的一种相当冗长的方式:

# define the sets of items
array1 = [1,2]
array2 = ['a', 'b']
array3 = ['foo', 'bar']

# create an empty list to collect combinations
all_combinations = []

# enumerate all combinations by nested iteration
for i in array1:
    for j in array2:
        for k in array3:
            all_combinations.append([i, j, k]) 

# print all combinations
for item in all_combinations:
    print item

答案 3 :(得分:3)

以下是javascript中的解决方案:

function p(o){
    var count=1;
    var step_len=[];
    for(var i=0;i<o.length;i++){
        step_len[i]=count;
        count*=o[i].length;
    }
    for(var i=0;i<count;i++){
        var tmp=[];
        for(var n=0;n<o.length;n++){
            tmp.push(o[n][Math.floor(i/step_len[n])%o[n].length]);
        }
        console.log(tmp);
    }
}

var o=[
    [1,2],
    ['a','b'],
    ['foo','bar']
];

p(o);

/* console output:
[1, "a", "foo"]
[2, "a", "foo"]
[1, "b", "foo"]
[2, "b", "foo"]
[1, "a", "bar"]
[2, "a", "bar"]
[1, "b", "bar"]
[2, "b", "bar"]
*/

它适用于任意数量的数组。

演示:http://jsfiddle.net/u9zJQ/

答案 4 :(得分:1)

刚刚做了一个python等同于@ stewe的回答。我喜欢这个答案比使用itertools的任何答案更好,因为它更通用,可以应用于任何语言。我在VBA中需要这个,它就像一个魅力...... +1

def p(o):
    count=1
    step_len=[]
    for i, item in enumerate(o):
        step_len.append(count)
        count *= len(o[i])

    for i in range(count):
        tmp=[]
        for n, item in enumerate(o):
            tmp.append(o[n][(i//step_len[n]) % len(o[n])])

        print tmp
    print count