Palindrome Checker
Learn how to check if a string or number is a palindrome in Python.
Palindrome Checker
Problem
A palindrome is a word, number, or sentence that reads the same forwards and backwards.
Input: "racecar"
Output: True
Input: "hello"
Output: False
Input: "A man a plan a canal Panama"
Output: True (ignoring spaces and case)
Input: 12321
Output: True
Input: 12345
Output: FalseLogic
- Clean the input — remove spaces, convert to lowercase
- Compare the cleaned string with its reverse
- If they match — it is a palindrome
- If they do not — it is not
Flow
Solution 1 — using string slicing
Clean the string, reverse it with [::-1], compare.
def is_palindrome(s):
# convert to string in case a number is passed
s = str(s)
# clean — lowercase and remove spaces
cleaned = s.lower().replace(" ", "")
# reverse the cleaned string
reversed_str = cleaned[::-1]
# compare — if same forwards and backwards it is a palindrome
return cleaned == reversed_str
# strings
print(is_palindrome("racecar")) # True
print(is_palindrome("hello")) # False
print(is_palindrome("A man a plan a canal Panama")) # True
print(is_palindrome("Madam")) # True
# numbers
print(is_palindrome(12321)) # True
print(is_palindrome(12345)) # FalseCode Execution — Solution 1
Trace through is_palindrome("A man a plan a canal Panama"):
| Step | Code | Result |
|---|---|---|
| Convert | str(s) | "A man a plan a canal Panama" |
| Lowercase | .lower() | "a man a plan a canal panama" |
| Remove spaces | .replace(" ", "") | "amanaplanacanalpanama" |
| Reverse | [::-1] | "amanaplanacanalpanama" |
| Compare | cleaned == reversed_str | True |
Trace through is_palindrome("hello"):
| Step | Code | Result |
|---|---|---|
| Convert | str(s) | "hello" |
| Lowercase | .lower() | "hello" |
| Remove spaces | .replace(" ", "") | "hello" |
| Reverse | [::-1] | "olleh" |
| Compare | "hello" == "olleh" | False |
Solution 2 — using a loop with two pointers
Use two pointers — one starting from the left, one from the right. Move them toward each other comparing characters. If any pair does not match — not a palindrome.
def is_palindrome(s):
# convert and clean
s = str(s).lower().replace(" ", "")
# left pointer starts at beginning
left = 0
# right pointer starts at end
right = len(s) - 1
while left < right:
# compare character at left with character at right
if s[left] != s[right]:
return False # mismatch found — not a palindrome
left += 1 # move left pointer forward
right -= 1 # move right pointer backward
# all pairs matched — it is a palindrome
return True
print(is_palindrome("racecar")) # True
print(is_palindrome("hello")) # False
print(is_palindrome("A man a plan a canal Panama")) # True
print(is_palindrome(12321)) # True
print(is_palindrome(12345)) # FalseCode Execution — Solution 2
Trace through is_palindrome("racecar"):
s = "racecar" — length 7, indexes 0 to 6
| Step | left | right | s[left] | s[right] | Match? |
|---|---|---|---|---|---|
| 1st | 0 | 6 | "r" | "r" | Yes |
| 2nd | 1 | 5 | "a" | "a" | Yes |
| 3rd | 2 | 4 | "c" | "c" | Yes |
| 4th | 3 | 3 | left < right is False | — | Stop |
All pairs matched — return True
Trace through is_palindrome("hello"):
s = "hello" — length 5, indexes 0 to 4
| Step | left | right | s[left] | s[right] | Match? |
|---|---|---|---|---|---|
| 1st | 0 | 4 | "h" | "o" | No — return False |
Mismatch on first comparison — immediately returns False.
The two-pointer approach is more efficient than reversing the whole string. It stops as soon as it finds a mismatch — it does not need to finish checking all pairs. For very long strings this matters.
Solution 3 — using recursion
Check the first and last characters. If they match, check the remaining middle string recursively.
def is_palindrome(s):
# clean only on first call — convert and strip spaces
s = str(s).lower().replace(" ", "")
def check(s):
# base case — empty string or single character is always a palindrome
if len(s) <= 1:
return True
# if first and last characters do not match — not a palindrome
if s[0] != s[-1]:
return False
# check the middle part — remove first and last characters
return check(s[1:-1])
return check(s)
print(is_palindrome("racecar")) # True
print(is_palindrome("hello")) # False
print(is_palindrome("A man a plan a canal Panama")) # True
print(is_palindrome(12321)) # TrueCode Execution — Solution 3
Trace through is_palindrome("racecar"):
check("racecar")
s[0]="r", s[-1]="r" → match
→ check("aceca")
s[0]="a", s[-1]="a" → match
→ check("cec")
s[0]="c", s[-1]="c" → match
→ check("e")
len("e") <= 1 → True ✅
return True
return True
return True
return TrueTrace through is_palindrome("hello"):
check("hello")
s[0]="h", s[-1]="o" → mismatch
return False ✅Solution 4 — handling punctuation too
A more complete version — strips spaces, punctuation, and handles case. Useful for real sentences.
import re
def is_palindrome(s):
# convert to string
s = str(s)
# remove everything except letters and numbers
# re.sub replaces all non-alphanumeric characters with ""
cleaned = re.sub(r"[^a-zA-Z0-9]", "", s).lower()
# compare with its reverse
return cleaned == cleaned[::-1]
print(is_palindrome("racecar")) # True
print(is_palindrome("A man, a plan, a canal: Panama")) # True
print(is_palindrome("Was it a car or a cat I saw?")) # True
print(is_palindrome("hello")) # False
print(is_palindrome(12321)) # TrueCode Execution — Solution 4
Trace through is_palindrome("A man, a plan, a canal: Panama"):
| Step | Code | Result |
|---|---|---|
| Input | s | "A man, a plan, a canal: Panama" |
| Remove non-alphanumeric | re.sub(...) | "AmanaplanacanalpanaMa" |
| Lowercase | .lower() | "amanaplanacanalpanama" |
| Reverse | [::-1] | "amanaplanacanalpanama" |
| Compare | cleaned == reversed | True |
re.sub(r"[^a-zA-Z0-9]", "", s) means — replace any character that is NOT a letter or digit with an empty string. The ^ inside [] means NOT. This handles commas, periods, colons, exclamation marks — anything that is not part of the actual word.
Which solution to use?
| Solution | How | Best when |
|---|---|---|
| Solution 1 | [::-1] slicing | Clean and readable — most common |
| Solution 2 | Two pointers | Efficient — stops early on mismatch |
| Solution 3 | Recursion | Understanding recursive thinking |
| Solution 4 | Regex cleaning | Real sentences with punctuation |
Output
True
False
True
True
True
False