Why does this recursive function exceed maximum length in python? - python

#finds length of a list recursively, don't understand why it exceeds maximum length, can someone please explain?
def lengtho(xs):
if(xs == None):
return 0
return 1 + lengtho(xs[1:])
lengtho([1,2,3,4,1,4,1,4,1,1])

When the code reaches the end of the list (the base case), xs will be equal to [] (the empty list), not None. Since [][1:] simply returns [], the function will call itself until the stack overflows.
The correct way to write this function in python would be:
def lengthof(xs):
"""Recursively calculate the length of xs.
Pre-condition: xs is a list"""
if (xs == []):
return 0
else:
return 1+ lengthof(xs[1:])

Your base case of recursion will never get to True value, xs == None will be always False if you are talking about lists, probably you want to change it to xs == [] or just if not xs

Related

How to initialize a tuple in Python using recursion

I'm working on course work for school, the problem is as follows,
The elements of tuple can be initialized so that tup[i] == i in a recursive fashion as follows:
A tuple of size 0 is already initialized
Otherwise:
set the last element of the tuple to n-1 (where n is the number of elements in the tuple)
initialize the portion of the tuple consisting of the first n-1 elements
Write a function named init that takes one argument, a tuple of the proper length, and returns an tuple initialized as described above.
def init(tupin):
if len(tupin) == 0:
return tupin
else:
return (0,) + init(tupin[1:])
so far this is all I have been able to get.
You skipped the step set the last element of the tuple to n-1. You can do that by appending (len(tupin)-1,).
def init(tupin):
if len(tupin) == 0:
return tupin
else:
return init(tupin[1:]) + (len(tupin)-1, )
Maybe like this:
def init(tupin):
if not isinstance(tupin, tuple):
raise TypeError("Please, supply a tuple to the function")
if len(tupin):
return init(tupin[:-1]) + (len(tupin)-1,)
else:
return tupin

Reverse sign function returns none [duplicate]

This question already has answers here:
Why is "None" printed after my function's output?
(7 answers)
Closed 4 years ago.
I would like to create a function where one passes a list of numbers and gets back another list where the signs of all numbers are reversed. This is my code:
def reverse_sign_of_nos_in_a_list(list1):
""" This function reverses sign of numbers
in a list and returns a list.
"""
list2 = []
for num in list1 :
if num > 0 :
return list2.append(num * -1)
elif num < 0 :
return list2.append(abs(num))
else :
return list2.append(num)
print (reverse_sign_of_nos_in_a_list([1,2,3,-1,-2,-3,0]))
The above code shows None as the output. What's the issue?
The are a couple of things wrong with your code:
You have a return statement in every branch of your code. That means that you will return from the first iteration of the loop no matter what.
list.append modifies the target instance in place. As is conventional in Python for such methods, it returns None, which, combined with #1 means that you always get a return value of None.
There's also something very strange about your code. You flip the sign of a positive number by multiplying by -1. That makes sense. But then you take the absolute value of a negative number. Why? Flipping the sign is the same as multiplying by -1 for negative numbers too. And even for zero.
In fact, you don't even need to multiply by -1. There's already a "flip the sign" operator: unary -.
You can write your function as a single list comprehension:
def reverse_sign_of_nos_in_a_list(list1):
return [-x for x in list1]
list.append() method will append the new element in-place and then will return None. So your function returns that None. Also it will return immediatelly after first element of the original list is processed.
def reverse_sign_of_nos_in_a_list(list1):
""" This function reverses sign of numbers
in a list and returns a list.
"""
list2 = []
for num in list1:
if num > 0:
list2.append(num * -1)
elif num < 0:
list2.append(abs(num))
else:
list2.append(num)
return list2
print(reverse_sign_of_nos_in_a_list([1,2,3,-1,-2,-3,0]))
Please, note I keep the code as close as possible to the original code. I would implement the function differently.
reverse_sign_of_nos_in_a_list is returning None because list.append() returns None, not appended list.
Following should do the job:
def reverse_sign_of_nos_in_a_list(list1) :
""" This function reverses sign of numbers
in a list and returns a list.
"""
list2 = []
for num in list1 :
if num > 0 :
list2.append(num * -1)
elif num < 0 :
list2.append(abs(num))
else :
list2.append(num)
return list2
You need to append and then return the list.
list2.append(...)
return list2
The reason you are getting None as output is because append is a void-Method that does not return a value. It only alters list2.
If you want every element of your list reversed, you should remove all the return which cause the function to return prematurely.
Code
def reverse_sign_of_nos_in_a_list(list1) :
""" This function reverses sign of numbers
in a list and returns a list.
"""
list2 = []
for num in list1 :
if num > 0 :
list2.append(num * -1)
elif num < 0 :
list2.append(abs(num))
else :
list2.append(num)
return list2
print (reverse_sign_of_nos_in_a_list([1,2,3,-1,-2,-3,0]))
Because list.append(elem) -- adds a single element to the end of the list. Common error: does not return the new list, just modifies the original
You should use similar to:
def reverse_sign_of_nos_in_a_list(list1) :
""" This function reverses sign of numbers
in a list and returns a list.
"""
list2 = []
for num in list1 :
if num > 0 :
list2.append(-num)
elif num < 0 :
list2.append(abs(num))
else:
list2.append(num)
return list2
print(reverse_sign_of_nos_in_a_list([1,2,3,-1,-2,-3,0]))
A different, shorter (and kind of more pythonic) way for the whole thing:
def reverse_sign_of_nos_in_a_list(list1):
return [(-1)*ii for ii in list1]

