我正在使用以下内容简化更大的复杂问题......
给定三个整数数组,返回每个元素的所有可能组合的最有效方法是什么?请注意,每个数组中的每个值始终位于相同的位置,因此[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]
]
答案 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"]
*/
它适用于任意数量的数组。
答案 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