2015-02-08 58 views
-3

我正在尋找代碼最後一行中的錯誤,但我無法弄清楚它是什麼。有任何想法嗎?遞歸基礎案例失敗

def letterScore(let): 
    let.lower() 
    if let in 'aAnNoOeErRsStTuUiIlL': 
     return 1 
    elif let in 'dDgG': 
     return 2 
    elif let in 'bBcCpPmM': 
     return 3 
    elif let in 'fFhHvVwWyY': 
     return 4 
    elif let in 'kK': 
     return 5 
    elif let in 'jJxX': 
     return 8 
    elif let in 'qQzZ': 
     return 10 
    else: 
     return 0 

def scrabbleScore(s): 
    return letterScore(s[0]) + scrabbleScore(s[1:len(s)]) 
+0

正如alfasin提到的,'let.lower()'不會改變'let':它不會因爲Python字符串是不可變的。但是如果你做了'let = let.lower()',那麼就會創建一個新的字符串,並且這個新的字符串被綁定到名字let。 – 2015-02-08 04:18:15

回答

0

的問題是在遞歸調用:

scrabbleScore(s[0]) 

s收益爲空字符串(遞歸的基本情況),此調用將失敗,並拋出一個異常。

附註:行中沒有意思:let.lower() - 它什麼也沒有做。

+0

當's'爲空時,'scrabbleScore(s [1:len(s)]'將會失敗,但是[1:len(s)]'實際上是ok的:引發IndexError的事情是'letterScore(s [0])'中的's [0]'。你可以切分一個空字符串,但是你不能索引它。例如'''[0:1]','''[1:1]'和甚至'''[1:0]'都會產生一個空字符串。 – 2015-02-08 04:15:17

+0

@ PM2Ring你說得對 - 我更正了答案,謝謝! – alfasin 2015-02-08 04:17:38

1

問:什麼時候你的遞歸函數「谷底」並停止遞歸?

答:沒有。

問:當應該它停止遞歸?

- 答:當len(s) == 0

Q.什麼實際上發生在len(s) == 0

A.你打電話s[0],它死了IndexError

如果你希望它是遞歸的,它應該看起來像

def scrabble_score(s): 
    if s: # Pythonic idiom for `len(s) > 0` 
     return letter_score(s[0]) + scrabble_score(s[1:]) 
    else: 
     return 0 

然而沒有好的理由讓這個遞歸;迭代的方法更簡單,更快速,

SCORES = dict(zip(
    "abcdefghijklmnopqrstuvwxyz", 
    [1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10] 
)) 

def letter_score(ch, scores=SCORES): 
    return scores.get(ch.lower(), 0) 

def scrabble_score(word): 
    return sum(letter_score(ch) for ch in word)