Reputation: 109
Hi how would I do linear search using recursion instead of doing it iteratively? This is how I'm trying to do it currently. I get this error
if l[0] == key:
TypeError: 'type' object is not subscriptable TypeError: 'type' object is not subscriptable for l
@classmethod
def _linear_search_r(l,key, i=0):
if l: #Check if list is not empty
if l[0] == key:
return i
s = _linear_search_r(l[1:],key, (i + 1))
if s is not False:
i = s
return i
return False
Upvotes: 0
Views: 1484
Reputation: 531858
There are only three cases to worry about:
I put "first" in quotes because while it is elegant to pass the tail of the input list to each recursive call, the overhead of constructing the tail makes it inefficient to do so. Instead, we just pass an incremented i
along to use as an index to walk the list.
# 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)
Upvotes: 1
Reputation: 155505
This is a class method, so the first argument it receives (which you named l
) is a reference to the class itself.
If l
is supposed to be an instance of said class, remove the @classmethod
decorator. If l
is supposed to be unrelated to the class, either change @classmethod
to @staticmethod
(the latter does not implicitly receive the type as the first argument) or add a cls
argument in front of l
.
If the goal is to process an instance attribute, then I'd suggest making the top-level function an instance method, with a recursive helper method (that's either class or static). For example:
# 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
Upvotes: 2