Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 递归线性搜索-返回列表索引_Python_Recursion - Fatal编程技术网

Python 递归线性搜索-返回列表索引

Python 递归线性搜索-返回列表索引,python,recursion,Python,Recursion,我有一个函数search,它在一个列表('l')中搜索键,如果找到,则返回True,否则返回False。如果找到,我希望它返回key的索引,如果没有找到,则返回False,但我不知道返回语句应该是什么。这是我的密码: def search(l,key): """ locates key in list l. if present, returns location as an index; else returns False. PRE: l is a lis

我有一个函数search,它在一个列表('l')中搜索键,如果找到,则返回True,否则返回False。如果找到,我希望它返回key的索引,如果没有找到,则返回False,但我不知道返回语句应该是什么。这是我的密码:

def search(l,key):
    """
    locates key in list l.  if present, returns location as an index; 
    else returns False.
    PRE: l is a list.
    POST: l is unchanged; returns i such that l[i] == key; False otherwise.
    """

    if l:   # checks if list exists
        if l[0] == key:     # base case - first index is key
            return True

        s = search(l[1:], key)      # recursion
        if s is not False:          
            return s

    return False            # returns false if key not found

非常感谢您的帮助。

对于您的基本案例,您刚刚在索引0处找到了该项目,对吗?返回0

if l[0] == key:     # base case - first index is key
    return 0
对于递归部分,让我们考虑返回什么。假设该项位于索引5处。因为我们已经给递归调用传递了一个移位一个元素的列表,它将找到它并返回4。(4,不是5。你明白为什么吗?)

在返回索引之前,我们需要添加一个以取消移动索引

s = search(l[1:], key)      # recursion
if s is not False:          
    return s + 1

问题是,您正在对列表的尾部进行切片,而没有保留有关切片发生位置的任何信息

事实上,您根本不需要对列表进行切片,因为您可以在列表中执行索引查找

线性搜索的算法是原始递归的,因此如果你能找到一个迭代的解决方案,递归的解决方案是很容易达到的(反之亦然)

因此,迭代解决方案可能如下所示:

for every integer i between zero and length of list
    if the element at position i in the list is equal to the key
        return i
else
   return "I couldn't find it"

我们将迭代解转换为递归解基本上意味着将循环转换为函数调用,其参数是下一个循环迭代的值。循环变量是
i
和正在搜索的列表。为了让你能从练习中学习,我就到此为止。

你需要跟踪索引。因为您的最终返回值[如果发生真正的搜索]是布尔值,所以您必须更改它。
我想下面的代码应该会对您有所帮助,但一定要彻底测试它,因为我只是试图理解意图,并没有彻底测试逻辑-

def search(l,key,idx=0):
"""
locates key in list l.  if present, returns location as an index; 
else returns False.
PRE: l is a list.
POST: l is unchanged; returns i such that l[i] == key; False otherwise.
"""

if l:   # checks if list exists
    if l[0] == key:     # base case - first index is key
    return idx

    s = search(l[1:], key, (idx + 1))      # recursion
    if s is not False:          
        return s

return False            # returns false if key not found

您的API设计存在严重缺陷

>>> False == 0
True
你的导师正在给你设置惊喜。例如:

where = search(["non-foo", "not-foo"], "foo") # returns False
if where == 0:
    print "foo is in pole position"
    # but "foo" isn't even a candidate
使其在出现故障时返回
None
。试试这个:

>>> def search(alist, key, pos=None):
...     if pos is None: pos = len(alist) - 1
...     if pos < 0: return None
...     if key == alist[pos]: return pos
...     return search(alist, key, pos - 1)
...
>>> search([1,2,3], 4) # -> None
>>> search([1,2,3], 3)
2
>>> search([1,2,3], 2)
1
>>> search([1,2,3], 1)
0
>>> search([], 1) # -> None
>>>

应该注意,我不能使用内置的.index函数或in运算符。我想如果没有这些,我已经很接近了。没有看到这个评论,你不能使用索引。但方法也可以类似。请尝试并在此处发布您的答案。请确保您的讲师知道(a)当这一问题出现在足够长的列表中时,您仍然可以通过(b)以递归为主的课程最好用支持递归的语言教授。如果所说的教练试图让你使用二传手或接球手,给他/她一个坚定但不具毁灭性的耳光,并告诉他们这是来自aaronasterling的。@aaronasterling:+1我猜,这更像是一个介绍性练习,限制他们使用python中提供的工具,并提出尊重这些约束的解决方案。当然,他们还应该告诉他们,为什么这个解决方案不适合/不如Python中的其他解决方案。在我发布我的答案之后,我看到了他的评论,并且得到了反对票。这不是Python!使用
for
循环迭代列表,不使用递归。+1是一个很好的解释,无需做家庭作业。我认为在失败的情况下返回
None
比返回
False
更好(函数从不返回
True
),但这可能是一个品味问题。-1感谢您在没有解释它是由极其丑陋的API设计所必需的情况下,获得了极其丑陋的
if is not False
。谢谢John,我理解你为什么要添加一个。这个解决方案(没有参数“idx”)更合适吗?或者反之亦然?@JMJY:inspectorG4dget在胡说八道:-(@JohnMachin:我现在已经看到了你的解决方案,并且对它们+1。我不相信我在发布此评论时看到了你的答案。回头看看时间戳。似乎你可能在我发布我的评论后不久就发布了你的答案。@inspectorG4dget:No“似乎”。我的评论确实是在我发布我的答案之前发表的,在那些情况下是非常有效的……您没有对您正在推动的代码进行严格检查,认为它是“正确的解决方案”@JohnMachin:我似乎有一个错误的印象。我的道歉谢约翰,谢谢你的帮助。我只是想知道你的xsearch、ysearch和zsearch之间的区别是什么?你只是在压缩代码吗?@JMJY:我在重构anirvan的代码(xsearch)以删除不必要的代码,这会造成不好的结果“if s not False”消失。请注意我在过程中添加到代码中的注释;我将返回并用“######”突出显示它们。如果“just”是指“仅仅”,请重新思考——臃肿的代码是糟糕的代码。感谢您的帮助和澄清。
def xsearch(l,key,idx=0):
    if l:   # checks if list exists
        if l[0] == key:     # base case - first index is key
            return idx
        s = xsearch(l[1:], key, (idx + 1))      # recursion
        if s is not False:          
            return s
        #### and if s is False, it falls through and returns False ####
        #### so it can return s unconditionally!                   ####
    return False            # returns false if key not found

def ysearch(l,key,idx=0):
    if l:   # checks if list exists
        if l[0] == key:     # base case - first index is key
            return idx
        return ysearch(l[1:], key, (idx + 1))      # recursion
    return False            # returns false if key not found
    #### above statement is better put closer to the `if` ####

def zsearch(l,key,idx=0):
    if not l:   # checks if list exists
        return False
    if l[0] == key:     # base case - first index is key
        return idx
    return zsearch(l[1:], key, (idx + 1))      # recursion