我有一个文件
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'
有人可以帮忙吗?
答案 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)