2013-11-01 85 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。:) –

相关问题