2012-01-22 104 views
2

,所以我試圖打開一個文本文件,一首詩,看多少次我可以拼出單詞「GOOD」,在文本文件中的信每一行,但我得到了以下錯誤:邏輯錯誤與Python的解析文件:KeyError異常:「O」

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

你應該用:'{c:string.count(c)for c in d}'。 –

回答

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 = {S:對於s string.count(收費)d})

(我也愛用collections.Counter的替代建議。但是,如果你有興趣的速度,然後我定時測量表明,1000萬字符串需要3秒,使計數器對象,但每次通話只有0.012秒到string.count)

+1

是的,我改變了一些代碼,使其更簡單 – Neo

+1

有更多的字母,良好的詞實際上是一個句子。對於那個很抱歉。 – Neo

+0

嗯,'d [「O」]/= 2'將*不*引發KeyError,因爲「C」不存在... – Gandaro

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'}避免了問題,是更簡潔了。我建議使用@甘達羅的答案。

1

在您的字典理解中使用'GOD'而不是string,因爲不是每一行都會包含'O'。

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)) 

計數器表現爲defaultdict,例如:

def parse(string): 
    d = {s: string.count(s) for s in 'GOD'} 
    d['O'] /= 2 
    return min(d.values()) 
+0

其實你應該把它改爲'GOD';),你現在計算並設置'O'兩次。除此之外,它是完美的。 –

+0

謝謝你,你是對的,這是沒有必要的。我改變了它。 – Gandaro

4

FWIW,我會使用計數器對象寫這

>>> from collections import Counter 
>>> Counter('GOOD') 
Counter({'O': 2, 'G': 1, 'D': 1}) 
>>> Counter('GOOD')['i'] 
0 
+1

+1我認爲你的解決方案是最好的DSM,但我的問題在於學習如何處理Key Error異常。感謝您的有用郵件 – Neo

+1

@Neo:不用擔心!無論你如何在Python中執行此操作,以及如何在給定代碼的情況下解決問題都是有用的事情。 – DSM