How can I return a single boolean value from a recursive function?

I have this function:
def most(P, S):
def recursion(P,S):
if len(S) == 0:
return []
elif P(S[0]):
return [P(S[0])] + recursion(P, S[1:])
else:
return recursion(P, S[1:])
if len(recursion(P,S)) > len(S)/2:
return True
else:
return False
It takes an input of function, P and list, S. If the result of P(S[i]) is true for most of S, then the function most() should return true. Any idea how I can do this recursively without a function inside of a function? In other words, how can I return a single boolean value from a recursive function that takes a list as its input?
Thanks!
The biggest key to recursion is understanding the "terminal condition." What is the state where the function must stop? In this case, it's the empty list.
def most(pred, lst):
if lst == []:
return # but what do we return?
You will need to keep track of the number of list elements that meet an expectation... so you have to keep track of both the expectation (i.e. how many have to be true in order for "most" to be true), as well as the count so far. Let's add those...
def most(pred, lst, threshold=None, count=0):
if threshold is None:
threshold = len(lst) // 2
if lst == []:
return count > threshold
So, then we need to "deconstruct" the list so that we can recurse over it. Let's add that...
def most(pred, lst, threshold=None, count=0):
if threshold is None:
threshold = len(lst) // 2
if lst == []:
return count > threshold
# Check the 'truth' of the head of the list...
if pred(lst[0]):
count += 1
# ...and pass the tail of the list into the next iteration.
return most(pred, lst[1:], threshold, count)
That should be all that you need. Now, I'll caution you that if your lists are of significant length, Python will blow its stack. This is also significantly slower than a solution using a for loop or reduce, because of all the additional function calls.
If I were implementing most for production code, I would do this:
def most(pred, lst):
return sum(1 for x in lst if pred(x)) > len(lst) // 2

On Finding the Maximum Depth of an Arbitrarily Nested List

