【问题标题】:Cartesian product generic function in PythonPython中的笛卡尔积泛型函数
【发布时间】:2013-07-19 18:55:04
【问题描述】:

在 Python 中,如何编写一个通用函数来生成重复 n 次的同一集合的笛卡尔积而不使用递归和不使用 itertools 包?该函数应该有两个参数:集合和n次。

例如:

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

等等

【问题讨论】:

  • 为什么不能使用itertools?这是作业吗?
  • 没有 itertools... 你对 numpy 还好吗?

标签: python for-loop set cartesian-product


【解决方案1】:

您可以通过迭代构建结果来概括您已经在使用的基于理解的技术:

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

【讨论】:

  • 这正是我一直在寻找的,也让我意识到在 Python 中单元素元组需要一个尾随逗号。
【解决方案2】:
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]]

【讨论】:

    【解决方案3】:

    我认为您正在寻找所谓的集合中的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)]
    >>> 
    

    【讨论】:

      猜你喜欢
      • 2022-01-19
      • 1970-01-01
      • 2019-04-20
      • 1970-01-01
      • 2012-02-24
      • 2021-05-18
      • 1970-01-01
      • 2016-02-15
      • 2021-11-19
      相关资源
      最近更新 更多