I am trying to learn while loops.
To practice, I created a simple while loop with an If statement inside a function to check and see if a word is a palindrome. For some reason, even if the word is not a palindrome, it keeps returning True.
I expected the output of the print function on the last line to be False:
from collections import deque
word = "tacrocat"
def check_palindrome(word):
d = deque(word)
while len(d) > 1:
if d.pop() == d.popleft():
return True
return False
print(check_palindrome(word))
NOTE: When I change the if statement evaluation to "!=", change the return statement inside the if statement to False, and change the return statement in the while loop to True, it seems to accurately detect palindromes - but I have no idea why.
CodePudding user response:
Once it finds a return True
it will come out of the function.
In the first iteration it will compare t
with t
and exit the function.
In your case it comes out at first letter.
rather you can do as stated by @Goodies in comment
from collections import deque
word = "tacrocat"
def check_palindrome(word):
d = deque(word)
while len(d) > 1:
if d.pop() != d.popleft():
return False
return True
print(check_palindrome(word))
CodePudding user response:
This is happening because it is returning True
if any one of the characters on either side of centre are equal. This is probably confusing but basically it checks if any of the letters are mirrored not all of them because the return True
exits early.
This means that, actually, your function does not always return True
, for example a word like "word" would return false.
To fix this, rather than return True
when one match is found and otherwise return False
, you could return False
if any do not match and else return True
like so (see comment above by @Goodies):
from collections import deque
word = "tacrocat"
def check_palindrome(word):
d = deque(word)
while len(d) > 1:
if d.pop() != d.popleft():
return False
return True
print(check_palindrome(word))
which (correctly) outputs:
False
CodePudding user response:
If the program is written like this:
from collections import deque
word = "tacrocat"
def check_palindrome(word):
d = deque(word)
while len(d) > 1:
if d.pop() == d.popleft():
return True
return False
print(check_palindrome(word))
At iteration-1:
Since both the first character('t') and last character('t') in the deque are equal it will enter the if condition and return True. When a return statement is executed in a function, then the control comes out of the function. In other words, as soon as return True statement is executed, the control comes back to print statement without executing remaining iterations of while loop and since we returned True, so True will be printed as output.
Let's analyze second program:
from collections import deque
word = "tacrocat"
def check_palindrome(word):
d = deque(word)
while len(d) > 1:
if d.pop() != d.popleft():
return False
return True
print(check_palindrome(word))
At iteration-1:
Current deque: [t,a,c,r,o,c,a,t]
We are popping both first element and last element and checking whether they are not equal in if condition. Since 't' and 't' are equal, if condition will not execute and while loop will continue.
At iteration-2:
Current deque: [a,c,r,o,c,a]
Since 'a' and 'a' are equal, if condition will not execute and while loop will continue. Both first and last elements are popped (pop and popleft)
At iteration-3:
Current deque: [c,r,o,c]
Since 'c' and 'c' are equal, if condition will not execute and while loop will continue. Both first and last elements are popped (pop and popleft)
At iteration-4:
Current deque: [r,o]
Since 'r' and 'o' are not equal, if condition will execute and return False statement is executed. So, the function check_palindrome will terminate with return value as False and so we get output as False.
The second program is correct because to check if a word is palindrome or not, we need to check all letters whether they are satisfying the condition or not. Just checking only the first and last character of a word and if they are equal, then it doesn't mean the remaining letters are same. We need to check them too.