2013-01-17 68 views
-2

所以基本上一個人幫助我改進我的代碼。問題是,它仍然令人失望,並且不起作用。我想要做的是重置lenRecur.number,所以我可以再次使用該函數,使用其他字符串並獲得正確的答案(不是太大的答案)如何重置在Python 2.73中分配給函數的變量?

我想,問題是與hasattr。但我無法刪除它,因爲如果我這樣做,我的字符串長度計算器將無法工作。

無論如何,即使我在函數後添加了lenRecur.number = 0,它仍然不起作用。

這就像不可能的,因爲當函數命中「返回」,它完成了,期間。如果我在「返回」之前重置它,它將返回0,不正確的答案,所以是的,我在這裏遇到了很大的麻煩。

def lenRecur(aStr): 
    if not hasattr(lenRecur, 'number'): 
     lenRecur.number = 0 
    ''' 
    aStr: a string 

    returns: int, the length of aStr 
    ''' 
    if aStr == '': 
     return lenRecur.number 
    else: 
     lenRecur.number += 1 
     return lenRecur(aStr[:-1]) 

附:我的程序(?)/ script(?)的目標是測量輸入字符串的長度,而不使用input()方法。當試圖重新創建length()方法時,使用更原始的方法。

該腳本將不得不有很多不同的輸入,所以它應該重置。

+2

這看起來像一個[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。不要問「我如何針對某些不明確指定的問題做出解決方案」,請告訴我們問題並尋求幫助解決問題。無論你的問題是什麼,你可能已經走上了錯誤的軌道。 – abarnert

+0

另外:「即使我在函數後添加了lenRecur.number = 0,它仍然不起作用」。真?我把你的函數,然後這樣做:'print lenRecur('abc'); lenRecur.number = 0;打印lenRecur('abcd')',我得到了'3'和'4',就像我想的那樣。 – abarnert

+0

設置變量爲無效嗎? –

回答

2

您不必在函數內部使用狀態變量。如果你想遞歸長度計算器,然後就去做

def lenRecur (aStr): 
    if (aStr == ""): 
     return 0 
    else 
     return lenRecur (aStr [:-1]) + 1 

還要注意的是這種風格有沒有錯誤檢查等,但對於學習遞歸的目的,它工作正常。

3

如果你只是想要一個遞歸強度長功能,這很簡單:

def len_recur(a_str): 
    if not a_str: 
     return 0 
    else: 
     return 1 + len_recur(a_str[1:]) 

當然,這並不是尾遞歸,但後來Python不反正優化尾遞歸,所以沒關係。

如果你想讓它成爲尾巴遞歸只是爲了它的地獄 - 或者你已經讀過保羅·巴特勒的Tail Recursion in Python的技巧並且想要嘗試一下 - 你仍然不想通過存儲累加器作爲函數的一個屬性。只需使用定義的本地函數慣用的伎倆(或使用可變默認參數,如果你喜歡):

def len_tail_recur(a_str): 
    def tail(a_str, acc): 
     if not a_str: 
      return acc 
     else: 
      return tail(a_str[1:], acc+1) 
    return tail(a_str, 0) 

如果你想將其轉換爲一個真正的尾遞歸函數,因此不會對彈1001個元素列表,並且不理解上面的Paul Butler鏈接,請參閱我對Get length of list in Python using recursion的回答,它解決了這個問題。 (另一個問題的答案還說明了如何解決與日誌n次遞歸調用,而不是N,這是解決該問題得到一個不同的方式,除非你有不可能長期list問題所在。)

之所以這麼說,即使你的實現是錯誤的做法,它實際上工作得很好。 (到目前爲止,我一直在使用PEP8--如果你的代碼看起來更像是習慣用法的Python;從這裏開始,我只是按照原樣複製粘貼,但是你的真實代碼看起來應該和上面一樣。)

def lenRecur(aStr): 
    if not hasattr(lenRecur, 'number'): 
     lenRecur.number = 0 
    ''' 
    aStr: a string 

    returns: int, the length of aStr 
    ''' 
    if aStr == '': 
     return lenRecur.number 
    else: 
     lenRecur.number += 1 
     return lenRecur(aStr[:-1]) 

print lenRecur('abc') 
lenRecur.number = 0 
print lenRecur('abcd') 

這打印3,然後4。當然你必須設置lenRecur.number以外的這個函數,因爲函數裏面還是需要這個值的。但是你可以解決用同一種包裝的:

def lenRecur(aStr): 
    lenRecur.number = 0 
    ''' 
    aStr: a string 

    returns: int, the length of aStr 
    ''' 
    def recur(aStr): 
     if aStr == '': 
      return lenRecur.number 
     else: 
      lenRecur.number += 1 
      return recur(aStr[:-1]) 
    return recur(aStr) 
+0

Thx你救了我。我會挖掘你的代碼 – 5brickbomzh

+1

對於最後一個代碼示例,在定義它之後不要忘記實際調用內部'recur'函數 – lxop

+0

@lxop:謝謝!完成。 – abarnert

1

如果你想使用遞歸那麼你可以使用像這樣實現的長度功能瞭解遞歸:

#!python 
def lenRecur(something, curlen=0): 
    if something: 
     return lenRecur(something[1:], curlen+1) 
    else: 
     return curlen 

。 ..我不會說這是特別好的代碼。但它應該可以與任何類型的序列(字符串,列表,元組)一起工作......只要不超過運行Python實例中的最大遞歸限制,[1:] slice操作就可以工作的任何東西。

在你的例子中,你試圖通過使用hasattr來用你的函數的「數字」屬性「修補」你的函數的對象來實現一個類似的概念。在我的例子中,我使用默認參數作爲將變量傳遞給遞歸調用的一種方式。

因此,在最初的調用curlen爲零(調用此與「可選」額外的參數會給假結果)。從那個調用中,函數調用自己的原始序列(字符串)的一部分,使得頭部變短(使其更短),並且使可選(curlen)參數遞增。最後,字符串/序列的長度爲零,零通過前面的(遞歸)調用返回。

這是一個蹩腳的方式來實現這一點,它可能是一個討論尾部遞歸消除(谷歌爲它)的起點。但是它將在沒有猴子修補你的函數/對象的情況下工作。

相關問題