对于列表,我想递归计算非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
然后我的代码得到一个追溯(列表索引超出范围)错误,因为它继续。我该怎么做才能使它只递归列表的长度并返回正确的总数,例如2
答案 0 :(得分:4)
所有代码都没问题,只是你添加的终止条件不正确,
应为if not thelist:
更改您的代码以检查空列表,if thelist is []:
到上面。
答案 1 :(得分:3)
虽然这里的其他答案解决了这个问题,但我认为他们没有解决核心问题。问题是:
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
这在检查可能是False
或int
的内容时非常有用。如果变量为0
且您检查if not var
,则False
和0
都是Falsey,并且都会评估为True
,因此您需要检查if var is False
1}}和if var is 0
假设它们在您的代码中有不同的含义。
答案 2 :(得分:1)
您的基本情况是列表为空。然后你要返回0,对吧?
您的递归案例要求您将列表拆分为第一个元素,其余元素。检查列表的头部 - 它不等于您要搜索的内容吗?
You can also use the except statement with no exceptions defined as follows −
try:
You do your operations here;
......................
except:
If there is any exception, then execute this block.
......................
else:
If there is no exception then execute this block.