【问题标题】:efficiency of Python's itertools.product()Python 的 itertools.product() 的效率
【发布时间】:2015-08-12 09:02:45
【问题描述】:

所以我正在寻找不同的方法来计算 n 数组的笛卡尔积,我遇到了使用以下代码的相当优雅的解决方案(此处为 SO):

import itertools
    for array in itertools.product(*arrays):
        print array

查看itertools.product()python doc page(我使用的是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)

(确实注意以下几点:这个函数等价于下面的代码,只是实际实现不会在内存中建立中间结果:

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

我错了吗?

【问题讨论】:

  • Python 代码是说明性,以大致显示输出是如何产生的。它不应该用来衡量实际实现的复杂性,请查看C source for the object
  • 但是效率通常不一样吗?
  • 仅当 实际 实现使用相同算法时。我没有验证它确实如此。 Python 代码 sn-p 通常是为了帮助理解生成的内容而进行的简化,而不是对实际 C 实现的忠实再现。
  • 大小为 m 和 n 的数组的笛卡尔积的最佳情况算法复杂度实际上是 O(mn),所以我不确定您在这里期待什么。

标签: python algorithm performance cartesian-product set-theory


【解决方案1】:

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

为什么会这样,为什么没有办法进一步优化?

好吧,在这种情况下,输出的大小直接是“所有n[i]的乘积”,这取决于我们正在讨论的函数的性质. Python 通过将其实现为生成器使这一点更加明显。所以对于每个元素,这个生成器都会产生一个元素,最终它会产生与所述产品一样多的元素。

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

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

【讨论】:

    猜你喜欢
    • 2011-03-02
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 2017-04-13
    • 2018-04-21
    • 1970-01-01
    相关资源
    最近更新 更多