I'm new to recursion and finding it pretty difficult to grasp. I can't figure out how to append an empty array if I can't directly "touch" it. If its a string I would add the value each time. If it was a number that involved multiplication, I could multiply it each time, but with an array, I don't know what to do.
I dont know how to append to an empty array without being able to directly "touch" it.
This is what I've done so far:
def laugh(num):
if num == 0:
return []
# This doesnt work since we can't append a function call. I'm unsure what to do.
return laugh(num - 1).append("ha ")
print(laugh(3)) -> ["ha, ha, ha"]
If could do this easily if i could just return a string of "Ha"'s instead. I could return an empty string and just add a "Ha" for each step.
You can modify it like:
def laugh(num):
if num == 0:
return []
haha = laugh(num-1)
haha.append("ha")
return haha
Since append does not return the modified list, you have to do it in two steps. Using concatenation and the ternary operator, you can shrink this to:
def laugh(num):
return laugh(num-1) + ["ha"] if num else []
In this case you are mutating the list by calling append on it. What you want to do is return a new list:
def laugh(num):
# base case
if num == 0:
return []
# recursive case
return ["ha"] + laugh(num-1)
Related
Let's say I have a string
S = "qwertyu"
And I want to build a list using recursion so the list looks like
L = [u, y, t, r, e, w, q]
I tried to write code like this:
def rec (S):
if len(S) > 0:
return [S[-1]].append(rec(S[0:-1]))
Ideally I want to append the last element of a shrinking string until it reaches 0
but all I got as an output is None
I know I'm not doing it right, and I have absolutely no idea what to return when the length of S reaches 0, please show me how I can make this work
(sorry the answer has to use recursion, otherwise it won't bother me)
Thank you very much!!!
There are many simpler ways than using recursion, but here's one recursive way to do it:
def rec (S):
if not S:
return []
else:
temp = list(S[-1])
temp.extend(rec(S[:-1]))
return temp
EDIT:
Notice that the base case ensures that function also works with an empty string. I had to use temp, because you cannot return list(S[-1]).extend(rec(S[:-1])) due to it being a NoneType (it's a method call rather than an object). For the same reason you cannot assign to a variable (hence the two separate lines with temp). A workaround would be to use + to concatenate the two lists, like suggested in Aryerez's answer (however, I'd suggest against his advice to try to impress people with convoluted one liners):
def rec (S):
if not S:
return []
else:
return list(S[-1]) + rec(S[:-1])
In fact using + could be more efficient (although the improvement would most likely be negligible), see answers to this SO question for more details.
This is the simplest solution:
def rec(S):
if len(S) == 1:
return S
return S[-1] + rec(S[:-1])
Or in one-line, if you really want to impress someone :)
def rec(S):
return S if len(S) == 1 else S[-1] + rec(S[:-1])
Since append mutates the list, this is a bit difficult to express recursively. One way you could do this is by using a separate inner function that passes on the current L to the next recursive call.
def rec(S):
def go(S, L):
if len(S) > 0:
L.append(S[-1])
return go(S[0:-1], L)
else:
return L
return go(S, [])
L = [i for i in S[::-1]]
It should work.
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)
A little background: I've been trying to code a "Sieve of Eratosthenes" algorithm. At the request of some fine (and very patient) programmers on the StackOverflow Python chatroom, I did some reading on the enumerate() function and found a way to incorporate it into my code (yes, I'm very much a novice here). So far, my (workable; returns expected response) code looks like this:
def SieveErat(n):
numbers = [False]*2+[True]*(n-1)
for index, prime_candidate in enumerate(numbers):
if prime_candidate == True:
yield index
for x in xrange(index*index, n, index):
numbers[x] = False
primes = []
for x in SieveErat(150000):
primes.append(x)
print primes[10002]
Needless to say, the enumerate() function makes coding this much, much less awkward than whatever nested loops I had before. However, I fear that I'm not understanding something about enumerate(), because when I tried to shorten this code by including the appending into the function, I kept getting errors- namely,
File "SievErat.py", line 13
return numbers
SyntaxError: 'return' with argument inside generator
I've also tried appending all the True elements inside the list numbers to a initialized list primes, but found no luck.
Any hints or advice would be very much welcomed.
This has nothing to do with enumerate you are trying to return something in a generator which before python 3.3 is illegal, and from 3.3+ it means something entirely different.
I'd recommend you leave your function a generator if you may use it without needing a list back, and if you want list results then just call list() on the return value:
primes = list(SieveErat(150000)) #this replaces loop with .append
But to understand what went wrong, if your function still has the yield statement in it then it must return a generator object, if you don't want it to return a generator object then remove the yield statement all together:
def SieveErat(n):
numbers = [False]*2+[True]*(n-1)
for index, prime_candidate in enumerate(numbers):
if prime_candidate == True:
#yield index #no yield statement if you want to return the numbers list
for x in xrange(index*index, n, index):
numbers[x] = False
return numbers #return at end
However this would then return a list of True and False instead of the numbers that are True, you can instead hold a separate list with all the prime numbers and .append to it everytime you would yield something:
def SieveErat(n):
numbers = [False]*2+[True]*(n-1)
result = [] #start with no results
for index, prime_candidate in enumerate(numbers):
if prime_candidate == True:
results.append(index) #instead of yield index
for x in xrange(index*index, n, index):
numbers[x] = False
return results
But this feels like a step backwards from a generator, personally I'd just keep what you have posted and cast the result to a list.
I need to sum objects (strings, ints, etc.) in one function (don't create other function, it can be done within one). It should work this way: When given my_sum([[['s'],'ta'],['c',['k']]]), it should return 'stack'.
I came up with this:
def my_sum(array):
if not array: #empty array
return None
else:
for item in array:
if type(item) == list:
my_sum(item)
else:
print(item)
It of course is not doing what it should be, I was just playing around with it trying to come up with something. This code above returns this:
s
ta
c
k
I think I am not that far from result as I have what I need, but here is the problem how can I sum up those items ? I can't write result = '' anywhere in the function and then return it, because it would be deleting every time there would be recursion call. Also I don't want global variables (if anyone would think of that). Maybe I am just being stupid and can't see that it is one simple thing, pardon me if it is so.
Thank you for every answer!
The common accumulating pattern is:
result = <init value>
for item in argument:
result = result <operator> item
return result
(this can be written more concisely, but that's not the point for now).
Applied to your problem:
def my_sum(items):
result = ''
for item in items:
if type(item) == list:
result += my_sum(item)
else:
result += item
return result
Note that type(x) == y is frowned upon in Python, isinstance is considered better style.
Homework: extend the function so that it works for these arguments too:
print my_sum([[['s'],'ta'],('c',('k')), {('over'), ('flow')}])
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