如何对同一个键的值求和

How to sum values for the same key

我有一个文件

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'

有人可以帮忙吗?

查看完整的回溯:

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() 的文档,我们发现它所做的是

Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError.

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

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('|') returns 一个字符串列表——所以我们需要明确地将 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}

将该词典转换回您想要的文件输出是一个单独的问题(您的代码未尝试),因此我将让您继续努力。

回答您的问题:"how to sum values for the same key" - 好吧,有一个名为 collections.Counter 的内置 class 非常适合您:

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)