在Python中如何编写一个泛型函数来生成相同集合的笛卡尔积,重复n次而不使用递归而不使用itertools包?该函数应该有两个参数:set和n次。
e.g:
set1={'a','b'}
print({(x,y) for x in set1 for y in set1})
{('a', 'b'), ('b', 'a'), ('b', 'b'), ('a', 'a')}
print({(x,y,z) for x in set1 for y in set1 for z in set1})
{('b', 'a', 'b'), ('a', 'b', 'a'), ('a', 'a', 'a'), ('b', 'a', 'a'), ('a', 'a', 'b'), ('b', 'b', 'a'), ('b', 'b', 'b'), ('a', 'b', 'b')}
等
但是:
set2={'a','b','c'}
print({(x,y,z) for x in set2 for y in set2 for z in set2})
print({(w,x,y,z) for w in set2 for x in set2 for y in set2 for z in set2})
等
答案 0 :(得分:2)
您可以通过迭代构建结果来概括您已经使用的基于理解的技术:
def cartesian_product(s, dim):
if dim == 0:
return set()
res = [(e,) for e in s]
for i in range(dim - 1):
res = [e + (f,) for e in res for f in s]
return set(res)
ex = {1,2,3}
for i in range(4):
print cartesian_product(ex, i)
输出:
set([])
set([(2,), (3,), (1,)])
set([(1, 2), (3, 2), (1, 3), (3, 3), (3, 1), (2, 1), (2, 3), (2, 2), (1, 1)])
set([(1, 3, 2), (1, 3, 1), (3, 3, 1), (2, 3, 1), (3, 3, 3), (2, 3, 2), (3, 3, 2), (2, 3, 3), (3, 2, 2), (3, 1, 3), (3, 2, 3), (3, 1, 2), (1, 2, 1), (3, 1, 1), (3, 2, 1), (1, 2, 2), (1, 2, 3), (1, 1, 1), (2, 1, 2), (2, 2, 3), (2, 1, 3), (2, 2, 2), (2, 2, 1), (2, 1, 1), (1, 1, 2), (1, 1, 3), (1, 3, 3)])
答案 1 :(得分:1)
def cartesian(A,n):
tmp1,tmp2 = [],[[]]
for k in range(n):
for i in A:
tmp1.extend([j+[i] for j in tmp2])
tmp1,tmp2 = [],tmp1
return tmp2
[In:1] A = [1,2,3] ; n = 1
[Out:1] [[1], [2], [3]]
[In:2] A = [1,2,3] ; n = 4
[Out:2] [[1, 1, 1], [2, 1, 1], [3, 1, 1], [1, 2, 1], [2, 2, 1], [3, 2, 1], [1, 3, 1],
[2, 3, 1], [3, 3, 1], [1, 1, 2], [2, 1, 2], [3, 1, 2], [1, 2, 2], [2, 2, 2],
[3, 2, 2], [1, 3, 2], [2, 3, 2], [3, 3, 2], [1, 1, 3], [2, 1, 3], [3, 1, 3],
[1, 2, 3], [2, 2, 3], [3, 2, 3], [1, 3, 3], [2, 3, 3], [3, 3, 3]]
答案 2 :(得分:0)
我认为你正在寻找一套所谓的cartesian power。
我不确定为什么你不能使用itertools
,但我认为应该用一个安全措施的例子指出,即使你不使用它。
>>> import itertools
>>> set1 = {'a', 'b'}
>>> list(itertools.product(set1, repeat=0))
[()]
>>> list(itertools.product(set1, repeat=1))
[('a',), ('b',)]
>>> list(itertools.product(set1, repeat=2))
[('a', 'a'), ('a', 'b'), ('b', 'a'), ('b', 'b')]
当您需要模仿n个嵌套for循环时,递归会派上用场。
def cartesian_power(seq, p):
if p == 0:
return [()]
else:
result = []
for x1 in seq:
for x2 in cartesian_power(seq, p - 1):
result.append((x1,) + x2)
return result
>>> cartesian_power([1, 2], 0)
[()]
>>> cartesian_power([1, 2], 1)
[(1,), (2,)]
>>> cartesian_power([1, 2], 2)
[(1, 1), (1, 2), (2, 1), (2, 2)]
>>>