Python Program to Check if a String Is a Palindrome
Beginner Strings
Checks whether a word or sentence reads the same backwards as forwards, ignoring capitals, spaces and punctuation.
A palindrome reads the same backwards as forwards: "level", "racecar" and "Madam" are palindromes. For a sentence, the
usual rule is to ignore capitals, spaces and punctuation, so "Never odd or even" is one too: in lower case and without
its spaces it's neveroddoreven, which is the same backwards.
Program
def is_palindrome(text):
"""True if text is a palindrome, ignoring case and symbols."""
# Keep only the letters and digits, in lower case
cleaned = ""
for char in text:
if char.isalnum():
cleaned += char.lower()
return cleaned == cleaned[::-1]
print("Madam:", is_palindrome("Madam"))
print("Never odd or even:", is_palindrome("Never odd or even"))
print("Python:", is_palindrome("Python"))
Open in the editor Download palindrome_string.py
Output
Madam: True
Never odd or even: True
Python: False
How it works
Step through the program line by line: each step below shows up as its line runs.
-
cleanedstarts as an empty string. It will hold the text with only the characters that count. - The loop goes through the text one character at a time.
isalnum()is true only for letters and digits, so spaces and punctuation are skipped. Each character kept is added in lower case, soMandmcount as the same letter. -
cleaned[::-1]iscleanedbackwards (strings). The text is a palindrome when the two are equal. - The program checks a word, a sentence, and a word that isn't a palindrome.
| Text | cleaned |
cleaned[::-1] |
Palindrome? |
|---|---|---|---|
Madam |
madam |
madam |
True |
Never odd or even |
neveroddoreven |
neveroddoreven |
True |
Python |
python |
nohtyp |
False |
Without the cleaning, "Madam" would fail: backwards it's "madaM", and to Python M and m are different characters.
Other ways to write it
With a list comprehension
A list comprehension keeps the same characters in one line. Lists reverse and compare like strings, so there's no need to join the characters back together.
def is_palindrome(text):
kept = [char.lower() for char in text if char.isalnum()]
return kept == kept[::-1]
print(is_palindrome("Was it a car or a cat I saw?"))With two indexes
This version makes no copy of the text. left starts at the first character and right at the last, and they move
towards each other, skipping anything that isn't a letter or digit. One pair that doesn't match is enough to return
False.
def is_palindrome(text):
left, right = 0, len(text) - 1
while left < right:
if not text[left].isalnum():
left += 1
elif not text[right].isalnum():
right -= 1
elif text[left].lower() != text[right].lower():
return False
else:
left += 1
right -= 1
return True
print(is_palindrome("A man, a plan, a canal: Panama!"))Try it yourself
- Check "Step on no pets" and "No lemon, no melon", which are palindromes, and a sentence of your own.
- Check numbers and dates as text: "12321" is a palindrome, and so is "02/02/2020" once the slashes are skipped.
- Take out
.lower()and run it again: "Madam" is no longer a palindrome. - Print
cleanedbefore the comparison, to see exactly what is compared.