具有嵌套列表的Python递归
我试图创建一个递归函数,该函数使用单个字符串遍历任何级别的嵌套列表,并返回True或False,无论给定的字符是否在该列表中 这是我的代码:具有嵌套列表的Python递归,python,list,recursion,nested,Python,List,Recursion,Nested,我试图创建一个递归函数,该函数使用单个字符串遍历任何级别的嵌套列表,并返回True或False,无论给定的字符是否在该列表中 这是我的代码: def inlist(character, lists): """Checks if a given character is in a list of any level""" if lists[0] == character: return True
def inlist(character, lists):
"""Checks if a given character is in a list of any level"""
if lists[0] == character:
return True
elif isinstance(lists[0], list):
return inlist(character,lists[0])
elif not lists[0] == character:
return inlist(character,lists[1:])
else:
return False
当我使用以下命令运行代码时:(“c”、[[“a”、“b”、“c”、“d”]、“e”])
它似乎工作得很好。但是,当我以这种方式键入列表时:((“c”、[[“a”、“b”、]、[“c”、“d”]、“e”]))
它给了我一个错误,它说:索引器:列表索引超出范围
我可以不这样写嵌套列表吗?若然,原因为何?
或者我的代码有什么问题,使它不能贯穿整个列表吗?您使它变得有点复杂,而递归的思维方式应该简单得多 DFS ish版本: (您可以在网上阅读有关DFS遍历的更多信息) 输出:
True
对于此输入:
print(inlist("z", a))
输出为:
False
简要说明:
- 循环列表中的所有项目
- 如果项目是字符-finish
- 如果该项为列表,则立即调用递归(此处最吸引人的部分是仅当为True时返回,因为如果不是,则并不意味着在其他项中找不到该字符)
- 如果完成所有项目,但未找到-完成
- 当项目在内部列表中的可能性越大越好
- 循环列表中的所有项目
- 如果项目是字符-finish
- 如果项目为列表-附加到
,在验证当前级别中的所有项目后执行extra\u arr
- 如果完成所有项目,但未找到-完成
- 如果该项目在外部列表中的可能性更大,则效果更佳
def inlist(char, lists):
if not lists: # check for empty list
return False
if lists[0] == char:
return True
elif isinstance(lists[0], list) and inlist(char, lists[0]):
return True # return only if found in sublist, otherwise continue
elif len(lists) > 1: # check rest of the list, if there is a rest
return inlist(char, lists[1:])
return False # all possibilities exhausted. Char not in this (sub-)list
这对于某些问题很有用,但要在列表中查找元素,循环会更快。此外,对于较长的列表,最大递归深度将是一个问题。@Wups已经介绍了纯递归解决方案。在
isinstance(lists[0],list)
情况下,如果递归调用返回false,您仍然必须小心地检查lists[1]
在输入值之前,始终检查列表是否为空。下面是另一种使用高阶函数思考问题的方法,例如,some
def部分(f,t):
如果不是t:
返回错误
其他:
返回f(t[0])或某些(f,t[1:])
def inlist(字符,ls):
还一些\
(lambda v:inlist(char,v)如果isinstance(v,list)else char==v
,ls
)
输入=[“c”、[[“a”、“b”、]、[“c”、“d”]、“e”]
打印(输入列表(“a”,输入))
打印(输入(“z”,输入))
上面我们写了一些,作为练习。您应该知道Python有一个内置的
any
函数-
def输入列表(字符,ls):
返回any(isinstance(v,list)和inlist(char,v)或char==v表示ls中的v)
输入=[“c”、[[“a”、“b”、]、[“c”、“d”]、“e”]
打印(输入列表(“a”,输入))
打印(输入(“z”,输入))
在检查
列表
是否包含任何元素之前,请注意您是如何执行列表[0]
的。嗯,如果在上面有另一个if语句并缩进其他所有内容,会更好吗?我只需将当前的if
转换为elif
,然后使用if
类似于if not list:
。不需要嵌套。您的逻辑也有一点缺陷,如果第一个元素是一个没有字符的列表,elif
将触发并返回False,即使后面的一个列表可能返回True。@Wups切片实际上在空列表上是安全的。这是一个很好的功能。这似乎是一个更聪明和更简单的解决方案,我会记住它!我知道这是迭代和递归的混合。这是解决这些问题的通常方法吗?或者有只使用递归的例子吗?我添加了一些DFS和BFS方法的“教育性内容”,它主要来自图遍历,但在我看来,这里的情况类似。我不知道对于什么是“惯常方式”是否有明确的定义,我想每个人都有自己的偏好,更重要的是,我认为递归和迭代之间没有关系。
def inlist(character, lists):
"""Checks if a given character is in a list of any level"""
extra_arr = []
for item in lists:
if item==character:
return True
if isinstance(item, list):
extra_arr.append(item)
for extra_item in extra_arr:
if inlist(character, extra_item):
return True
return False
def inlist(char, lists):
if not lists: # check for empty list
return False
if lists[0] == char:
return True
elif isinstance(lists[0], list) and inlist(char, lists[0]):
return True # return only if found in sublist, otherwise continue
elif len(lists) > 1: # check rest of the list, if there is a rest
return inlist(char, lists[1:])
return False # all possibilities exhausted. Char not in this (sub-)list
True
False
True
False