Testing for a Palindrome in Python - python

I now know there are better solutions for this, but I'm confused as to why I'm getting the result I am.
import sys
def isPalindrome(test):
if len(test) == 1:
return("Is a palindrome")
else:
if test[0] == test[-1]:
isPalindrome(test[1:-1])
else:
return("Not a palindrome")
print(isPalindrome(sys.argv[1]))
On a true palindrome, I get 'None'. When the result is not a palindrome, I get the expected value of 'Not a palindrome'.

Change to the following line:
return isPalindrome(test[1:-1])
You have to return a value or the value returned is None.

Another suggestion
def isPalindrome (test):
if test[0] != test[-1]: return ("It is NOT a Palindrome")
if len(test) == 1: return ("It is a Palindrome")
else:return test[0] == test[-1] and isPalindrome(test[1:-1])

Your issue: the 7th line should be:
return isPalindrome(test[1:-1])
Without return, you call the function, and return None.
Also, as mentioned in other posts, you have an issue with even strings, so add the condition for len(test)==0.

There is no return path in the if --> True situation. When you return out of the recursion you only return "Is a palindrome" to the level about it, but beyond that you are returning a Null string to the main function.
You have not accounted for when the recursion becomes an empty string. So the condition test[0] == test[-1] gives a *** IndexError: string index out of range
This works:
def isPalindrome(test):
if (len(test) == 1 or len(test)==0):
return("Is a palindrome")
else:
print test[0] == test[-1]
if test[0] == test[-1]:
return isPalindrome(test[1:-1])
else:
print('Not')
return("Not a palindrome")
print(isPalindrome("aa"))

Related

Check for a palindrome in python

palindrome
Here is the code i have written so far:
string=input(("Enter a string:"))
for char in string:
print(char)
if(string==string[::-1]):
print("The string is a palindrome")
else:
print("Not a palindrome")
To produce the described output, it looks like you'd need to perform character-wise comparison. What you've attempted is a straight-forward comparison of a string with it's reverse. Try this:
string=input(("Enter a string:"))
rev_string = string[::-1]
for i in range(len(string)):
print (string[i], "--", rev_string[i])
if string[i].lower() != rev_string[i].lower():
print("Not a palindrome")
exit(0)
print("The string is a palindrome")
I would like to point out that checking if two characters are the same is not trivial, as discussed in this answer. The following code should work for any character:
import unicodedata
def normalize_caseless(text):
return unicodedata.normalize("NFKD", text.casefold())
def caseless_equal(left, right):
return normalize_caseless(left) == normalize_caseless(right)
string = input("Enter a string: ")
rev_string = string[::-1]
i = 0
palindrome = True
while palindrome and i < len(string):
print(f'{string[i]} -- {rev_string[i]}')
palindrome = caseless_equal(string[i], rev_string[i])
i += 1
print(f"The string is{' not'*(not palindrome)} a palindrome")

Keep encountering "string index out of range' error in Python

I'm doing an assignment for an intro course in which I need to determine whether a string is a palindrome. Having trouble with this segment of the code:
def is_palindrome(letters):
if (len(letters))==0:
return True
elif len(letters)==1:
return True
elif (letters[end])==(letters[0]):
return is_palindrome(letters[(letters[0+1]):(letters[len(letters)-1])])
else:
return False
Your code is nearly correct, but you have errors in the slicing of the strings:
def is_palindrome(letters):
if (len(letters))==0:
return True
elif len(letters)==1:
return True
elif (letters[0])==(letters[-1]): # index [-1] gives the last letter
return is_palindrome(letters[1:-1]) # slice [1:-1] is the word without the first and last letter.
else:
return False
The above works.
I suggest you review this post that explains in details how slicing works: Explain Python's slice notation
Try these following codes:
def palindrome(text):
if text == text[::-1]:
print(text, 'is palindrome')
else:
print(text, 'is not palindrome')
palindrome('reser')
palindrome('reset')
str[::-1] will reverse the string. for more info, try help(slice).

Why doesn't my python algorithm for checking palindromes work?

