如何对同一个键的值求和

时间:2015-02-19 18:51:59

标签: python dictionary typeerror

我有一个文件

gu|8
gt|5
gr|5
gp|1
uk|2
gr|20
gp|98
uk|1
me|2
support|6

我希望每个TLD都有一个号码,如:

 gr|25
 gp|99
 uk|3
 me|2
 support|6
 gu|8
 gt|5

这是我的代码:

f = open(file,'r')
d={}
for line in f:
    line = line.strip('\n')
    TLD,count = line.split('|')
    d[TLD] = d.get(TLD)+count

print d

但是我收到了这个错误:

    d[TLD] = d.get(TLD)+count
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:4)

看一下完整的追溯:

Traceback (most recent call last):
  File "mee.py", line 6, in <module>
    d[TLD] = d.get(TLD) + count
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'

错误告诉我们,我们尝试将NoneType类型的内容添加到str类型的内容中,而Python中不允许这样做。

只有NoneType类型的一个对象,毫不奇怪,None - 所以我们知道我们尝试将字符串添加到None

我们尝试在该行中添加的两件事是d.get(TLD)count,并查看dict.get()的文档,我们看到它的作用是

  

如果 key 在字典中,则返回的值,否则默认。如果未给出默认,则默认为None,因此此方法永远不会引发KeyError

由于我们没有提供默认d.get(TLD)在字典中找不到None时返回TLD,并且我们在尝试向其添加count时收到错误。因此,让我们提供0默认,看看会发生什么:

f = open('data','r')
d={}
for line in f:
    line = line.strip('\n')
    TLD, count = line.split('|')
    d[TLD] = d.get(TLD, 0) + count

print d
$ python mee.py
Traceback (most recent call last):
  File "mee.py", line 6, in <module>
    d[TLD] = d.get(TLD, 0) + count
TypeError: unsupported operand type(s) for +: 'int' and 'str'

好吧,我们仍然遇到错误,但现在问题是我们正在尝试将字符串添加到整数,这也是不允许的,因为它会是ambiguous

因为line.split('|')返回字符串列表而发生这种情况 - 因此我们需要将count显式转换为整数:

f = open('data','r')
d={}
for line in f:
    line = line.strip('\n')
    TLD, count = line.split('|')
    d[TLD] = d.get(TLD, 0) + int(count)

print d

......现在它起作用了:

$ python mee.py 
{'me': 2, 'gu': 8, 'gt': 5, 'gr': 25, 'gp': 99, 'support': 6, 'uk': 3}

将该词典重新转换为您想要的文件输出是一个单独的问题(而不是您的代码尝试过),所以我将让您继续处理。

答案 1 :(得分:3)

回答你问题的标题:“如何对同一个键的值进行求和” - 好吧,有一个名为collections.Counter的内置类与你完美匹配:

import collections
d = collections.Counter()
with open(file) as f:
    tld, cnt = line.strip().split('|')
    d[tld] += int(cnt)

然后回信:

with open(file, 'w') as f:
    for tld, cnt in sorted(d.items()):
        print >> f, "%s|%d" % (tld, cnt)