How to write a palindrome program in Python
Discover how to write a palindrome program in Python. This guide covers various methods, practical applications, and debugging techniques.

A palindrome is a word or phrase that reads the same forwards and backward. A program to check for palindromes is a classic Python exercise that sharpens your logic skills.
Here, you'll discover different techniques to write a palindrome checker. You'll also find practical tips, real-world applications, and advice to debug your code, helping you master this common programming challenge.
Using string reversal to check for palindromes
def is_palindrome(text):
return text == text[::-1]
print(is_palindrome("racecar"))
print(is_palindrome("hello"))--OUTPUT--True
False
This approach is one of the most Pythonic ways to check for a palindrome. It's elegant because it packs the entire logic into a single line within the is_palindrome function. The magic lies in Python's extended slice syntax.
The expression text[::-1] creates a reversed copy of the input string. This slice notation leaves the start and end indices blank, which selects the entire string by default. The third parameter, the step, is set to -1, instructing Python to step through the string backward. The function then compares the original string to its reversed version using the == operator, returning True if they match.
Basic palindrome checking techniques
If the slicing trick feels a bit like magic, exploring these foundational methods will help you build a palindrome checker from the ground up.
Using a while loop to compare characters
def is_palindrome(text):
left, right = 0, len(text) - 1
while left < right:
if text[left] != text[right]:
return False
left += 1
right -= 1
return True
print(is_palindrome("level"))
print(is_palindrome("python"))--OUTPUT--True
False
This iterative approach uses two pointers, left and right, to check characters from opposite ends of the string. The while loop continues as long as the pointers haven't crossed, comparing one pair of characters at a time as it moves inward.
- If the characters at the
leftandrightpositions don't match, the function immediately returnsFalse. - If they do match, the pointers move one step closer to the center of the string.
- The function returns
Trueonly if the loop finishes without finding any mismatches.
Using recursion to check palindromes
def is_palindrome(text):
if len(text) <= 1:
return True
if text[0] != text[-1]:
return False
return is_palindrome(text[1:-1])
print(is_palindrome("madam"))
print(is_palindrome("coding"))--OUTPUT--True
False
This recursive solution breaks the problem into smaller, identical subproblems. The function keeps calling itself until it reaches a base case—a string with one or zero characters, which is always a palindrome.
- First, it checks if the outermost characters,
text[0]andtext[-1], match. If they don't, the function immediately returnsFalse. - If they do match, the function calls itself with the string's inner slice,
text[1:-1], effectively peeling away the outer layer and repeating the process on the smaller string.
Using the reversed() function
def is_palindrome(text):
reversed_text = ''.join(reversed(text))
return text == reversed_text
print(is_palindrome("radar"))
print(is_palindrome("algorithm"))--OUTPUT--True
False
This method offers another clear way to check for a palindrome. It leverages Python's built-in reversed() function, which efficiently creates a reverse iterator from the input string.
- Unlike slicing,
reversed()doesn't immediately create a new string. Instead, you use the''.join()method to piece the characters from the iterator together into a new, reversed string. - The function then compares this new string to the original to see if they match.
Advanced palindrome techniques
Building on these foundational methods, you can now write more robust checkers that handle real-world text and even work with numbers.
Ignoring case, spaces, and punctuation
import re
def is_palindrome(text):
# Remove non-alphanumeric characters and convert to lowercase
cleaned_text = re.sub(r'[^a-zA-Z0-9]', '', text.lower())
return cleaned_text == cleaned_text[::-1]
print(is_palindrome("A man, a plan, a canal: Panama"))
print(is_palindrome("No 'x' in Nixon"))--OUTPUT--True
True
This function makes your palindrome checker more robust by sanitizing the input first. It handles phrases that include capitalization, spaces, and punctuation, which would otherwise fail a simple comparison.
- The
text.lower()method converts the entire string to lowercase, making the check case-insensitive. - Next,
re.sub(r'[^a-zA-Z0-9]', '', ...)uses a regular expression to remove any character that isn't a letter or number.
Once the text is cleaned, the function can accurately check if the resulting alphanumeric string is a palindrome.
Checking if a number is a palindrome
def is_palindrome_number(num):
return str(num) == str(num)[::-1]
print(is_palindrome_number(12321))
print(is_palindrome_number(12345))
print(is_palindrome_number(123454321))--OUTPUT--True
False
True
This function cleverly checks if a number is a palindrome by first converting it into a string. Since you can't directly reverse an integer, this approach lets you reuse the same string manipulation techniques you've already seen.
- The
str(num)function converts the input number into its string representation. - Then, it compares the string to its reversed version using the slice notation
[::-1].
This makes the logic concise and easy to read, as it boils down to a simple string comparison.
Using filter() and lambda for custom palindrome checks
def is_palindrome(text, ignore_chars=' ,.!?:;-_'):
filtered_text = ''.join(filter(lambda c: c not in ignore_chars, text.lower()))
return filtered_text == filtered_text[::-1]
print(is_palindrome("Was it a car or a cat I saw?"))
print(is_palindrome("No lemon, no melon"))--OUTPUT--True
True
This method gives you a more customizable way to clean text. It combines filter() with a lambda function to selectively build the string for comparison.
- The
filter()function processes the lowercase text. - A
lambdafunction provides the logic, tellingfilter()to keep only characters that aren't found in theignore_charsstring. - Finally,
''.join()assembles the kept characters into a new string.
This approach is highly flexible, as you can easily pass a custom string to the ignore_chars parameter.
Move faster with Replit
Replit is an AI-powered development platform that transforms natural language into working applications. Describe what you want to build, and Replit Agent creates it—complete with databases, APIs, and deployment.
For the palindrome-checking techniques you've learned, Replit Agent can turn them into production-ready tools:
- Build a text analysis utility that finds and highlights palindromic phrases in documents, using the advanced filtering methods covered in this article.
- Create a word puzzle game where players must form the longest possible palindrome from a given set of letters.
- Deploy a bioinformatics tool that identifies palindromic DNA sequences, a crucial function in genetic analysis.
Describe your app idea, and Replit Agent will write the code, test it, and fix issues automatically, all within your browser.
Common errors and challenges
When writing your palindrome checker, you might encounter a few common pitfalls that can trip you up.
- Forgetting to handle case sensitivity. A frequent oversight is forgetting to handle case sensitivity. A simple check will treat "Madam" and "madam" as different strings because the uppercase 'M' doesn't match the lowercase 'm'. Your
is_palindrome()function will returnFalseincorrectly unless you convert the input to a consistent case before comparing. - Handling special characters and spaces. Similarly, real-world palindromes often contain spaces and punctuation. A phrase like "Was it a car or a cat I saw?" will fail a direct character-by-character comparison. For a truly robust checker, you need to filter out these non-alphanumeric characters before you check for symmetry.
- Missing the base case in recursion. If you're using recursion, forgetting the base case is a classic mistake. The base case—in this scenario, a string with one or zero characters—is the condition that stops the function from calling itself. Without it, your recursive
is_palindrome()function will enter an infinite loop, eventually causing aRecursionErroras it exceeds the maximum call stack depth.
Forgetting to handle case sensitivity in is_palindrome()
A common slip-up is forgetting that Python's string comparison is case-sensitive. This means your is_palindrome() function will incorrectly fail on a word like "Radar" because the uppercase 'R' doesn't match its lowercase counterpart. The code below demonstrates this exact problem.
def is_palindrome(text):
# This fails with mixed case palindromes
return text == text[::-1]
print(is_palindrome("Radar")) # Returns False incorrectly
The == operator treats uppercase and lowercase letters as distinct characters. Because 'R' and 'r' aren't identical, the comparison returns False. The corrected function below shows how to resolve this.
def is_palindrome(text):
# Convert to lowercase first
text = text.lower()
return text == text[::-1]
print(is_palindrome("Radar")) # Now correctly returns True
The fix is to normalize the string by calling text.lower() before the comparison. This step ensures that characters like 'R' and 'r' are treated as identical, so the check doesn't fail due to case differences. After this conversion, the comparison text == text[::-1] works as intended. You'll want to keep this in mind whenever your function handles text from sources with inconsistent capitalization, like user input.
Handling special characters and spaces in palindromes
Just like with case sensitivity, spaces and punctuation can trip up your function. A simple text == text[::-1] comparison will fail on a classic palindrome like "A man, a plan, a canal: Panama" because it doesn't ignore these extra characters.
def is_palindrome(text):
# Bug: Not handling spaces and punctuation
return text == text[::-1]
print(is_palindrome("A man, a plan, a canal: Panama")) # Returns False incorrectly
The comparison fails because text[::-1] reverses every character, including spaces and punctuation. The original string's second character is a space, while the reversed string's second character is 'a', causing an immediate mismatch. The corrected function shows how to solve this.
def is_palindrome(text):
# Remove non-alphanumeric and convert to lowercase
cleaned_text = ''.join(char.lower() for char in text if char.isalnum())
return cleaned_text == cleaned_text[::-1]
print(is_palindrome("A man, a plan, a canal: Panama")) # Now correctly returns True
The fix is to sanitize the string before comparison. This corrected function uses a generator expression to build a new, clean string that's ready for the palindrome check.
- It iterates through the input
text, keeping only letters and numbers withchar.isalnum(). - Each character is also converted to lowercase.
The ''.join() method then assembles these characters into a sanitized string. You'll find this approach essential when handling user-provided text or parsing natural language.
Missing base case in recursive is_palindrome() function
A recursive function needs a base case to know when to stop. If your is_palindrome() function is missing one for an empty string, it won't have an exit strategy. This oversight causes an infinite loop, triggering a RecursionError. The code below shows this exact scenario in action.
def is_palindrome(text):
# Bug: No base case for empty string
if len(text) == 1:
return True
if text[0] != text[-1]:
return False
return is_palindrome(text[1:-1])
print(is_palindrome("")) # Will cause RecursionError
The function has no exit strategy for an empty string. When processing an even-length palindrome, it eventually calls itself with "" and tries to access text[0], which crashes the program. The corrected function below handles this scenario.
def is_palindrome(text):
# Fixed: Proper base case for empty string
if len(text) <= 1: # Empty string or single character
return True
if text[0] != text[-1]:
return False
return is_palindrome(text[1:-1])
print(is_palindrome("")) # Now safely returns True
The fix is to broaden the base case to if len(text) <= 1:. This single condition provides a safe exit point for the recursion, preventing the function from attempting to access an index on an empty string.
- It correctly identifies both empty strings and single-character strings as palindromes.
- This change stops the function from calling itself indefinitely, which prevents the crash.
You'll want to double-check your base cases whenever writing recursive functions to avoid these kinds of errors.
Real-world applications
With your robust checker ready, you can now apply these concepts to practical text analysis and string manipulation problems.
Using find_palindromes() to extract palindromic words from text
You can create a find_palindromes() function to scan a body of text and extract every word that reads the same forwards and backward.
def find_palindromes(text):
words = text.lower().split()
return [word for word in words if word == word[::-1] and len(word) > 1]
sample_text = "Bob found a level field where radar signals were strong. Noon is the best time."
palindromes = find_palindromes(sample_text)
print(f"Palindromic words found: {palindromes}")
The find_palindromes() function first prepares the text by converting it to lowercase with text.lower() and splitting it into a list of words. A list comprehension then builds a new list by filtering these words based on two conditions.
- First, it uses the familiar slice
word[::-1]to check if a word reads the same backward. - Second, it ensures the word is longer than a single character using
len(word) > 1.
This efficiently isolates multi-character palindromes while ignoring case and single letters.
Using character frequency to check if a string can form a palindrome
You can determine if a string can be rearranged into a palindrome by analyzing its character frequencies, a clever approach that avoids reversing or rearranging the string at all.
def can_form_palindrome(text):
# Remove non-alphanumeric and convert to lowercase
text = ''.join(c.lower() for c in text if c.isalnum())
# Count occurrences of each character
char_count = {}
for char in text:
char_count[char] = char_count.get(char, 0) + 1
# In a palindrome, at most one character can appear an odd number of times
odd_count = sum(1 for count in char_count.values() if count % 2 != 0)
return odd_count <= 1
print(can_form_palindrome("tact coa")) # Can form "tacocat"
print(can_form_palindrome("hello")) # Cannot form a palindrome
This function, can_form_palindrome(), cleverly checks if a string can be scrambled into a palindrome without actually generating any permutations. After sanitizing the text, it builds a frequency map of all characters.
- The logic hinges on a simple rule: for a word to be a palindrome, its letters must form pairs.
- An odd-length palindrome can have one unique character in the middle, but all others must be paired.
The code counts how many characters have an odd frequency. If that number is greater than one, a palindrome is impossible, so it returns False.
Get started with Replit
Turn your new skills into a real tool with Replit Agent. Describe what you want, like “a web app that highlights palindromic words in a text file” or “a utility that finds palindromic DNA sequences.”
The agent writes the code, tests for errors, and deploys the app. Start building with Replit and bring your ideas to life.
Create and deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.
Create & deploy websites, automations, internal tools, data pipelines and more in any programming language without setup, downloads or extra tools. All in a single cloud workspace with AI built in.


.png)
.png)