0

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.


How can I check for an element in a 2D list using recursion?

4
  • 1
    @KenY-N: Even then it doesn't work and give the same error Commented Dec 19, 2018 at 23:56
  • I'm not sure what this implementation is really trying to do (perhaps explain the thinking behind it?) - but I can't actually think of a good way to do this using recursion. (The data structure has only 2 levels, and only one of those can actually contain the value 0.) I'd probably just do this in a loop instead. Commented Dec 19, 2018 at 23:59
  • I think if isinstance(lst, list): return 0 is needed. Please also note we expect the actual code to be posted, so please correct the declaration. Commented Dec 20, 2018 at 0:00
  • 1
    Edited, now it is ) Commented Dec 20, 2018 at 0:07

3 Answers 3

1

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.

Sign up to request clarification or add additional context in comments.

Comments

1

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.

Part II:

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]

Comments

0

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]]

1 Comment

But the call stack indicates that the error is after one level of recursion and the OP has pointed out their typo.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.