繁体   English   中英

递归计算列表中非v的元素数

[英]recursively counting the number of elements in a list that are not v

对于列表,我想递归计算非v的元素数量。

到目前为止,我的代码如下:

def number_not(thelist, v):
"""Returns: number of elements in thelist that are NOT v.

Precondition: thelist is a list of ints
              v is an int"""
total = 0
if thelist is []:
    return total
elif thelist[0] is v:
    print "is v"
    total += 0
    print total
    return number_not(thelist[1:],v)
elif thelist[0] is not v:
    print "is not v"
    total += 1
    print total
    return number_not(thelist[1:],v)

return total

它将打印每个数字的总数,而不是最终总数。 例如,对于list = [1,2,2,2,1],它将打印:

is not v
1
is v
0
is v
0
is v
0
is not v
1

但是然后我的代码因为继续运行而出现traceback(列表索引超出范围)错误。 我如何做到这一点,使其仅在列表的长度上递归,并返回正确的总数,例如该示例为2

所有代码都很好,只是您添加的终止条件不正确,

if not thelist:

if thelist is []: ,请更改代码以检查空白列表。

虽然这里的其他答案可以解决问题,但我认为他们没有解决核心问题。 问题是:

if thelist is []:

因为该条件语句不是您认为的那样。 例如:

In [2]: [] is []
Out[2]: False

is对身份的测试,而不是您似乎在代码中假设的平等。 它检查对象的id ,它是一个唯一的整数,类似于C中的内存地址。

In [3]: id([])
Out[3]: 140402932955720

In [4]: id([])
Out[4]: 140402923983176

每个[]是一个具有唯一id的新对象,因此您的基本条件将永远不会被触发。 为了比较列表实例,您应该使用==len (如果需要确保列表是列表,则可以使用isinstance)。

顺便说一句... is比较常数/建宏一样是合适的:

1 is 1
type([]) is list
False is False

当检查可能为Falseint东西时,这很有用。 如果变量为0并且您检查if not var ,则False0均为Falsey且都为True因此,假设它们在代码中的含义不同,您将需要检查if var is False以及if var is 0

您的基本情况是列表为空。 那你想返回0,对吧?

您的递归案例要求您将列表分成第一个元素和其余元素。 检查列表的开头-它不等于您要搜索的内容吗?

def counter(needle, haystack):
    if not haystack: 
        return 0

    # Splits the list into the first element and the remaining elements as a list.
    head, *rest = haystack

    if head != needle:
        return counter(needle, rest) + 1
    else:
        return counter(needle, rest)

重复

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM