Python itertools.combinations()的超时问题

时间:2017-03-16 15:45:29

标签: python itertools

我们有一个使用itertools.combinations()的脚本,它似乎以较大的输入大小挂起。

我是一个相对缺乏经验的Python程序员,所以我不确定如何解决这个问题。有更合适的图书馆吗?或者有没有办法启用详细日志记录,我可以调试方法调用挂起的原因?

非常感谢任何帮助。

[编辑]

def findsubsets(S,m):
    return set( itertools.combinations(S, m) )

for s in AllSearchTerms:
    S.append(itemsize)
    itemsize = itemsize + 1

for i in range (1,6):
    Subset = findsubsets(S,i)
    for sub in Subset:
        for s in sub:
            sublist.append(AllSearchTerms[s])
        PComb.append(sublist)
        sublist = []

1 个答案:

答案 0 :(得分:0)

您的代码中有两件事会挂起以适应较大的输入尺寸。

首先,您的函数findsubsets调用itertools.combinations,然后将结果转换为集合。 itertools.combinations的结果是一个生成器,一次生成一个组合而不存储它们或者一次计算所有组合。将它转换为集合时,会强制Python一次计算并存储它们。因此,行return set( itertools.combinations(S, m) )几乎肯定是您的程序挂起的地方。您可以通过在该行之前和之后立即放置print语句(或其他类型的日志记录语句)来检查它,如果您看到前面的打印并且程序在您看到后续打印之前挂起,则表明您已找到问题。解决方案不是将组合转换为集合。将其保留为生成器,您的程序可以根据需要一次抓取一个组合。

其次,即使你做了我刚刚建议的事情,你的循环for sub in Subset:也是一个使用每种组合的相当紧密的循环。如果输入大小很大,那么该循环将花费很长时间并且实现我的前一段将无济于事。您可能应该重新组织程序以避免大的输入大小,或者至少在该循环期间显示某种进度。组合功能has a predictable output size,因此您甚至可以在进度条中显示完成的百分比。

itertools.combinations内没有记录,因为正确使用时不需要记录,并且没有记录将生成器转换为集合。如果需要,您可以在自己的紧密循环中实现日志记录。