Recursive linear search method by using ending index - python

def searchletter(letterdata,eIndex,letter):
found_list=[]
if eIndex==-1:
return found_list
elif letterdata[eIndex]==letter:
found_list.append(letterdata[eIndex])
return searchletter(letterdata,eIndex-1,letter)
else:
return searchletter(letterdata,eIndex-1,letter)
letterdata=['a','b','a']
print(searchletter(letterdata,len(letterdata)-1,'a'))
Expected Output:
['a','a']
Hello, I actually know the reason why I get an empty list. It is because when I call the function inside the function, it makes found_list empty again, so is there any method for code not to read found_list=[] after it executes first time?

def searchletter(letterdata,eIndex,letter,found_list):
if eIndex==-1:
return found_list
elif letterdata[eIndex]==letter:
found_list.append(letterdata[eIndex])
return searchletter(letterdata,eIndex-1,letter,found_list)
else:
return searchletter(letterdata,eIndex-1,letter,found_list)
letterdata=['a','b','a']
print(searchletter(letterdata,len(letterdata)-1,'a',[]))
You are creating a list everytime your function gets called either you need to have a global list that keeps appending the elements or you can pass a list as an argument.

Related

How to store results in a recursive function and will my method even work?

My first attempt at writing a recursive function that lists all permutations of strings characters.
If I set a list to be empty, then add the results to this list, I find that the list gets reset to empty with each call of the function.
I know what I have at the moment is also wrong as the for loop will be broken by the return statement. But this is where I am stuck, how to save the results i.e. each separate permutation, without having the list reset to empty with each call? I am not allowed use global variables, this is an exercise from an MIT open Courseware class.
Also would like to know if my method will even work? not sure if how I have sliced the string up will work.
Can anyone shed light on how I can make a list of all the permutations within the function? and if my method even has any chance of working?
def get_permutations(sequence):
if len(sequence) == 1:
return sequence
else:
return (sequence[i] + get_permutations(sequence[0:i-1] + sequence[i +
1 : len(sequence)]) for i in range(len(sequence)))
Now the output is
<generator object get_permutations.<locals>.<genexpr> at 0x102b3b9d0>
You can't return more than once! Instead of returning each value from inside of a loop, you want to build a list and return that. That would look something like this:
def get_permutations(sequence):
if len(sequence) == 1:
# base case
return sequence
# Each recursive call needs to be on a subset of sequence so it gets
# smaller each time and eventually reaches the base case...
return [
sequence[i] + get_permutations(sequence[0:i-1] + sequence[i+1:len(sequence)])
for i in range(len(sequence))
]
There are still some errors here in how you're reducing to your base case and how you're building the list, but hopefully this gets you pointed in the right direction!
Since the function is supposed to return a list of permutations, you should use a nested for clause in the list comprehension to iterate through the returning list from the recursive call to append to the current value at index i. Also, in the base case the function should also return a list of string characters, even it's a list of just one character:
def get_permutations(sequence):
if len(sequence) == 1:
return [sequence]
return [
sequence[i] + s
for i in range(len(sequence))
for s in get_permutations(sequence[:i] + sequence[i + 1:])
]
so that:
get_permutations('abc')
returns:
['abc', 'acb', 'bac', 'bca', 'cab', 'cba']

What's the different between calling function with and without 'return' in recursion?

