类列表数组python的递归线性搜索

类列表数组python的递归线性搜索,python,list,class,recursion,Python,List,Class,Recursion,嗨,我如何使用递归而不是迭代地进行线性搜索?这就是我目前尝试的方式。我得到这个错误 如果l[0]==键: TypeError:“type”对象不是可下标的TypeError:“type”对象 不是l的下标 这是一个类方法,因此它收到的第一个参数(您将其命名为l)是对类本身的引用 如果l应该是所述类的实例,请删除@classmethod装饰器。如果假定l与类无关,请将@classmethod更改为@staticmethod(后者不会隐式接收类型作为第一个参数),或者在l前面添加cls参数 如果目标

嗨,我如何使用递归而不是迭代地进行线性搜索?这就是我目前尝试的方式。我得到这个错误

如果l[0]==键:

TypeError:“type”对象不是可下标的TypeError:“type”对象 不是l的下标


这是一个类方法,因此它收到的第一个参数(您将其命名为
l
)是对类本身的引用

如果
l
应该是所述类的实例,请删除
@classmethod
装饰器。如果假定
l
与类无关,请将
@classmethod
更改为
@staticmethod
(后者不会隐式接收类型作为第一个参数),或者在
l
前面添加
cls
参数

如果目标是处理实例属性,那么我建议将顶级函数设置为实例方法,并使用递归帮助器方法(类或静态)。例如:

# Public instance method that delegates to recursive class method
def linear_search(self, key):
    return self._linear_search_r(self._values, key)

@classmethod
def _linear_search_r(cls, l, key, i=0):

    if l:  #Check if list is not empty
        if l[0] == key:
            return i 

        s = cls._linear_search_r(l[1:],key, (i + 1))
        if s is not False:
            i = s
            return i

    return False

这是一个类方法,因此它收到的第一个参数(您将其命名为
l
)是对类本身的引用

如果
l
应该是所述类的实例,请删除
@classmethod
装饰器。如果假定
l
与类无关,请将
@classmethod
更改为
@staticmethod
(后者不会隐式接收类型作为第一个参数),或者在
l
前面添加
cls
参数

如果目标是处理实例属性,那么我建议将顶级函数设置为实例方法,并使用递归帮助器方法(类或静态)。例如:

# Public instance method that delegates to recursive class method
def linear_search(self, key):
    return self._linear_search_r(self._values, key)

@classmethod
def _linear_search_r(cls, l, key, i=0):

    if l:  #Check if list is not empty
        if l[0] == key:
            return i 

        s = cls._linear_search_r(l[1:],key, (i + 1))
        if s is not False:
            i = s
            return i

    return False

只有三种情况需要担心:

  • 如果输入列表为空,则引发异常
  • 如果列表的“第一个”元素是匹配的,则返回索引
  • 如果列表的“第一个”元素不匹配,则进行递归调用并返回其值
我将“first”放在引号中,因为虽然将输入列表的尾部传递给每个递归调用很优雅,但构造尾部的开销使得这样做效率低下。相反,我们只是传递一个递增的
i
,作为遍历列表的索引

# Elegant, but inefficient
def _linear_search(l, key):
    if not l:
        raise LookupError(key)
    elif l[0] == key:
        return 0
    else:
        return 1 + _linear_search(l[1:], key)

# Clumsy, but faster
# Note: generally, you do not explicitly call this
# with an explicit value for i; it should only be
# used as a 
def _linear_search(l, key, i=0):
    if not l:
        raise LookupError(key)
    elif l[i] == key:
        return i
    else:
        return _linear_search(l, key, i+1)

# Slightly more complicated, but hides the i argument from the user
def _ls_helper(l, key, i):
        if not l:
            raise LookupError(key)
        elif l[i] == key:
            return i
        else:
            return _ls_helper(l, key, i+1)

def _linear_search(l, key):
    return _ls_helper(l, key, 0)

只有三种情况需要担心:

  • 如果输入列表为空,则引发异常
  • 如果列表的“第一个”元素是匹配的,则返回索引
  • 如果列表的“第一个”元素不匹配,则进行递归调用并返回其值
我将“first”放在引号中,因为虽然将输入列表的尾部传递给每个递归调用很优雅,但构造尾部的开销使得这样做效率低下。相反,我们只是传递一个递增的
i
,作为遍历列表的索引

# Elegant, but inefficient
def _linear_search(l, key):
    if not l:
        raise LookupError(key)
    elif l[0] == key:
        return 0
    else:
        return 1 + _linear_search(l[1:], key)

# Clumsy, but faster
# Note: generally, you do not explicitly call this
# with an explicit value for i; it should only be
# used as a 
def _linear_search(l, key, i=0):
    if not l:
        raise LookupError(key)
    elif l[i] == key:
        return i
    else:
        return _linear_search(l, key, i+1)

# Slightly more complicated, but hides the i argument from the user
def _ls_helper(l, key, i):
        if not l:
            raise LookupError(key)
        elif l[i] == key:
            return i
        else:
            return _ls_helper(l, key, i+1)

def _linear_search(l, key):
    return _ls_helper(l, key, 0)

请添加出现错误的数据。错误不是不言自明的吗?这意味着
l
是一个对象,它是不可下标的,也就是说,您不能执行
l[0]
?但我如何解决这个问题,我不是列表对象吗?当我试图解决这个问题时,我遇到的问题是我不知道如何缩短self.\u值,因为你不能将它作为参数传递到函数中。如果搜索失败,你不能返回
False
False
可能是列表中的一个元素。您必须在搜索失败时引发异常。请添加获取错误的数据。错误不是不言自明的吗?这意味着
l
是一个对象,它是不可下标的,也就是说,您不能执行
l[0]
?但我如何解决这个问题,我不是列表对象吗?当我试图解决这个问题时,我遇到的问题是我不知道如何缩短self.\u值,因为你不能将它作为参数传递到函数中。如果搜索失败,你不能返回
False
False
可能是列表中的一个元素。您必须在搜索失败时引发异常。虽然这很有用,但根本无法解决问题。问题是,他们把对类对象的引用当作一个列表……我同意这实际上是一个扩展的注释,而不是一个正确的答案。问题中没有足够的上下文来了解为什么函数被声明为类方法,或者为什么列表不能作为参数传递。虽然这些都很有用,但根本没有解决问题。问题是,他们把对类对象的引用当作一个列表……我同意这实际上是一个扩展的注释,而不是一个正确的答案。问题中没有足够的上下文来了解为什么函数被声明为类方法,或者为什么列表不能作为参数传递。