Python:为什么我在这两个问题上得到typeerror ?(递归)



我有两个问题,得到错误,我想了解。他们可能出于相似的原因,因此我在这篇文章中将他们分组在一起。我来这里是为了学习如何理解解决这些错误!

首先,一个函数的目标是在包含整型、浮点数和字符串的列表中查找偶数。由于某种原因,我得到一个错误,说不是所有的参数都能够在字符串格式化期间转换。下面是我的代码:

def recEvenNumbers(lst):
'return a count of all the even numbers(ints and floats) in the list'
evens = 0

if lst == []:
return
else:
if type(lst[0])== int or float:
if ((lst[0]%2*10))==0:
evens = evens+1
return recEvenNumbers(lst[1:], evens + 1)

我相信我把整个函数都写下来了,除了这个错误。为什么会发生这种情况,我如何防止将来发生这种情况?

我得到的另一个错误是不同的函数。下面是它的代码:

def recMerge(a,b):
'Merge two strings together recursivly'
if len(a)==0:
return
elif len(b)==0:
return
else:
if type(a) == str:
if type(b) == str:
return a[0] + b[0] + recMerge(a[1:], b[1:])

此函数的目的是合并两个字符串以创建一个字符串,该字符串的字符在两个字符串之间交替。对我的问题来说不是很重要,我只是想知道为什么我可能会在这里得到TypeError。这是它告诉我的:

File "C:/Users/1734/py.py", line 59, in recMerge
return a[0] + b[0] + recMerge(a[1:], b[1:])
TypeError: can only concatenate str (not "NoneType") to str
>>> 

为什么会发生这种情况?我假设if类型(a)和if类型(b)应该处理这个。为什么我不能在这种情况下使用它们?还是我只是滥用了它们?

还有,这两个错误是否相关?我知道这个问题可能看起来很奇怪,但如果这些问题中有某些因素是我难以理解的,我想指出它是什么,以及为什么我误解了它。

谢谢你的时间!

你犯了一个典型的错误。这个语句并不是你想象的那样:

if type(lst[0])== int or float:

Python将其解析为:

if (type(lst[0])== int) or (float):

And since "float"总是成立的,你总是取这里的if。当lst[0]是字符串时,'%'操作符是字符串格式化操作符。你想要的:

if type(lst[0]) in (int, float):

或者

if isinstance(lst[0],int) or isinstance(lst[0],float):

第二个函数的问题是,它返回None,而不是输入为空的基准情况下的空字符串。因为递归的工作方式是在递归调用的结果上添加,所以最后一个递归调用必须是可以添加的。

def recMerge(a: str, b: str) -> str:
"""Merge two strings together recursively.  If the strings are of
unequal length, the remainder of the longer string is dropped."""
# Type check (not necessary if you type-annotate and mypy your code!)
if not isinstance(a, str) or not isinstance(b, str):
raise TypeError("both parameters must be strings!")
# Base case: if one param is empty, there's nothing to merge, so return ""
if not a or not b:
return ""
# Recurse with a smaller slice of both parameters.
return a[0] + b[0] + recMerge(a[1:], b[1:])

我知道其他人都在评论你的第一个问题,但如果你处理得当,它就会起作用。也就是说,您应该首先处理字符串,并将evens添加为None参数,以检查第一次传递的实例。

下面是一个工作函数:

def recEvenNumbers(lst, evens = None):
'return a count of all the even numbers(ints and floats) in the list'
if evens is None:
evens = [0]
if lst:
# To keep things organized, extract first item
# into variable and the rest into a smaller list with
# star selection
item, *lst = lst
# Check for string first
# Pass rest of process if detected.
if type(item) == str:
pass
# Continue as you were before
elif type(item) == int or float:
if item % 2 * 10 == 0:
evens[0] += 1
# Recurse with appropriate params.
return recEvenNumbers(lst, evens)
# Return result.
return evens[0]

运行函数:

test_list = [1, 2.2, 4, "string"]
recEvenNumbers(test_list)

输出:

1

第2部分:

# Function with commentary.
def recMerge(a, b):
'Merge two strings together recursivly'
# Check types
if type(a) == type(b) == str:
# Run until b is empty.
if len(b) > 0:
# Deconstructing into single and rest of items with asterisk.
aa, *a_rest = a
bb, *b_rest = b
# New `a` value that prepends the rest of a in
# front of the concatenation of the current a and b characters.
# Since a_rest is a list, we should "collect" the items back into
# a proper string format.
a = "".join(a_rest) + aa + bb
# Return the new a with another concatenated list for the
# remaining b items.
return recMerge(a, "".join(b_rest))
# Return a.  Ensure that it is a string.
return "".join(a)

运行测试案例:

A = "abc"
B = "def"
recMerge(A, B)

输出:

'adbecf'

这是我的工作代码。


def recEvenNumbers(lst):
'return a count of all the even numbers(ints and floats) in the list'
evens = 0
if lst == []:
return 0

elif type(lst[0]) == int or type(lst[0]) == float:
if ((lst[0]%2))==0:
evens = evens+1
return recEvenNumbers(lst[1:]) + evens


def recMerge(a,b):
'Merge two strings together recursivly'
if type(a) != str or type(b) != str:
return None
#recMerge ((a[1:]), (b[1:]))

if a == "":
return b
elif b == "":
return a
else:
return  a[0] + b[0] + recMerge(a[1:], b[1:])

最新更新