Reputation: 97
Given the following array,
l = [
[0, 0, 0, 0, 0],
[0, 2, 1, 1, 0],
[0, 1, 0, 0, 0],
[0, 1, 1, 3, 0],
[0, 0, 0, 0, 0]
]
I am asked to define a recursive function that outputs "yay"
every time we find a certain element in this 2D array.
def f(element, lst):
if not lst:
return 0
if len(lst[0])==0:
return f(element,lst[1:])
if lst[0][0]==2:
print("yay")
return f(element,lst[0][1:])
return f(element, lst[0][1:])
f(2, l)
I should be getting "yay"
printed once. Instead I get the following:
Traceback (most recent call last):
File "finder.py", line 37, in <module>
f(2, l)
File "finder.py", line 35, in f
return f(element, lst[0][1:])
File "finder.py", line 30, in f
if len(lst[0])==0:
TypeError: object of type 'int' has no len()
Normally you can get the len()
of a sublist, but not in the case where you check inside a function.
Upvotes: 0
Views: 2208
Reputation: 6516
When you do this:
return f(element,lst[0][1:])
lst[0][1:]
cuts down your list of list into just a list. You get:
[0, 0, 0, 0]
That's why len(lst[0])
fails because lst[0] = 0
, an int
, therefore you can't get len()
from it.
You have to rethink your process.
What you're looking for will end up with a pretty ugly approach. Keep in mind you have to navigate both sides of your array. A nested loop can handle that nicely, unlike recursion.
Python has easier ways to do what you want, such as:
[print('yay') for i in l for j in i if j == element]
Upvotes: 1
Reputation: 476
When debugging, I usually find it very helpful to print out the values to see where they're erroring out. In this case (after fixing your assignment for l
since you seemed to have copied it wrong):
l = [[0, 0, 0, 0, 0],
[0, 2, 1, 1, 0],
[0, 1, 0, 0, 0],
[0, 1, 1, 3, 0],
[0, 0, 0, 0, 0]]
def f(element, lst):
print("Element: " + str(element))
print("List: " + str(lst))
if not lst:
return 0
if len(lst[0])==0:
return f(element,lst[1:])
if lst[0][0]==2:
print("yay")
return f(element,lst[0][1:])
return f(element, lst[0][1:])
f(2, l)
Which leads to:
Element: 2
List: [[0, 0, 0, 0, 0], [0, 2, 1, 1, 0], [0, 1, 0, 0, 0], [0, 1, 1, 3, 0], [0, 0, 0, 0, 0]]
Element: 2
List: [0, 0, 0, 0]
Traceback (most recent call last):
File "test.py", line 20, in <module>
f(2, l)
File "test.py", line 18, in f
return f(element, lst[0][1:])
File "test.py", line 13, in f
if len(lst[0])==0:
TypeError: object of type 'int' has no len()
It is erroring out on this line if len(lst[0])==0:
because you're trying to take the len()
of whatever object is in the 0th place of your list, which is a number.
As an example, this is almost exactly what is happening:
>>> len(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()
@slybloty's answer is why you're only getting a list.
Upvotes: 1
Reputation: 3782
The declaration for your list really only creates one list of integers.
l = [0, 0, 0, 0, 0]
[0, 2, 1, 1, 0]
[0, 1, 0, 0, 0]
[0, 1, 1, 3, 0]
[0, 0, 0, 0, 0]
Python assigns l
to [0, 0, 0, 0, 0]
and doesn't care about the next 4 lines. Because of that, this line:
if len(lst[0])==0:
attempts to find the length of l[0]
, which is an integer.
Simply change your declaration for l
to this:
l = [[0, 0, 0, 0, 0],
[0, 2, 1, 1, 0],
[0, 1, 0, 0, 0],
[0, 1, 1, 3, 0],
[0, 0, 0, 0, 0]]
Upvotes: 0