One way to break out of a recursive function in Python is to throw an exception and catch that at the top level. Some people will say that this is not the right way to think about recursion, but it gets the job done. Furthermore, if the task is to identify "problem" elements in an array/array of arrays/ndarray etc., a break technique is convenient, because it stops the algorithm from continuing after the global solution has been identified.
def solve_problem(lst):
def solve_rec(l):
'''has impl. that may throw an exception '''
try:
solve_rec(lst)
return True
except:
return False
Answer from garde on Stack OverflowOne way to break out of a recursive function in Python is to throw an exception and catch that at the top level. Some people will say that this is not the right way to think about recursion, but it gets the job done. Furthermore, if the task is to identify "problem" elements in an array/array of arrays/ndarray etc., a break technique is convenient, because it stops the algorithm from continuing after the global solution has been identified.
def solve_problem(lst):
def solve_rec(l):
'''has impl. that may throw an exception '''
try:
solve_rec(lst)
return True
except:
return False
def is_pal(string):
if len(string) <= 1:
return True
if first(string) == last(string):
return is_pal(middle(string))
else:
return False
That way, if they don't match, False is returned; if it makes it all the way to the end, True is returned. I also eliminated a redundant conditional and checked for the edge-case of an even-length palindrome.
How to Stop Recursion Function?
Getting out of a recursive function... - Post.Byes - Bytes
python - How to break out of recursive function? - Stack Overflow
How do I break out of loops in recursive functions?
So currently, I solved the issue with a global variable that won't change, but I feel dirty not properly solving this.
So in short, I have a binary tree with nodes, a node holds a key (name) and data.
I have a "find" function that is supposed to find a node with a given key, and return its data. Problem is, when I find it, I set the returning value to the data, but as it keeps recursively returning back this value (or pointer) is set to null, because I assume I just made a local change in the function call that found the node?
I traverse the tree using "inorder traversal".
double* find_key(Node * & p, int key_to_be_found, double* dataReturn)
{
if (p == NULL)
return dataReturn;
find_key(p->left, key_to_be_found, dataReturn);//Left
if(key_to_be_found == p->key) //Visit
{
dataReturn = &p->data;
return;
}
find_key(p->right, key_to_be_found, dataReturn);//Right
}Note: it works for the nodes in the right subtree, but not for the nodes in the left subtree. My guess is that it has to do with it "returning backwards" for the left subtree, thus returning a different "dataReturn" then what I set, as I chose inorder traversal.
Just return at that point, if you want to propagate the result back up.
For instance, if you want to return the first non-float found:
def flatten(arr):
for elem in arr:
if isinstance(elem, collections.Iterable) and not isinstance(elem, (str, bytes)):
res = flatten(elem)
if res is not None: # add this if you want to return the first one
break
else:
if not isinstance(elem, float):
return elem
return res
To stop the for loop, just use a break, the code would be like that:
def flatten(arr):
for elem in arr:
if isinstance(elem, collections.Iterable) and not isinstance(elem, (str, bytes)):
return flatten(elem)
else:
if not isinstance(elem, int):
break
Instead of using break, you could just return the function.
Try
function findCategory(categoryName) {
var trail = [];
var found = false;
function recurse(categoryAry) {
for (var i = 0; i < categoryAry.length; i++) {
trail.push(categoryAry[i].category);
// Found the category!
if ((categoryAry[i].category === categoryName)) {
found = true;
break;
// Did not match...
} else {
// Are there children / sub-categories? YES
if (categoryAry[i].children.length > 0) {
recurse(categoryAry[i].children);
if(found){
break;
}
}
}
trail.pop();
}
}
recurse(catalog);
return trail
}
Demo: Fiddle
the return stmt does work but remember it will be called everytime the loop unwinds and that's not what you are looking at. Example
// global scope
String matchingVariable;
int getMatch(index count, String input, String[] inputs){
if(isValid(input) || count < inputs.length){
// your condition is met and break
// assign your value to global scope variable
matchingVariable = input;
}else if(matchingVariable ==null){
++count
if(count < inputs.length){
getMatch(count, input+inputs[count], inputs)
}
// NOTE RETURN - I WOULDN'T DO THIS
return input;
// doesn't work instead assign the input to global scope variable when a match is found.
}
}
Hey pals,
I am very overwhelmed about this homework i've been working on. Searched the web for solutions but couldn't find anything helpful.
So the goal is to define a function that determines if a number is a happy number (if a number reaches finally to 1, when sum of its squared digits transformed repeatedly, it is a happy number; see below).
>Step 1: Transform 139
>
>1² + 3² + 9² = 1 + 9 + 81 = 91
>
>Step 2: Transform 91
>
>9² + 1² = 81 + 1 = 82
>
>Step 3: Transform 82
>
>8² + 2² = 64 + 4 = 68
>
>Step 4: Transform 68
>
>6² + 8² = 36 + 64 = 100
>
>Step 5: Transform 100
>
>1² + 0² + 0² = 1 + 0 + 0 = 1
>
>The algorithm stops at step 5: 139 is a Happy number
​
-
I have to write this as a recursive function but it keeps going into infinite loops? How can i avoid this?
-
I need to return number of steps required to reach the final result. How can i add this to my code?
Besides, i am a newbie coder so any help and advice about coding in general and about this issue in particular are appreciated.
ps: not a native English speaker.
def digitsOf(num):
digits = []
while num > 0:
rem = num % 10
num = (num - rem)/10
digits.append(int(rem))
return digits
def number_detection(num):
digits = digitsOf(num)
summ = 0
for number in digits:
summ += number**2
result = False
if summ == 1:
result = True
elif summ == num:
result = False
else:
if number_detection(summ) == True:
result = True
return result
def isNumberHappy(num):
if number_detection(num) == True:
print(num,"is a happy number")
elif number_detection(num) == False:
print(num, "is a sad number")The function combo I was looking for is CATCH/THROW. Once again, using the given function:
walk: func [series [block!] criteria [block!]][
use [value] compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
]
]
I can simply wrap it as follows:
catch [walk [a [b c [d e] f] g] [if value = 'e [throw value]]]
; returns 'e
Some Notes
- I want the function to return NONE if there are no matches
I'll just have WALK return NONE (am using ALSO just so as not to leave an awkward trailing none):
walk: func [series [block!] criteria [block!]][
also none use [value] compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
]
]
- red does not have a USE function
This introduces a complication as I only want to bind the block to the word VALUE. If I were to rewrite the function as follows:
walk: func [series [block!] criteria [block!] /local value][
do bind compose/deep [
while [not tail? series][
value: pick series 1
either block? value [
walk value criteria
][
(to paren! criteria)
]
series: next series
]
] 'value
]
Then it also binds that same block to the words SERIES and CRITERIA which would override the binding of any such words from the calling context, e.g.:
walk [some values][series: none probe value] ; results in error
This version avoids binding anything except VALUE and works in Red 0.6.3 and Rebol2:
walk: func [series [block!] criteria [block!]][
also none do bind compose/deep [
while [not tail? series] [
value: pick series 1
either block? value [
walk value criteria
] [
(to paren! criteria)
]
series: next series
]
]
context [value: none]
]
(Comments on how this implementation differs from what USE does would be welcome.)
And yes, this does not work on Rebol3 Alpha. But neither does the one with the USE. I think it's a THROW issue.
You could use exceptions for that - either throw some suitable exception or craft your own and use it. Although using exceptions for flow control is generally not recommended this is the only reliable way here.
In C you can use longjmp/setjmp for this, but I don't think it's safe to use this in C++ (bypasses destructors ?). You'll probably have to use exceptions.
Three changes are needed. First, you need to return something once you solved it:
printf ("%s : %6d\n", s3 , n3);
return 1;
Next, you need to check the return value when you recurse, and stop if you found a solution:
if (solve (v, n, i+1,s1,s2,s3,letters))
return 1;
Last, if you don't find a solution, you need to return 0:
}
return 0;
}
You could use setjmp()/longjmp(). For this you need to:
#include <setjmp.h>
then a global variable:
jmp_buf env;
Then in main (or wherever you call your recursive function) you do:
if(!setjmp(env)) recursiveSolve();
and then when you find the solution:
if(solutionFound) longjmp(env, 1);
and it will return to main like nothing happened - but your solution found.