A little program to test if a word or phrase is a palindrome.
word = input('Enter a word or phrase. ')
letters = filter(str.strip, list(word))
test = list(reversed(word))
letter_test = filter(str.strip, test)
if list(letter_test) == list(letters):
print(f'{word} is a palindrome!')
else:
print(f'{word} is not a palindrome!')
Observation: this code fails on words/sentences which are considered palindromes: those which start with capital letters (Never odd or even) or containing punctuation and word dividers (Madam, I'm Adam).
You could use IndexAccess on strings.
word.lower() == word.lower()[::-1]
Just make the word lowercase, before you compare them.
Another way is to write function with short-circuit i.e if first non-match encountered then False is returned. Text cleaning must be performed, this is somewhat easier with built-in tools if you need to test only in english; for other languages one could define allowed letters manually (or exclude punctuation).
One way of accomplishing it (it will ignore non-ascii characters, depending on use-case it may be a problem, using 'if letter not in string.punctuation' might be an alternative):
>>> import string
>>> def palindrome_check(text):
... cleaned = [letter.lower() for letter in text if letter in string.ascii_letters]
... for forward, backward in zip(cleaned, cleaned[::-1]):
... if forward != backward:
... return False
... return True
Of course, there is built-in function all() exactly for that purpose:
>>> import string
>>> def palindrome_check(text):
... cleaned = [letter.lower() for letter in text if letter in string.ascii_letters]
... return all(forward == backward for forward, backward in zip(cleaned, cleaned[::-1]))
If you are trying to save memory with palindrome_check
, you should use reversed
instead the use of index access. The index access creates a new list in memory. The reversed object is evaluated lazy.
But this is not important for words. With very long text, this can make sense.
(Mar-04-2019, 12:29 PM)DeaD_EyE Wrote: [ -> ]If you are trying to save memory with palindrome_check
, you should use reversed
instead the use of index access. The index access creates a new list in memory. The reversed object is evaluated lazy.
You are absolutely right.
Here's a recursive solution that almost gave me an aneurysm:
#! /usr/bin/python3
from sys import argv, exit
def is_palindrome(s):
if s != '':
if s[0] != s[-1]:
return False
return is_palindrome(s[1:-1])
return True
if __name__ == "__main__":
if len(argv) < 2:
print("Enter a word as an argument")
exit()
print(is_palindrome(argv[1]))