所以我试图用一首诗打开一个文本文件,看看我能用每行文本文件中的字母拼写单词“GOOD”多少次,但是我收到以下错误:
Traceback (most recent call last):
File "./soup.py", line 11, in <module>
print( "\n".join( [("Case #%d: %d" % (i, parse(file[i]))) for i in range(1, len(file))]))
File "./soup.py", line 7, in parse
d['O'] /= 2
KeyError: 'O'
源:
#!/usr/bin/python
def parse(string):
d = {'G' : 0, 'O' : 0, 'D' : 0}
d = {s: string.count(s) for s in string if s in d }
d['O'] /= 2
return min(d.values())
file = open("poem.txt").read().split('\n')
print( "\n".join( [("Case #%d: %d" % (i, parse(file[i]))) for i in range(1, len(file))]))
答案 0 :(得分:4)
FWIW,我会用Counter对象写这个:
from collections import Counter
def spellcount(string, wanted):
wanted_counts = Counter(wanted)
have_counts = Counter(string)
return min(have_counts[c]//wanted_counts[c] for c in wanted_counts)
wanted = "GOOD"
with open("poem.txt") as fp:
for i, line in enumerate(fp):
print("Case", i, ":", spellcount(line, wanted))
计数器表现为默认值,例如
>>> from collections import Counter
>>> Counter('GOOD')
Counter({'O': 2, 'G': 1, 'D': 1})
>>> Counter('GOOD')['i']
0
答案 1 :(得分:3)
你确定你的第7行读d ['O']吗?
错误消息表明它读取了d ['C']
问题是如果该行不包含'O'字符,则'O'将不在d中,这会产生错误。
第二次定义d将创建一个不包含“O”键的新词典。
def parse(string):
d = {'G' : 0, 'O' : 0, 'D' : 0}
d = {s: string.count(s) for s in string if s in d }
try:
d['O'] /= 2
except KeyError:
return 0
return min(d.values())
file = open("test1.py").read().split('\n')
print( "\n".join( [("Case #%d: %d" % (i, parse(file[i]))) for i in range(1, len(file))]))
(您可能会发现在d中执行d = {s:string.count(s)for s}更有效率)
(我也喜欢使用collections.Counter的替代建议。但是,如果你对速度感兴趣,那么我的定时测量表明,对于一个1000万字符的字符串,制作Counter对象需要3秒,但只有0.012秒每次调用string.count)
答案 2 :(得分:1)
在字典理解中使用'GOD'
代替string
,因为并非每行都包含“O”。
def parse(string):
d = {s: string.count(s) for s in 'GOD'}
d['O'] /= 2
return min(d.values())
答案 3 :(得分:0)
问题是,如果您遇到一条不计算“O”的行,则该密钥不会存在。您可以使用dict.get
解决此问题。如果某个密钥不存在但返回其第二个参数,则dict.get
不会引发异常,在这种情况下0
:
def parse(string):
d = {s: string.count(s) for s in string if s in 'GOD'}
d['O'] = d.get('O', 0) / 2
return min(d.values())
请注意,上面只匹配大写字母,如果你想要大写和小写,你可以这样做:
def parse(string):
string = string.upper()
d = {s: string.count(s) for s in string if s in 'GOD'}
d['O'] = d.get('O', 0) / 2
return min(d.values())
修改强>
当然,使用d = {s: string.count(s) for s in 'GOD'}
可以完全避免这个问题,也更简洁。我建议使用@ Gandaro的答案。