我有一个带有未指定编号的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)
代码片段工作但是当给出更大的列表时,我得到了MemoryError。任何人都可以告诉我代码是否有问题或错误是由于我的硬件限制?
答案 0 :(得分:4)
“更大的名单”究竟有多大?如果len(intList)
为n
,则len(diffList)
将为n*(n-1)//2
(一次2个n
项的组合数量。如果n
足够大,这将消耗所有内存。
如果您只关心值2,
print sum(abs(a-b) == 2 for a, b in combinations(intList, 2))
是一种方法,无论intList
有多大,都会消耗很少的内存。但是,它仍然需要时间与len(intList)
的平方成比例。
答案 1 :(得分:3)
您可以使用以下代码解决问题:
result = 0
for a, b in combinations(intList, 2):
if abs(a - b) == 2:
result += 1
print result
因此,您的问题不仅仅是硬件限制,而是硬件限制和错误代码。
答案 2 :(得分: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的答案。