【问题标题】:Python Memory Error when generating pairs using itertools.combinations使用 itertools.combinations 生成对时出现 Python 内存错误
【发布时间】:2013-09-20 00:14:46
【问题描述】:

我有一个未指定数字的 int 列表。我想找出列表中匹配某个值的两个整数之间的差异。

from itertools import combinations

#Example of a list
intList = [3, 6, 2, 7, 1]
diffList = [abs(a -b) for a, b in combinations(intList, 2)]

#Given if difference = 2    
print diffList.count(2)

代码 sn-p 有效,但是当给出更大的列表时,我收到 MemoryError。谁能告诉我代码是否有问题或错误是由于我的硬件限制造成的?

【问题讨论】:

  • 列表可以有多长?
  • @MostafaR - 可能有数百个。组合可能会达到数千..

标签: python list compiler-errors out-of-memory


【解决方案1】:

“更大的列表”到底有多大?如果len(intList)n,则len(diffList) 将是n*(n-1)//2n 的组合数一次取 2 个)。如果n 足够大,这将消耗你所有的内存。

如果你只关心值 2,

print sum(abs(a-b) == 2 for a, b in combinations(intList, 2))

是一种不管intList 有多大都会消耗很少内存的方法。但是,它仍然需要与len(intList) 的平方成正比的时间

【讨论】:

  • 这个解决方案非常聪明。
  • 这实际上一点儿也不难,但它是一个非常有用的技巧,可以帮助你很多次。因此,如果您不明白为什么会这样,那么值得尝试弄清楚。我的回答试图有效地解释相同的技巧,但一步一步。
【解决方案2】:

您可以使用以下代码解决您的问题:

result = 0
for a, b in combinations(intList, 2):
    if abs(a - b) == 2:
        result += 1
print result

所以您的问题不仅仅是您的硬件限制,而是您的硬件限制和错误代码。

【讨论】:

  • 感谢您的建议。我没有考虑到我可能会遇到产生远远超出内存处理能力的可能性。我发现有不同的方法可以获得相同的结果。
【解决方案3】:

您创建了一个带有列表解析的列表,然后调用了它的count 方法。相反,只需使用生成器表达式创建一个迭代器,然后调用一个接受任何可迭代对象的 icount 函数:

diffs = (abs(a -b) for a, b in combinations(intList, 2))
print icount(diffs, 2)

它与您的原始代码几乎相同,但不使用任何额外的内存。


icount这个函数当然不存在,但你应该可以自己写。

def icount(iterable, value):
    result = 0
    for element in iterable:
        if element == value:
            result += 1
    return result

……或……

def ilen(iterable):
    return sum(1 for _ in iterable)
def icount(iterable, value):
    filtered = (elem for elem in iterable if elem == value)
    return ilen(filtered)

……或……

def icount(iterable, value):
    return sum(elem == value for elem in iterable)

…或(使用itertools recipes)…

def icount(iterable, value):
    return quantify(iterable, lambda elem: elem == value)

如果需要,您可以将表达式合并到 icount 函数中,并在一行中完成所有操作,然后您就会得到 Tim Peters 的确切答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-13
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多