Python Forum

Full Version: Palindrome Test
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
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]))