2013-11-01 82 views
2

在這個遞歸代碼中,我得到了正確返回True的函數,但隨後它進行了1個額外的步驟並將返回值更改爲「None」。我相信我不能正確理解返回值。有人能告訴我爲什麼會發生這種情況嗎?先謝謝你。返回後,返回值會發生什麼變化?

-

def nestedListContains(NL, target): 
    for i in range(0, len(NL)): 
     if type(NL[i]) == int: 
     if NL[i] == target: 
      return True 
     elif i == (len(NL) - 1): 
      return False 
     elif type(NL[i]) != int: 
     nestedListContains(NL[i], target) 

nestedListContains([[9, 4, 5], [3, 8]], 3) #Test Case# 
+0

在你需要有底部elif的情況下,「迴歸nestedListContains ......」這樣的遞歸調用知道返回的功能底部的返回值。 –

+0

[Weird函數返回值?]可能的重複(http://stackoverflow.com/questions/11097822/weird-function-return-value) –

回答

1

有三個問題與您的代碼;首先,你對遞歸調用的結果不做任何事情。其次,您應該使用isinstance()來檢查某個值是否屬於某種類型,而不是type(ob) ==。第三,不是使用range()並檢查我是否到達最後一個值,只要在循環後返回False,如果沒有找到。

總數:

def nestedListContains(NL, target): 
    for value in NL: 
     if isinstance(value, int): 
      test = value == target 
     else: 
      # value is not an int, so it's a list 
      test = nestedListContains(value, target) 
     if test: 
      return True # found target 

    return False # We finished the loop without finding target 

這將拋出一個TypeError如果NL不是列表中的所有。這可能比isinstance()更好的檢查 - 如果它可以迭代,那麼它是一個列表,如果迭代拋出TypeError,那麼我們應該將它與目標進行比較。我也會使命名更加標準:

def nested_list_contains(nested_list, target): 
    try: 
     for value in nested_list: 
      if nested_list_contains(value, target): 
       return True 
     return False 
    except TypeError: 
     # It's a single value 
     return nested_list == target 

但還有一種更好的方法。我們真正想要做的就是拼合嵌套列表,並檢查目標是否在其中。我們可以把上面的成平展iterables遞歸發電機:

def flatten_nested_list(nested_list): 
    try: 
     for v in nested_list: 
      for flattened in flatten_nested_list(v): 
       yield flatten 
    except TypeError: 
     yield nested_list 

def nested_list_contains(nested_list, target): 
    return target in flatten_nested_list(nested_list) 
+0

非常感謝,這是一個很好的解釋。現在我已經摔了兩天了。我知道我的算法是正確的,但是你在幫助我實現正確的代碼方面做得非常好,以及它是正確的。 – Icarus

0

使用已遞歸來回報您的遞歸結果:

def nestedListContains(NL, target): 
    for i in range(0, len(NL)): 
     if type(NL[i]) == int: 
     if NL[i] == target: 
      return True 
     elif i == (len(NL) - 1): 
      return False 
     elif type(NL[i]) != int: 
     #you missed the return for the recursive case 
     ret = nestedListContains(NL[i], target) 
     if(type(ret) == bool): #ensure we have an actual result and not a fall through 
      return ret 
+0

@Icarus來解決你的建議更新,你濫用'isinstance'這是爲了繼承請參閱http://stackoverflow.com/questions/1549801/differences-between-isinstance-and-type-in​​-python – megawac

+0

如果遞歸nestedListContains返回False,則會失敗,因爲那麼該循環必須繼續。 – RemcoGerlich

+0

是的,謝謝megawac,我還是比較新的Python,但這樣更方便! – Icarus

-1

闡述一下剛纔的答覆一點點,你會得到None當你到達的結束函數而不返回特定值:

def func(): 
    ... do something ... 

相當於:

def func(): 
    ... do something ... 
    return None 

如果您傳遞一個空的NL,這仍然會發生,因爲循環後沒有return語句。

(也isinstance(value, int)是檢查什麼類型的首選方式)

+0

這是真的,但沒有解決'elif'中沒有'return'的主要問題。 –

+0

是的,這就是爲什麼我寫了「詳細說明早先的答案」。 – Fredrik

+0

我鼓勵你讓這個獨立的答案。答案不應該依賴於其他答案。我會把我的贊成票改成upvote。:) –

相關問題