使用递归选择偶数

时间:2018-11-10 18:43:49

标签: python list recursion

这里我定义了一个函数,该函数接受一个列表并返回同一列表中偶数的计数。当我运行该程序时,我得到的结果为None。

def count_even(lst, c = 0):
    """
    parameters : a lst of type list
    returns : the even elements from that list
    """
    if lst == []:
        return c
    if lst[0] % 2 == 0:
        c += 1
    else:
        return count_even(lst[1:])


print(count_even([1,2,3,4,5,6,7,8,9]))

我的问题在哪里?

3 个答案:

答案 0 :(得分:7)

lst[0] % 2 == 0情况下,您没有返回任何内容(因此隐式返回了None)。您也永远不会在递归中包含c的更新值。将其更改为

if lst == []:
    return c

if lst[0] % 2 == 0:
    c += 1

return count_even(lst[1:], c)

你很好。由于其他答案包括一些漂亮的替代解决方案,因此我将继续提名

def count_even(lst):
    return 1 - lst[0]%2 + count_even(lst[1:]) if lst else 0

也是。

答案 1 :(得分:1)

当前的实现存在两个基本问题:

  1. cint,并且int是不可变的。如果更改c,则不是并不意味着递归调用中的c已“更新”,每个递归调用c的值为{{1 }};和
  2. 如果第一项为偶数,则不会返回任何值,因此Python在这种情况下将返回0
None

但是,更紧凑的表示形式是:

def count_even(lst, c = 0):
    if lst == []:
        return c
    if lst[0] % 2 == 0:
        c += 1
    # no else
    return count_even(lst[1:], c+1)  # pass a new value for c

但是请注意, linear 递归通常不是一个好主意,因为调用堆栈会随着元素数量的增长而增长,因此很容易导致溢出(尤其是因为Python不实现尾部呼叫优化(TCO))。

答案 2 :(得分:1)

您几乎做到了。只是一个简单的更正。您在else块中调用了递归,这是不正确的。您应该在块之外考虑它。检查以下代码:

def count_even(lst, c = 0):
    """
    parameters : a lst of type list
    returns : the even elements from that list
    """
    if lst == []:
        return c
    if lst[0] % 2 == 0:
        c = c + 1
    return c + count_even(lst[1:])


print(count_even([1,2,3,4,5,6,7,8,9]))