why does this not work?
It works for False palindrome; however, for anything True it never returns True..
I don't understand why this function does not return True?
And how I should improve this same answer so that it returns True.
My logic was that after the function completes iterating through the entire string, it will return True.
def isPalindrome(string, i = 0):
if i == len(string):
return True
if string[i] != string[len(string)-1-i]:
return False
isPalindrome(string,i+1)
Problem is with your last line:
isPalindrome(string,i+1)
That last line will eventually resolve to either True or False -- but how is that value being returned? (It isn't.)
Try:
return isPalindrome(string,i+1)
Check out the visualization here
My hint would be check what you are returning (i.e. what does isPalindrome return).
If you want just the answer, it is here
Related
I'm wondering how to break out of a recursive loop to the main function. I am trying to do a simple palindrome exercise. The function should return True for "redivider" but the return True is being passed to is_pal() and the function isn't breaking. Short of adding a second variable to is_pal to track True/False, what is the proper way to break out of this recursive loop?
def first(word):
return word[0]
def last(word):
return word[-1]
def middle(word):
return word[1:-1]
def is_pal(str):
if len(str) == 1:
return True
if first(str) == last(str) and len(str) > 1:
is_pal(middle(str))
print is_pal("redivider")
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
def is_pal(str):
if len(str) <= 1:
return True
if first(str) == last(str):
return is_pal(middle(str))
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.
You don't "break" out of recursive functions. Trying to do so says you're thinking about them the wrong way. Currently your recursive call is ignoring the output, which means that the recursion is pointless; whatever is_pal(middle(str)) returns has no effect on the return value of your function.
A recursive algorithm solves the input problem by decomposing the problem into a smaller problem, getting the solution to the smaller problem recursively, and then using the smaller solution to construct a correct solution to the larger problem. You don't "break" out of the inner calls, you return a solution back up one level. You don't know (or need to know) whether you're in an inner call or a top level call. In either case, your function should do the same thing: return True if the argument is a palindrome, and False if it isn't.
The algorithm you're trying to implement is basically this:
If the string is of length 1, it's a palindrome (return True)
Otherwise, if the first character is the same as the last character, then the input is a palindrome if the middle characters are a palindrome.
So what this means is that once you've established the first and last characters are the same, the answer to "is my input a palindrome" is exactly the same as the answer to "are the middle characters a palindrome". You need to return that answer to fulfil your contract. So the recursive call should be return is_pal(middle(str)) rather than just is_pal(middle(str)). If this was a top level call, then that's the answer; if this wasn't a top-level call, then the outer call is going to need this answer to work out the answer to the outer problem (in this case, by simply returning it).
Btw, your algorithm also has some other problems.
You never return False, so the answer can never be False (in this case you happen to accidentally return None by falling off the end of the function if the first and last character don't match, and None will probably do as a stand in for False in most cases, but it's still not really correct).
If the string's length is zero rather than 1 (which will happen if an empty string is passed in or if a palindrome of even length is passed in once all the pairs of equal first and last characters are stripped off), then you don't return the correct answer, and in fact you try to get the first and last character of the empty string, which will cause an exception.
You can exit the program after printing the results using the exit() function.
That may not be a good practice, but it might be what you're looking for.
You're missing a return. Also, don't use str as a variable name. Last thing, the first and last functions could be named slightly better.
def first_letter(word):
return word[0]
def last_letter(word):
return word[-1]
def middle(word):
return word[1:-1]
def is_pal(word):
if len(word) == 1:
return True
if first_letter(word) == last_letter(word) and len(word) > 1:
return is_pal(middle(word))
print is_pal("redivider")
You need to return False in case they don't match and add a return statement. Also you will probably want to check against len(str)==0 and len(str)==1:
def is_pal(str):
if len(str) in [0, 1]:
return True
if first(str) == last(str) and len(str) > 1:
return is_pal(middle(str))
else :
return False
YOU CAN BREAK RECURSION BY RETURNING 1 in 'if' statement before you write your 'function()' 2nd time.
I mean that's what we do to find factorial !! RIGHT? :)
This is what it should return
Returns True if all items are truthy.
Examples:
>>> all_true([1, True, 'oregonstate'])
True
>>> all_true([0, 1, 2])
False
"""
This is what I have written
def all_true(items):
for i in items:
if i == True:
return True
else:
return False
pass
Not sure why it is not working, can someone help?
Your function just returns the truthiness of the first item in the list, since it always returns on the first iteration.
You want to do something like this:
def all_true(items):
for i in items:
if not i:
return False
return True
Note that this all_true function already exists in Python. It is the the built-in all function.
Two problems. First, you are returning on the first True thing. In fact, you are returning either True or False on the first thing, regardless. Since you return on both the if and its else clauses, the loop will always return on the first iteration. A bit more subtle, but if there aren't any values in the list, it will return None.
Second, if you want "truthy", don't compare specifically to True. foo == True is False. Instead, just let the if do the boolean test
def all_true(items):
for i in items:
if not i:
return False
return True
all and any are builtin functions that do the same thing. It would generally be preferable to use them.
"All items are truthy" is logically equivalent to "no items are falsy."
def all_true(items):
for i in items:
if not i:
return False
return True
Because 0 is falsy. Also there's no need to implement your own function for that, use Python's built–in all() function instead!
Hey Stackoverflow community,
I am a python newbie.
So, I am trying to build the function any() from scratch. However the output I get is not what I expected. My code is working fine without the second if statement:
def anys(lst):
for i in range(0,len(lst)):
if bool(lst[i])==True:
return True
anys([False,True,False]) executes True as expected.
However, when I am adding a second if statement I get a different outcome:
def anys(lst):
for i in range(0,len(lst)):
if bool(lst[i])==True:
return True
if bool(lst[i])==False or len(lst)==0:
return False
anys([False,True,False]) executes False.
Can anyone help me what I am doing wrong? Any help would be greatly appreciated.
When you are using a return statement, the function will stop executing and, as instructed, return to the place where the function was called from. This means that the function will return at the first elemt in the list since it was False. If you want the function to return false if all of the elemts are false, I would recomend that you put the return False statement after the for loop.
To clearify, the loop starts with the first elemnt in the list, which in this case is False. The element satisfies the condition:
if bool(lst[i])==False or len(lst)==0:
And the function will then return False.
To answer the comment, if you loop through the entire list, and none of the elements are true (in other words "any"), you then want to return false instead.
def anys(lst):
for i in range(0,len(lst)):
if bool(lst[i])==True:
return True
return False
The code now goes through the list, if it ever encounters a True value, it returns True, however if none of the elements are True, it instead returns False.
The basic answer is that with both conditional return statements, you were always returning on the first iteration and ignoring the rest of the values from the list (or other iterable).
But aside from that, a few other hints that could be useful:
You do not need to loop by index number - just loop over the elements in the list directly.
To test whether an expression (here x) would be True if converted into a boolean, all you need to do is if x:
In the correct form with a single conditional return in the loop, it was returning None if no true values were found and the end of the function was reached. But the builtin any returns False in that situation, so an explicit return False is needed if you want to emulate this behaviour.
def anys(lst):
for x in lst:
if x:
return True
return False
Let us execute your second any() function line by line.
First element of input argument is False.
When you check first if condition, if bool(False) == True, it fails.
It reaches to your second if condition.
if bool(False) == False or len(lst) == 0, bool(False) == False is true hence this if condition is executed and your method returns False.
I'm not getting any error or any results so I can't quite pinpoint the issues.
It's based on the 'stack' data structure.
def is_match(p1, p2):
return (p1,p2) in ['(,)', '{,}', '[,]']
def is_open(param):
return param in '([{'
def is_balanced(exp):
stack = []
for i in range(len(exp)):
if is_open(exp[i]):
stack.append(exp[i])
else:
top = stack.pop()
if not is_match(top,str(exp[i])):
return False
if stack == []:
return True
else:
return False
is_balanced('{[}')
First of all, you are not printing anything. Your function always returns False, but without a print, the result is discarded.
Secondly, you have logic errors. The most obvious one is ('(', ')') is never equal to '(,)'. And if you don't test if the stack is empty as you pop, so in case of input such as '}', you will get an error. And str(exp[i]) is redundant, exp[i] is a string already. Finally,
if condition:
return True
else:
return False
is an antipattern; you can simply say return condition (or, if it is not a boolean and you want it to be, return bool(condition); not needed in this case, as the result of equality comparison is always a boolean).
I apologize for how obvious this answer must be, but I just can't seem to find out why an else statement isn't needed in the following function which returns True -
def boolean():
x = 1
if x == 1:
return True
return False
boolean()
My beginner coding mind is confused why False isn't being returned. The if statement returns True, then outside of that if statement, False is returned. I would've thought to write -
def boolean():
x = 1
if x == 1:
return True
else:
return False
boolean()
Why isn't the else statement needed here? Thank you very much for enlightening me on this.
The execution of a function always ends as soon as a return statement is run. Nothing past that point is even evaluated. For example, if you added a print statement immediately after the return statement, you would not see it printed in the console.
Similarly, the execution of this function never reaches return False because True was already returned.