Keep encountering "string index out of range' error in Python - 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).

Related

I have tried two methods to make a palindrome check that uses input but neither work. [Python]

I am trying to make a script that checks if input is a palindrome or not. I'm confused as to why neither of them work. In the first attempt, I printed reversed_phrase but it printed <list_reverseiterator object at 0x000001DDD1E27D60>. In the second attempt, I printed phrase[i] and reverse_phrase[i] in each iteration and they printed the same thing.
First Attempt:
original_phrase = input()
phrase = list(original_phrase)
reversed_phrase = reversed(phrase)
if phrase == reversed_phrase:
print(original_phrase, 'is a palindrome')
else:
print(original_phrase, 'is not a palindrome')
Second Attempt:
original_input= input()
phrase = list(original_input)
reversed_phrase = phrase
reversed_phrase.reverse()
is_palindrome = False
for i in range(0, len(phrase)):
print(phrase[i], reversed_phrase[i])
if phrase[i] != reversed_phrase[i]:
break
elif i >= len(phrase) - 1:
is_palindrome = True
if is_palindrome:
print(original_input, 'is a palindrome')
else:
print(original_input, 'is not a palindrome')
Your first solution is misusing the reversed(array) function as it returns a pointer to the end of the array so that you can iterate through it in reverse. What you want here is to actually reverse the array which is done with array.reverse();
Your second solution incorrectly always returns true because when you do this: reversed_phrase = phrase both reversed_phrase and phrase reference the same object, so any changes made to one appear when referencing either. What you want to do is reversed_phrase = phrase.copy() so that they are each individual versions of the array

Testing for a Palindrome in 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"))

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

Python reverse() for palindromes

I'm just getting started in python, and I'm trying to test a user-entered string as a palindrome. My code is:
x=input('Please insert a word')
y=reversed(x)
if x==y:
print('Is a palindrome')
else:
print('Is not a palindrome')
This always returns false because y becomes something like <reversed object at 0x00E16EF0> instead of the reversed string.
What am I being ignorant about? How would you go about coding this problem?
Try y = x[::-1]. This uses splicing to get the reverse of the string.
reversed(x) returns an iterator for looping over the characters in the string in reverse order, not a string you can directly compare to x.
reversed returns an iterator, which you can make into a string using the join method:
y = ''.join(reversed(x))
For future reference, a lambda from the answers above for quick palindrome check:
isPali = lambda num: str(num) == str(num)[::-1]
example use:
isPali(9009) #returns True
Try this code.
def pal(name):
sto_1 = []
for i in name:
sto_1.append(i)
sto_2 = []
for i in sto_1[::-1]:
sto_2.append(i)
for i in range(len(name)):
if sto_1[i] == sto_2[i]:
return "".join(sto_1), "".join(sto_2)
else:
return "no luck"
name = raw_input("Enter the word :")
print pal(name)
list(reverse( mystring )) == list( mystring )
or in the case of numbers
list(reverse( str(mystring) )) == list( str(mystring) )
Try this code:
def palindrome(string):
i = 0
while i < len(string):
if string[i] != string[(len(string) - 1) - i]:
return False
i += 1
return True
print palindrome("hannah")
Try this code to find whether original & reverse are same or not:-
if a == a[::-1]:
#this will reverse the given string, eventually will give you idea if the given string is palindrome or not.

Categories