So I was doing exercise 6 from chapter 7 from Think Python and it stroke me as odd that this piece of code I wrote as a solution didn't work:
def is_palindrome(word):
if len(word) <= 1:
return True
elif first(word) == last(word):
is_palindrome(middle(word))
else:
return False
It doesn't enter any recursion and I don't know why. It returns None for words longer than 1 character of length. Why is this? When the length of the word reaches 1 or less it should return True!
Why doesn't it work?
PS: Here are first, last and middle deffinitions:
def first(word):
return word[0]
def last(word):
return word[-1]
def middle(word):
return word[1:-1]
You're missing a return:
def is_palindrome(word):
if len(word) <= 1:
return True
elif first(word) == last(word):
return is_palindrome(middle(word)) # <--
else:
return False
So your current snippet is returning None once the elif block is entered, since you don't have an explicit return statement there. In other words, you do compute is_palindrome(middle(word)), but you do nothing with the result.
Maybe working through a simple example would help. Consider calling the original function with an argument of 'aba':
function called
word is now 'aba'
len(word) <= 1 is False, if-body not entered.
first(word) == last(word) is True, elif-body entered:
function called recursively:
word is now 'b'
len(word) <= 1 is True, if-body entered:
True returned
Return value of recursive call discarded (since we have no return in elif)
None returned
Add return
return is_palindrome(middle(word))
I think you are missing to return the method in 5th line of your function.
return is_palindrome(middle(word))
should be there instead of
is_palindrome(middle(word))

Improving Python Palindrome code