I'm currently working with a recursive function in Python, and I've run into a wall. As titled, the problem is to return the maximum depth of an arbitrarily nested list.
Here is what I have so far:
def depthCount(lst):
'takes an arbitrarily nested list as a parameter and returns the maximum depth to which the list has nested sub-lists.'
var = 0
if len(lst) > 0:
if type(lst[0]) == list:
var += 1
depthCount(lst[1:])
else:
depthCount(lst[1:])
else:
return var
I feel that the problem is with my recursive calls (this may be obvious). It will indeed return var when the list has reached the end, but when I have a nonempty list, things go awry. Nothing is returned at all.
Am I slicing wrong? Should I be doing something before the slice in the recursive call?
The problem may also be with my base case.
If they are just nested lists, e.g., [[[], []], [], [[]]], here's a nice solution:
def depthCount(lst):
return 1 + max(map(depthCount, lst), default=0)
Here's a slight variation you could use if you don't use Python 3.4, where the default argument was introduced:
def depthCount(lst):
return len(lst) and 1 + max(map(depthCount, lst))
They also differ by how they count. The first considers the empty list to be depth 1, the second to be depth 0. The first one is easy to adapt, though, just make the default -1.
If they're not just nested lists, e.g., [[[1], 'a', [-5.5]], [(6,3)], [['hi']]]), here are adaptions to that:
def depthCount(x):
return 1 + max(map(depthCount, x)) if x and isinstance(x, list) else 0
def depthCount(x):
return int(isinstance(x, list)) and len(x) and 1 + max(map(depthCount, x))
Make sure you understand how the latter one works. If you don't know it yet, it'll teach you how and works in Python :-)
Taking the "purely recursive" challenge:
def depthCount(x, depth=0):
if not x or not isinstance(x, list):
return depth
return max(depthCount(x[0], depth+1),
depthCount(x[1:], depth))
Granted, the extra argument is slightly ugly, but I think it's ok.
It will indeed return var when the list has reached the end, but when I have a nonempty list, things go awry. Nothing is returned at all.
That's because you have no return statement, except in the else base case for an empty list. And if you fall off the end of the function without hitting a return, that means the function returns None.
But you have another problem on top of that. You're starting var = 0, then possibly doing var += 1… but you're not passing that down into the recursive calls, or using any result from the recursive calls. So the recursive calls have no useful effect at all.
What you probably meant is something like this:
def depthCount(lst):
'takes an arbitrarily nested list as a parameter and returns the maximum depth to which the list has nested sub-lists.'
if len(lst) > 0:
if type(lst[0]) == list:
return 1 + depthCount(lst[1:])
else:
return depthCount(lst[1:])
else:
return 0
But this still isn't actually right. The depth count of a list is 1 more than the depth count of its deepest element. Just checking its second element won't do you any good; you need to check all of them. So, what you really want is something like this:
def depthCount(lst):
'takes an arbitrarily nested list as a parameter and returns the maximum depth to which the list has nested sub-lists.'
if isinstance(lst, list):
return 1 + max(depthCount(x) for x in lst)
else:
return 0
If you want to replace that iterative for x in lst with a second layer of recursion, of course you can, but I can't see any good reason to do so; it just makes the code more complicated for no reason. For example:
def max_child_count(lst):
if lst:
return max(depth_count(lst[0]), max_child_count(lst[1:]))
else:
return 0
def depth_count(lst):
if isinstance(lst, list):
return 1 + max_child_count(lst)
else:
return 0
This may still not be right. It definitely does the right thing for, e.g., [1, [2,3], [4, [5]]]. But what should it do for, say, []? I can't tell from your question. If it should return 0 or 1, you'll obviously need to change the if appropriately. If that's illegal input, then it's already doing the right thing. (And that should also answer the question of what it should do for, e.g., [[[], []], [], [[]]], but make sure you think through that case as well.)
So, essentially, the data structure that you're referring to is a k-ary tree, also known as n-ary tree, with arbitrary branching. Here's the code for determining the max. depth of a n-ary tree with arbitrary branching.
def maxdepth(tree):
if isleaf(tree):
return 1
maximum = 0
for child in children(tree):
depth = maxdepth(child)
if depth > maximum:
maximum = depth
return maximum + 1
You can see the code in action with different test inputs here.

How to write a recursive function that returns a list made up of squares of the elements of lst?

Im not sure how to get my recursion to work properly or keep from infinitely repeating.
This is what i have so far:
def listSquareR(lst):
if len(lst)== 1:
return lst[0]**2
else:
return lst[0]**2+[listSquareR(lst[1:])]
last return line is obviously wrong
Another possibility:
def listSquare(L):
if L: return [L[0]**2] + listSquare(L[1:])
else: return []
An even shorter version (as Cristian Ciupitu mentions below) is:
def listSquare(L):
return [L[0]**2] + listSquare(L[1:]) if L else []
You have it almost right, but the key is to mind your types. In your code:
def listSquareR(lst):
if len(lst)== 1:
return lst[0]**2 # Returning a number
else:
return lst[0]**2+[listSquareR(lst[1:])] # Returning a number plus a list of a list
We just need two small fixes:
def listSquareR(lst):
if len(lst)== 1:
return [lst[0]**2] # Returning a list
else:
return [lst[0]**2] + listSquareR(lst[1:]) # Returning a list plus a list
def SquareArea(width):
if width == 0:
return 0
else:
return SquareArea(width-1) + (2*width-1)
This is a recursive function I've recently used to find the area of a square.
And since the area of a square is Side*Side, one can use it to find the square of any function.
Now all that is required of you is to make a loop, eg:
for i in range (list):
and implement this function on i
Or maybe use while loop.
newList=[]
length = len(list)
while i != length:
newList.append(SquareArea(i))
And then return the newList

Categories

Resources