I tried to create recursive function for generating Pascal's triangle as below.
numRows = 5
ans=[[1],[1,1]]
def pascal(arr,pre,idx):
if idx==numRows:
return ans
if len(arr)!=idx:
for i in range (0,len(pre)-1,1):
arr+=[pre[i]+pre[i+1]]
if len(arr)==idx:
arr+=[1]
ans.append(arr)
pascal([1],arr,idx+1)
a = pascal([1],ans[1],2)
return a
The output I got was an empty list [ ]. But if I add return when calling pascal as
return pascal([1],arr,idx+1)
the output was correct [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]].
As I understand, a should have been assigned by return ans. Then why a failed to get an answer when calling pascal without return and why return is necessary in this case?
When you have recursion, you usually combine the returns in some way. Could be a sum, like fibonacci:
fibonacci(n+1) = fibonnaci(n)+fibonacci(n-1)
Or appending a line to a matrix, like your case. Anyway, if you don't have a return, you have no information to combine! Consider the fibonnaci case without return:
def fibonnaci(n):
if n<2:
return 1
fib_ans = fibonnaci(n-2)+fibonnaci(n-1)
In this case, if I called fibonnaci(0) or fibonnaci(1) the output would be 1, like you return ans if idx == numRows, but if I called fibonnaci(2), then the variable fib_ans would receive 2, which is the expected answer, but it would be available outside the scope of the funtion. Python "would add" return None to the end of my function, just below the fib_ans attribution. So, I need to return fib_ans
Well as far as i know, if you want to get a value back you need the "return" statement...
The point is if you don't have "return", you will be getting no values back...
Hopefully this helps..
For all algol languages that has a return keyword it exits the nearest function completely and the result of it is the result of the expression of the return argument. eg.
def test(v):
if v == 0:
return someFun(10)
...
If v is zero the result of the function is the value returned by someFun(10). The rest of the function denoted by ... is never executed unless v is nonzero.
If we write the same without return:
def test(v):
if v == 0:
someFun(10)
...
Now, when v is zero someFun(10) is still called, but the value returned by it is discarded and in order for it to have any true meaning someFun needs to do some side effects, like printing, storing values, updating object. In addition all the rest of the function denoted by ... is then continued once someFun(10) is done.
For Python and many other languages not having a return at all doesn't mean it doesn't return anything. In Python there is an invisible return None in the last line of every function/method.
When you do pascal([1],arr,idx+1), you are doing the recursive call but then discarding the value which it returns. If you want to return it to the caller, then you need to use explicitly return pascal(...).
In fact recursion is not necessary in this example anyway. You could easily refactor your code to use a simple for loop. For example:
def pascal(numRows):
ans = [[1]]
for _ in range(1, numRows):
pre = ans[-1]
arr = [1]
for i in range(0,len(pre)-1,1):
arr+=[pre[i]+pre[i+1]]
arr+=[1]
ans.append(arr)
return ans
print(pascal(5))
(I'm using the name _ here as the for loop variable according to convention because it is a dummy variable not used inside the loop, but you could use something else e.g. row if you prefer.)
The above is as close to the original code as possible, but you should also consider using arr.append(value) in place of arr += [value] -- this would be the normal way to append a single value to a list.

Setting a function to return its resulting value as a string

My goal is to have the function SRA_Accession return it's values as a string e.g "Value1,Value2,Value3" the code so far is
def SRA_Accession():
SRA=1293518
while (SRA < 1293618):
SRA=SRA+1
print "SRA"+str(SRA)
if False:
break
the lack of tabs are making this not work and you need a return statement which returns everything.
def SRA_Accession():
SRA=1293518
my_list = []
while (SRA < 1293618):
SRA=SRA+1
my_list.append("SRA"+str(SRA))
return ','.join(my_list)
Judging by the way you are writing the statement I would say you were looking to use a yield statement which returns each SRA string all by itself. This means you will need to add commas outside the function like so.
def SRA_Accession():
SRA=1293518
while (SRA < 1293618):
SRA=SRA+1
yield "SRA"+str(SRA)
value = ','.join(list(SRA_Accession()))
print(value)

stack function python error

I created the following stack class for a project and am having trouble getting it to function properly. I can't tell if i made the error or it is an error in the main function i was given by my TA, anyways here is my code:
class Stack:
#takes in the object as input argument
#will not return anything
def __init__(self):
#initialise an instance variable to an empty list.
self.items=[]
#takes in the object as input argument
#return value Type: True or False
def isEmpty(self):
#check if the list is empty or not. If empty, return True else return False
if self.items == []:
return True
else:
return False
#takes in the object as the first argument
#takes the element to be inserted into the list as the second argument
#should not return anything
def push(self, x):
#add the element to be inserted at the end of the list
self.items.append(x)
#takes in the object as the input argument
#if the list is not empty then returns the last element deleted from the list. If the list is empty, don't return anything
def pop(self):
#check if the list is Empty
#if Empty: print the list is empty
#if the list is not empty, then remove the last element from the list and return it
if self.isEmpty()==True:
print("the list is empty")
else:
return self.items.pop()
#takes in the object as the input argument
#should not return anything
def printContents(self):
#if the list is not empty, then print each element of the list
print("The content of the list is", self.items)
Based on the comments can anyone give me any advice on how I might make this work more appropriately? Sorry I am not a computer scientist and i am trying my hardest to understand classes and functions for my python class.
from stack import *
def main():
s = Stack()
s.push(1)
s.pop()
s.pop()
s.push(2)
s.push(3)
s.push(4)
s.printContents()
main()
You should take a good look in spaces and alignment. For example printContents is not properly aligned. Note the proper alignment is very, very important in python.
Also you are not printing in printContents. This should work:
class Stack:
#takes in the object as input argument
#will not return anything
def __init__(self):
#initialise an instance variable to an empty list.
self.items=[]
#takes in the object as input argument
#return value Type: True or False
def isEmpty(self):
#check if the list is empty or not. If empty, return True else return False
if self.items == []:
return True
else:
return False
#takes in the object as the first argument
#takes the element to be inserted into the list as the second argument
#should not return anything
def push(self, x):
#add the element to be inserted at the end of the list
self.items.append(x)
#takes in the object as the input argument
#if the list is not empty then returns the last element deleted from the list. If the list is empty, don't return anything
def pop(self):
#check if the list is Empty
#if Empty: print the list is empty
#if the list is not empty, then remove the last element from the list and return it
if self.isEmpty():
print("the list is empty")
else:
return self.items.pop()
#takes in the object as the input argument
#should not return anything
def printContents(self):
#if the list is not empty, then print each element of the list
print("the contents of the list are", self.items)
def main():
s = Stack()
s.push(1)
s.pop()
s.pop()
s.push(2)
s.push(3)
s.push(4)
s.printContents()
main()
You can see it working online here:
https://repl.it/BZW4
Everybody has to start sometime so no worries, and I hope you are not offended by my extended critique, as I am just trying to be helpful.
You probably want the top declaration to be:
class Stack(object):
Leaving off the (object): part is a deprecated form that makes certain features of the class different in ways you probably don't want.
Secondly, declaring an isEmpty method is not really a normal "pythonic" approach. The strong expected python convention is to simply check the truth value of your object, with empty being False. Typical python users of your class will not expect an isEmpty method. You can control the behavior of your object's truth value by defining the special nonzero which you could write like this:
def __nonzero__(self):
return bool(self.items)
This way somebody could use your class like:
stack = Stack()
stack.append("apple")
stack.append("pear")
if stack:
print "stack has stuff in it"
else:
print "stack is empty"
Moreover, there are other things you should overload to make a good stack class. For example you ought support len(stack) and you ought to be able to iterate over your stack. You can define special len and iter methods to do this. Notice if you define the len then you don't need to define the iszero (python will consider your stack False if len returns 0 and you have not defined iszero).
Your printContents method will not print or write anything without a print or write statement, but will return the last element in the stack and throw an index error if the stack is empty. To iterate over each item and print it you could write it like this (from the top item of stack to the first one):
def printContents(self):
for item in reversed(self.items):
print item
However it would be more pythonic to define an iteration method and the use that, so your user can iterate over your stack and print it themselves:
def __iter__(self):
for item in self.items:
yield item
# later in code .....
stack = Stack()
stack.append("apple")
stack.append("pear")
for item in stack:
print item
Hopefully these tips may prove useful. Keep at it, and you will get it before long.
Modify your pop definition in class to this
def pop(self):
#check if items is empty
if len(self.items)==0:
#if empty
return "Nothing to pop"
else:
#if not empty
return str(self.items.pop())+" Popped"

Python: Passing a list through a recursive function call causes the list to become 'NoneType', why?

I have the following recursive function:
def recurse(y,n):
if len(y) == n:
return y
else:
return recurse(y.append(1),n)
When I run it:
x=recurse([],10)
I get the following error:
TypeError: object of type 'NoneType' has no len()
It seems that the function gets past the if statement the 1st time around, then it goes into the next level of recursion, and there, y.append(1) is 'NoneType', why is it not: '[1]' as expected? I have thought about this for a while and I can't seem to figure it out. Any insight is appreciated!
The problem is here:
y.append(1)
The append() method returns None, so you can't pass its result for building the output list (you'd have to first append to the list and then pass it, as shown in other answers). Try this instead:
def recurse(y, n):
if len(y) == n:
return y
else:
return recurse(y + [1], n)
The above solution is more in line with a functional programming style. Using append adds an element to an existing list - which will mutate a function parameter, in general not a very good idea. On the other hand y + [1] creates a new list each time, leaving the parameter untouched. Proponents of functional programming will tell you that's a Good Thing.
list.append() calls the append method on a list, and while it modifies the list, it returns None.
So it does not return the list.
You want something like:
def recurse(y,n):
if len(y) == n:
return y
else:
y.append(1)
return recurse(y,n) # explicitly pass the list itself
y.append operates on y in place and returns None

Categories

Resources