Actually you should break the function down first:
A loop has a few parts:
the header, and processing before the loop. May declare some new variables
the condition, when to stop the loop.
the actual loop body. It changes some of the header's variables and/or the parameters passed in.
the tail; what happens after the loop and return result.
Or to write it out:
foo_iterative(params){
header
while(condition){
loop_body
}
return tail
}
Using these blocks to make a recursive call is pretty straightforward:
foo_recursive(params){
header
return foo_recursion(params, header_vars)
}
foo_recursion(params, header_vars){
if(!condition){
return tail
}
loop_body
return foo_recursion(params, modified_header_vars)
}
Et voilà; a tail recursive version of any loop. breaks and continues in the loop body will still have to be replaced with return tail and return foo_recursion(params, modified_header_vars) as needed but that is simple enough.
Going the other way is more complicated; in part because there can be multiple recursive calls. This means that each time we pop a stack frame there can be multiple places where we need to continue. Also there may be variables that we need to save across the recursive call and the original parameters of the call.
We can use a switch to work around that:
bar_recurse(params){
if(baseCase){
finalize
return
}
body1
bar_recurse(mod_params)
body2
bar_recurse(mod_params)
body3
}
bar_iterative(params){
stack.push({init, params})
while(!stack.empty){
stackFrame = stack.pop()
switch(stackFrame.resumPoint){
case init:
if(baseCase){
finalize
break;
}
body1
stack.push({resum1, params, variables})
stack.push({init, modified_params})
break;
case resum1:
body2
stack.push({resum2, params, variables})
stack.push({init, modified_params})
break;
case resum2:
body3
break;
}
}
}
Answer from ratchet freak on Stack ExchangeActually you should break the function down first:
A loop has a few parts:
the header, and processing before the loop. May declare some new variables
the condition, when to stop the loop.
the actual loop body. It changes some of the header's variables and/or the parameters passed in.
the tail; what happens after the loop and return result.
Or to write it out:
foo_iterative(params){
header
while(condition){
loop_body
}
return tail
}
Using these blocks to make a recursive call is pretty straightforward:
foo_recursive(params){
header
return foo_recursion(params, header_vars)
}
foo_recursion(params, header_vars){
if(!condition){
return tail
}
loop_body
return foo_recursion(params, modified_header_vars)
}
Et voilà; a tail recursive version of any loop. breaks and continues in the loop body will still have to be replaced with return tail and return foo_recursion(params, modified_header_vars) as needed but that is simple enough.
Going the other way is more complicated; in part because there can be multiple recursive calls. This means that each time we pop a stack frame there can be multiple places where we need to continue. Also there may be variables that we need to save across the recursive call and the original parameters of the call.
We can use a switch to work around that:
bar_recurse(params){
if(baseCase){
finalize
return
}
body1
bar_recurse(mod_params)
body2
bar_recurse(mod_params)
body3
}
bar_iterative(params){
stack.push({init, params})
while(!stack.empty){
stackFrame = stack.pop()
switch(stackFrame.resumPoint){
case init:
if(baseCase){
finalize
break;
}
body1
stack.push({resum1, params, variables})
stack.push({init, modified_params})
break;
case resum1:
body2
stack.push({resum2, params, variables})
stack.push({init, modified_params})
break;
case resum2:
body3
break;
}
}
}
Following up on @ratchet freak's answer, I created this example of how the Fibonacci function can be rewritten to a while loop in Java. Note that There's a much simpler (and efficient) way to rewrite the Fibonacci with a while loop though.
class CallContext { //this class is similar to the stack frame
Object[] args;
List<Object> vars = new LinkedList<>();
int resumePoint = 0;
public CallContext(Object[] args) {
this.args = args;
}
}
static int fibonacci(int fibNumber) {
Deque<CallContext> callStack = new LinkedList<>();
callStack.add(new CallContext(new Object[]{fibNumber}));
Object lastReturn = null; //value of last object returned (when stack frame was dropped)
while (!callStack.isEmpty()) {
CallContext callContext = callStack.peekLast();
Object[] args = callContext.args;
//actual logic starts here
int arg = (int) args[0];
if (arg == 0 || arg == 1) {
lastReturn = arg;
callStack.removeLast();
} else {
switch (callContext.resumePoint) {
case 0: //calculate fib(n-1)
callStack.add(new CallContext(new Object[]{arg - 1}));
callContext.resumePoint++;
break;
case 1: //calculate fib(n-2)
callContext.vars.add(lastReturn); //fib1
callStack.add(new CallContext(new Object[]{arg - 2}));
callContext.resumePoint++;
break;
case 2: // fib(n-1) + fib(n-2)
callContext.vars.add(lastReturn); //fib2
lastReturn = (int) callContext.vars.get(0) + (int) callContext.vars.get(1);
callStack.removeLast();
break;
}
}
}
return (int) lastReturn;
}
def count(ls):
if not ls: # empty
return 0
return count(ls[1:]) + 1
Use it like this:
>>> find = [a, b, c, d]
>>> count(find)
4
I managed to do so by defining the following function:
def ric(find, n, c):
if n < len(find):
if find[n] in find:
c += 1
n += 1
return ric(find, n, c)
else:
return c
and calling it with ric(find, 0, 0)
loops - Recursive looping function in Python - Stack Overflow
[Python] Converting Nested For-Loop into Recursion
python - How can I replace a nested for loop with recursion? - Stack Overflow
Converting a for loop to recursion in Python - Stack Overflow
Videos
A recursive function is a nice way to do this:
def collect_folders(start, depth=-1)
""" negative depths means unlimited recursion """
folder_ids = []
# recursive function that collects all the ids in `acc`
def recurse(current, depth):
folder_ids.append(current.id)
if depth != 0:
for folder in getChildFolders(current.id):
# recursive call for each subfolder
recurse(folder, depth-1)
recurse(start, depth) # starts the recursion
return folder_ids
I generally avoid recursion like the plague in python because it's slow and because of the whole stack overflow error thing.
def collect_folders(start):
stack = [start.id]
folder_ids = []
while stack:
cur_id = stack.pop()
folder_ids.append(cur_id)
stack.extend(folder.id for folder in getChildFolders(cur_id))
return folder_ids
This assumes that getChildFolders returns an empty list when there are no children. If it does something else, like return a sentinel value or raise an exception, then modifications will have to be made.
Hey guys, I'm pretty new to python and I'd like to practice using Recursion in my code to further assist my understandings with the recursive function. From what I am aware of, identifying a base case is required to prevent infinite recursion but I cannot seem to figure out the base case for this scenario.
Simplified code as shown below:
for y in range(N):
for x in range(M):
if origin[x][y] == 1 and CellsMap[x][y] == 0:
CellsCounter += 1
DiscoverCells(origin, x, y, CellsCounter) Basically the above code will scan for every (x, y) coordinate in a grid (Implemented by the nested For Loop)
How do I go about converting this code into recursion, with a call to function of def DiscoverCells()?
Thanks in advance!!
I would approach this as follows:
def recursive(input, output=None):
if output is None:
output = {} # container to store results
if 'children' in input:
# do whatever, add things to output
recursive(input['children'], output)
return output
This way, the output dictionary is accessible to all depths of iteration and gets returned with all contents at the end. This means that you don't have to explicitly deal with the return values of the recursive calls.
Depending on exactly what you have, it may look more like:
def recursive(input, output=None):
if output is None:
output = {} # container to store results
if 'children' in input:
for child in input['children']:
# do whatever, add things to output
recursive(child, output)
return output
And output may be a different container (e.g. list, set).
def recurseDict(dictionary):
if "children" in dictionary:
return recurseDict(dictionary['children'])
else:
return "Whatever you want to return here -- you didn't specify"
This will take a dictionary, check if "children" is one of its keys, then recurse through the dictionary dictionary['children'] and etc etc until it gets to a point where there isn't a 'children' key (e.g. the dictionary has no further branches) where it goes into the else branch and you can return whatever the heck you want -- you didn't specify.
You can use itertools.product and its repeat argument:
from operator import mul
import itertools
def myprod(n, div, repeat=4):
# i is a list of factors
for i in itertools.product(range(n), repeat=repeat):
# calculate product of all elements of list
prod = reduce(mul, i, 1)
if prod % div == 0:
yield prod
print list(myprod(10, 6))
Changing the repeat argument of myprod will change the number of loops and factors you are calculating.
Also, since multiplication is commutative (a * b == b * a) you should eliminate repetitive computations using itertools.combinations_with_replacement:
from operator import mul
import itertools
def myprod_unique(n, div, repeat=4):
for i in itertools.combinations_with_replacement(range(n), r=repeat):
prod = reduce(mul, i, 1)
if prod % div == 0:
yield prod
print list(myprod_unique(10, 6))
If you remove duplicate results from myprod using set you will find that the two results are equal:
print set(myprod_unique(10, 6)) == set(myprod(10, 6))
but you have cut down the number of operations drastically from n ** r to (n+r-1)! / r! / (n-1)!. For example 92,378 instead of 10,000,000,000 for n=10, r=10.
You should have a look at the builtin package itertools:
for a,b,c,d in itertools.product(range(10),range(10),range(10),range(10)):
if (a*b*c*d)%6==0:
allProducts.append(a*b*c*d)
Is it true? If not can anyone give counter examples of code where one cannot be switched to another?
I think the key here is really in just getting used to thinking about recursion and how to solve problems with it. It really is a "work backwards" kind of a solution. With that in mind, let's see if we can develop a recursive solution together.
- Whenever you're writing something recursive, you're essentially always going to want to start at the end of the problem -- what will or should the behavior of the code be when it is finished, when it has found the answer? What overall environment and inputs should we expect at that final state? And, most importantly, how can we "propagate" our answer back up the call stack without losing anything we care about in the process?
First things first: before we can properly get started thinking about or writing any code, we need to make sure we're equipped with the right tools for the job: choosing and preparing the proper data structures (where minor differences in choice can be the difference between hacking away at an incorrect or suboptimal solution for days, or figuring out an elegant and optimal one in a few hours!) The dictionary you've provided as shown here really isn't doing you any favors: the values, as lists of lists, are difficult to check through cleanly and efficiently, Pythonically without a lot of cruft. Personally, I think this particular problem lends itself well to a dict of dicts, i.e.
d = { 'dict1': { 'Movie1': 'Fiction', 'Movie2': 'Romance' }, etc... }considering that the dict values already form a natural association (in fact, they closely resemble a popular way of instantiating dicts: with a list of
(key, value)tuples). If this doesn't seem like your cup of tea, I think another strategic choice would be having parallel dicts of lists -- sharing the same keys, but having one just for movie titles and one just for genres. The lists should be easy to use while coding your solution, but (unlike the nested dictionaries before --dict_valuesanddict_keysare implemented as sets behind the scenes) won't make lookup quite as quick...so depending on your use case this would be less preferable. A quick illustrative example:movies = {'dict1': ['Movie1', 'Movie2'], 'dict2': ['Movie3']} genres = {'dict1': ['Fiction', 'Romance']}In this set-up, you'd first check through the level of dictionary keys and then the list indices of the value for the matching entry in the corresponding dictionary.
In general, though, it can really simplify your code and your thought process to not try to cram too many different things (data with different meanings or uses) into the same object rather than having a neat, well-laid plan for utilizing a collection of objects designed to work together, especially if that can be done in a manner so as to not waste a lot of memory.
Now that we have a general plan (the dict-of-dicts approach first described above) we can return to our original question: where do we end when solving this problem? What is our base case (important terminology as you progress with recursion)? Well, that actually seems trivially easy -- the base case is when we are looking at some collection (a
list,set,dictkeys or values, what have you) and we find that it contains the movie title we are searching for. So we can already write our base case (partially)def recursive_movie_search(movie, db, ...): if movie in db: return movie, db[movie] # Rest of search logic goes hereNotice that because of our choice of data structure, once we've found the movie title we've already got the genre as well, since they're formally associated. We're not quite done yet though, as hinted at by the comment and the ellipsis in the function signature above.
Here's the last challenge to the recursive technique -- how do we make it so that, by the time we find what we're looking for, we have any and all other information we need to produce our final answer? Often, as in this case, this has to do with cleverly passing along any necessary auxiliary information on our way (down the recursive call stack) to solving the problem. One simple way (not that there's only one!) to finish off the implementation in this case would be something like the following:
def recursive_movie_search(movie, db, prev=None): prev = prev or [] if movie in db: return prev.extend((movie, db[movie]])) for key in db: search = recursive_movie_search(movie, db[key], prev + [key]) if search: return search return False
Now, to be fair, the problem as you gave it wasn't particularly well-suited to a recursive solution since the searching we needed to do was quite shallow. But the approach above should work with arbitrarily deeply nested dictionaries (then once you get the answer you can decide which of the keys along the path that led to it are significant and worth reporting, or should just be omitted). The only assumption made is that at the bottom level the movie titles will be associated with their genres.
Note also that there are several minor changes you could have made just based on personal choice: instead of accumulating the keys and passing them into the function, this could have been handled simply in the recursive call, e.g. search = key + recursive_movie_search(movie, db[key]) but then this would have required a slightly more thorough check on the next line to ensure that we got a "hit" with that call. Also, you could just as easily return None, an empty list [], or any other item whose boolean value evaluates to False (in the failure case where the movie isn't found) and this logic will work just as well. You just need some kind of flag there to tell you that the search failed -- you could even use a special string that you check for specifically.
P.S. This is my first answer on StackOverflow -- I really hope it helps! And I'm very much open to further questions or feedback on how I can improve :)
Assuming that your given structure does not change for other cases, I think this is what you are looking for:
dic = {
"dict1": [["Movie1", "Fiction"], ["Movie2", "Romance"]],
"dict2": [["Movie3", "Comedy"]],
}
def rec_search(data, movie_name):
if isinstance(data, dict):
for key in data.keys():
result = rec_search(data[key], movie_name)
if isinstance(result, tuple):
return f"found in {key}; Title: {result[0]}; Genre: {result[1]}"
return None
elif isinstance(data, list):
for element in data:
if isinstance(element, str):
if element == movie_name:
return element
else:
result = rec_search(element, movie_name)
if result:
return (result, element[1])
return None
print(rec_search(dic, "Movie2"))
What I think you are trying to achieve can be done with recursion:
def recursive(n, p=2, prev=[]):
productList = []
for k in range(10**(n-1),10**n):
if p == 1:
productList.append([k, k])
else:
for product in recursive(n, p=p-1):
productList.append([k] + product[:-1] + [k*product[-1]])
return productList
do you need all products to be unique, as this will give (2*4=8) also as (4*2=8)?
The batteries for this in SymPy are already included:
from sympy.utilities.iterables import subsets
from sympy.core.mul import prod
numbers = [1, 2, 3] # or whatever factors you want
p = 2 # how many factors you want
for n in subsets(numbers, p, repetition=True):
print(n + (prod(n),))
This outputs
(1, 1, 1)
(1, 2, 2)
(1, 3, 3)
(2, 2, 4)
(2, 3, 6)
(3, 3, 9)
This is different from cartes (or product) in that you won't get permutations of the factors, e.g. the latter would also give (2, 1, 2), a permutation of (1, 2, 2). You can read more about subsets using help(subsets) in SymPy and you can read the source if you want to.