Your problem is on this line:
if word_check == word_check.reverse():
You're expecting word_check.reverse()
to return the reverse of word_check
, but in fact it reverses the parts of word_check
in place (i.e. it changes word_check
itself, without creating something new). And once it's done, it returns None
.
Two ways of doing what you expected:
if word_check == list(reversed(word_check)):
(Note: the list()
is needed here to take what reversed()
returns and turn it back into a list. After all, word_check
is a list, not a reversed
type object that allows you to iterate over the data in reverse)
Or:
if word_check == word_check[::-1]
In this case, either is fine. The first example could deal with any object that implements a __reversed__()
method, or that supports Python's sequence protocol. You could define your own class that has a concept of being 'reversed' and allows comparison with itself, and this logic would remain the same.
The second example only works for objects that allow indexing with a slice. But a list (or a string) does, so it works here.
The first part of your code effectively does the same as this:
word = input("Input a word: ")
word_check = list(word)
After this, if you enter test
, word_check == ['t', 'e', 's', 't']
.
But you don't even need to do that with the second solution, so:
# the simplest solution:
word = input("Input a word: ")
if word == word[::-1]:
print("The word is a palindrome")
else:
print("The word is not a palindrome")
# if you do actually want to use a list for some reason:
word_check = list(word)
if word_check == list(reversed(word_check)):
print("Yep, definitely a palindrome")
else:
print("Nope, definitely not a palindrome")
Here, word
itself (the string) is reversed with word[::-1]
- since you can index a string with a slice, this works and the resulting string is the same string with its characters in reverse order. So:
word = 'abcd'
print(word[::-1]) # prints `dcba`
A good explanation of slicing is here: Understanding slicing
In case anyone is wondering how the methods compare in performance:
from timeit import timeit
def is_palindrome0(s):
# simple slice
return s == s[::-1]
def is_palindrome1(s):
# reassemble a string from the result of reversed
return s == "".join(reversed(s))
def is_palindrome2(s):
# assemble a list from the result of reversed, compare to the list of s
return list(s) == list(reversed(s))
def is_palindrome3(s):
# as the previous, but tuples instead
return tuple(s) == tuple(reversed(s))
print(timeit(lambda: is_palindrome0('abcdedbcaabcdedbca'), number=10000000))
print(timeit(lambda: is_palindrome1('abcdedbcaabcdedbca'), number=10000000))
print(timeit(lambda: is_palindrome2('abcdedbcaabcdedbca'), number=10000000))
print(timeit(lambda: is_palindrome3('abcdedbcaabcdedbca'), number=10000000))
Result (on my machine):
1.6170584000001327
4.881220600000233
5.382383899999695
5.094953499999974