在使用python的sum(dict.values())函数计算字典中值的总和时,遇到一个奇怪的问题,如果字典的大小超过一定限度,函数会给出错误的结果。具体来说,结果会突然变成负数。这个问题是在使用python 2.7在Windows 7系统中遇到的。
以下是问题的具体代码:
def primeset(limit):
pr = [0]*(limit+1)
for i in range(2,limit+1):
j = i
i += j
while i <= limit:
pr[i] = 1
i += j
primes = [k for k in range(2,limit+1) if pr[k] == 0]
composites = defaultdict(list)
for p in primes:
q = p
p += q
while p <= limit:
composites[p].append(q)
p += q
return primes, composites
def method2(limit):
primes, composites = primeset(limit)
prf = {}
count = 0
count += limit-1
count += (limit-2)/2
prf[1] = limit-1
prf[2] = (limit-2)/2
for i in primes:
if i != 2:
tally = limit-i-(limit/i)+1
count += tally
prf[i] = tally
for i in composites:
tally = limit-i
for item in composites[i]:
tally -= (limit/item-i/item)
count += tally
prf[i] = tally
if 88000 < i < 88055:
print i, count, tally, sum(prf.values())
return count, prf
result, index = method2(88547)
print result,sum(index.values())
2、解决方案
这个问题是由于整数溢出引起的。在Python中,整数溢出是不应该发生的,但是在这个问题中,由于计算结果超出了32位整数的最大值(2^31 - 1),导致了溢出。溢出后,Python会自动将计算结果转换为一个长整数(long),但是这个长整数仍然超出了系统限制,导致了错误的结果。
解决这个问题的方法是在代码中使用长整数,这样就可以避免溢出。具体来说,可以将sum(dict.values())替换为sum(long(value) for value in dict.values())。这样,计算结果就会自动转换为长整数,避免溢出。
以下是用长整数解决这个问题的代码:
def primeset(limit):
pr = [0]*(limit+1)
for i in range(2,limit+1):
j = i
i += j
while i <= limit:
pr[i] = 1
i += j
primes = [k for k in range(2,limit+1) if pr[k] == 0]
composites = defaultdict(list)
for p in primes:
q = p
p += q
while p <= limit:
composites[p].append(q)
p += q
return primes, composites
def method2(limit):
primes, composites = primeset(limit)
prf = {}
count = 0
count += limit-1
count += (limit-2)/2
prf[1] = limit-1
prf[2] = (limit-2)/2
for i in primes:
if i != 2:
tally = limit-i-(limit/i)+1
count += tally
prf[i] = tally
for i in composites:
tally = limit-i
for item in composites[i]:
tally -= (limit/item-i/item)
count += tally
prf[i] = tally
if 88000 < i < 88055:
print i, count, tally, sum(long(value) for value in prf.values())
return count, prf
result, index = method2(88547)
print result,sum(long(value) for value in index.values())
采用了以上改进后,问题得到了解决。