Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Palindrome Test
#1
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!')
Reply
#2
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).
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#3
You could use IndexAccess on strings.

word.lower() == word.lower()[::-1]
Just make the word lowercase, before you compare them.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#4
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]))
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#5
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.
Almost dead, but too lazy to die: https://sourceserver.info
All humans together. We don't need politicians!
Reply
#6
(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.
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#7
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]))
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020