So I recently implemented a code that checks a word to see if it's a palindrome.
def isPalindrome():
string = input('Enter a string: ')
string1 = string[::-1]
if string[0] == string[(len(string)-1)] and string[1:(len(string)-2)] == string1[1:(len(string)-2)]:
print('It is a palindrome')
else:
print('It is not a palindrome')
isPalindrome()
I was wondering if anyone could give me tips on simplifying the code.
Edit - If I were to make the function an iterative function with the statements string == string1, how would I stop the endless while loop? Would I need a count to stop the while loop?
No need for such complex conditional. You already have a reversed string (string[::-1]).
All you need to do is this:
def isPalindrome():
string1 = input('Enter a string: ')
string2 = string1[::-1]
if string1 == string2:
return 'It is a palindrome'
return 'It is not a palindrome'
isPalindrome()
(by the way don't use string as a variable name. That's the name of a built-in module)
It's better to return the strings instead of printing them. That way your function will not return None (preventing some stuff that could happen later)
You can do it in a one liner:
return "Is a palindrome" if string == string[::-1] else "Not a palindrome"
Sample script:
>>> string = "stanleyyelnats"
>>> print "Is a Palindrome" if string == string[::-1] else "Not a palindrome"
>>> Is a Palindrome
You can also do this (although its slower):
print "Is a Palindrome" if string == ''.join(reversed(string)) else "Not a palindrome"
Also, use raw_input and not input. Because input will be evaluated. Let me show you an example:
Script
inp = input("Evaluate ")
print inp
Run
Evaluate "cheese" + "cake"
cheesecake
Here is a simple solution in just 1 LINE.
plandrom = lambda string: True if string == string[::-1] else False
Please check this algorithm,
def is_palindrome(n):
m = len(n)/2
for i in range(m):
j = i + 1
if n[i] != n[-j]:
return False
return True
print is_palindrome('malayayalam')
So, I just got into learning python and I have been trying to these exercises, #8. Though I see that a lot of these answers are creating a new reverse string(which adds a memory overhead) and comparing both strings, I thought I could utilize lesser memory by doing this:
def is_palindrome(s):
l=len(s)
list_s=list(s)
for i in range(0,l):
if(list_s[i] !=list_s[l-i-1]):
return False
else:
return True
You can use a print statement to verify.
All I am doing is comparing the first index to the last and the second index to the second last and so on.
Hope that helps.
Check Counter from collections
from collections import Counter
def is_palindrome(letters):
return len([v for v in Counter(letters).values() if v % 2]) <= 1
Here is another solution I came up with:
###Piece of code to find the palindrome####
def palindrome():
Palindromee = input("Enter the palindrome \t:")
index = 0
length = len(Palindromee)
while index < length:
if Palindromee[0] == Palindromee[-1] :
index +=1
print ("Palindrome worked as expected")
palindrome()
Simple way to write palindrome
a=raw_input("Enter the string : ") # Ask user input
b= list(a) # convert the input into a list
print list(a)
b.reverse() # reverse function to reverse the
# elements of a list
print b
if list(a) == b: # comparing the list of input with b
print("It is a palindrome")
else:
print("It is not a palindrome")
we could use reverse String function to verify Palindrome:
def palindrome(s):
str=s[::-1]
if s==str:
return True
else:
return False
palindrome('madam')
you can as well try this
def palindrome(str1):
return str1==str1[::-1]
print(palindrome(str1)
the answer above returns a boolean according to the string given
if it is a palindrome prints true else false

Where's the bug in this function to check for palindrome?

Given below is the code to check if a list is a palindrome or not. It is giving correct output for 983. Where am I going wrong?
def palindrome(num):
flag=0
r=num[::-1]
for i in range (0, len(num)-1):
if(r[i]==num[i]):
flag=1
else:
flag=0
return flag
You should return as soon as there is a mismatch. Also, you just need to iterate till half the length:
def function(...):
...
for i in range (0, (len(num) + 1) / 2):
if r[i] != num[i]:
return False
return True
BTW, you don't need that loop. You can simply do:
def palindrome(num):
return num == num[::-1]
This would be easier:
def palindrome(num):
if num[::-1] == num:
return True
else:
return False
Your for loop checks all pairs of characters, no matter if it found mismatch or not. So, in case of string '38113' it will return True, because the flag variable will be set to True after the check for equality of last digit in '38113' and its reversed version '31183' (both equal to 3, while the string isn't a palindrome).
So, you need to return False right after you've found mismatch; if you checked all the characters and didn't find it - then return True, like so:
def palindrome(num):
r = num[::-1]
for i in range (0, len(num)-1):
if(r[i] != num[i]):
return False
return True
Also, as someone pointed out it'll be better to use python's slices - check out the documentation.
Just for the record, and for the ones looking for a more algorithmic way to validate if a given string is palindrome, two ways to achieve the same (using while and for loops):
def is_palindrome(word):
letters = list(word)
is_palindrome = True
i = 0
while len(letters) > 0 and is_palindrome:
if letters[0] != letters[-1]:
is_palindrome = False
else:
letters.pop(0)
if len(letters) > 0:
letters.pop(-1)
return is_palindrome
And....the second one:
def is_palindrome(word):
letters = list(word)
is_palindrome = True
for letter in letters:
if letter == letters[-1]:
letters.pop(-1)
else:
is_palindrome = False
break
return is_palindrome
str1=str(input('enter string:'))
save=str1
revstr=str1[::-1]
if save==revstr:
print("string is pailandrom")
else:
print("not pailadrom")
# We are taking input from the user.
# Then in the function we are reversing the input i.e a using
# slice [::-1] and
# storing in b
# It is palindrome if both a and b are same.
a = raw_input("Enter to check palindrome:")
def palin():
#Extended Slices to reverse order.
b = a[::-1]
if a == b:
print "%s is palindrome" %a
else:
print "%s is not palindrome" %a
palin()
this would be much easier:
def palindrome(num):
a=num[::-1]
if num==a:
print (num,"is palindrome")
else:
print (num,"is not palindrome")
x=input("Enter to check palindrome:")
palindrome(x)
Here in my opinion is the most elegant:
def is_palindrome(s):
if s != '':
if s[0] != s[-1]:
return False
return is_palindrome(s[1:-1])
return True
it's also the same code in the is_palindrome() function:
pip install is-palindrome
>>> from is_palindrome import is_palindrome
>>> x = "sitonapanotis"
>>> y = is_palindrome(x)
>>> y
True
Take care to note the hyphen vs underscore when installing vs. importing
a="mom"
b='mom'[::-1] # reverse the string
if a==b: # if original string equals to reversed
print ("palindrome ")
else:
print ("not a palindrome ")
def palindrome(a):
a=raw_input('Enter :')
b=a[::-1]
return a==b

Categories