Python的效率';s itertools.product()

Python的效率';s itertools.product(),python,algorithm,performance,cartesian-product,set-theory,Python,Algorithm,Performance,Cartesian Product,Set Theory,因此,我正在研究计算n个数组的笛卡尔积的不同方法,并且我发现了使用以下代码的相当优雅的解决方案(这里就是这样): import itertools for array in itertools.product(*arrays): print array 查看itertools.product()的代码(我使用的是2.7,顺便说一句),它表示代码相当于以下内容: def product(*args, **kwds): # product('ABCD', 'xy')

因此,我正在研究计算n个数组的笛卡尔积的不同方法,并且我发现了使用以下代码的相当优雅的解决方案(这里就是这样):

import itertools
    for array in itertools.product(*arrays):
        print array
查看
itertools.product()
的代码(我使用的是2.7,顺便说一句),它表示代码相当于以下内容:

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)
(注意:此函数与以下代码等效,但实际实现不会在内存中生成中间结果:)

我不是计算机科学的人,所以我很不擅长估计这个算法的效率。我的第一个猜测是
O(n^2)
(由于嵌套的for循环)


我错了吗

你完全正确。也就是说,在两个数组输入的特殊情况下,大小均为n。在1..k中i的大小为n[i]的k个数组的一般情况下,它将是O(所有n[i]的乘积)

为什么会出现这种情况,为什么没有进一步优化的方法

在这种情况下,输出的大小直接是“所有n[i]的乘积”,这取决于我们正在讨论的函数的性质。Python将其实现为一个生成器,从而使这一点更加明显。因此,对于每个元素,这个生成器生成一个元素,最终生成的元素数与所述产品的元素数相同

当然,如果某个如此明显的东西做了x倍的事情,那么它的效率不可能比O(x)更好。如果每个元素的工作量也取决于输入大小,则情况可能会更糟。因此,准确地说,这里每个元素的工作量取决于我们放入的数组的数量,所以真正的工作量是


O(k×所有n[i]的乘积)

Python代码是说明性的,大致说明了输出是如何产生的。不应该用它来衡量实际实现的复杂性,请看下面的例子。但是,效率通常不是一样的吗?只有当实际实现使用相同的算法时。我没有证实它是真的。Python代码片段通常是为了帮助理解生成的内容而进行的简化,而不是忠实地重新创建实际的C实现。大小为m和n的数组的笛卡尔乘积的最佳情况算法复杂性是,事实上,我不确定您在这里到底期望什么。