Python Palindromes: an Exhaustive Tutorial

Erik - Apr 16 '21 - - Dev Community

Let's have some fun with something called "palindromes." Palindromes are words or sentences that are the same forward as they are backwards. Some notable examples are “racecar,” “taco cat,” and “a man, a plan, a canal, Panama.”

There's a lot of guides out there for working with palindromes, but most of them stop at "racecar" because there's no spaces or tricky commas to deal with. This tutorial will go a step further in handling cases like "taco cat" and "a man, a plan, a canal, Panama."

Working with palindromes is likely something you will never do in your professional career as a programmer, but it may show up on a coding interview (because coding interviews can be ridiculous), so it won't hurt to cover them.

Getting Started

To check if a string is a palindrome, we first need to reverse it. There's actually a very easy way to reverse strings and lists in Python, and that's the list reference [::-1]. Check it out in action:

example_string = 'Programming is great!'
print(example_string[::-1]) # Outputs !taerg si gnimmargorP
Enter fullscreen mode Exit fullscreen mode

From here, identifying a palindrome is a simple matter of checking if the reversed string equals the regular string. Easy:

is_palindrome = lambda string: string == string[::-1]
print(is_palindrome('racecar')) # Outputs True
print(is_palindrome('hello')) # Outputs False
Enter fullscreen mode Exit fullscreen mode

Here we've defined a lambda function called is_palindrome that checks that it's string input is the same backwards as forwards. Let's see if it works for "taco cat" as well:

print(is_palindrome('taco cat')) # Outputs False
Enter fullscreen mode Exit fullscreen mode

This returns false because when we reverse "taco cat," we actually get "tac ocat."

A Better Palindrome Checker

If we want strings like "taco cat" to get picked up as a palindrome, we have to remove spaces. This is where the replace function comes in.

The replace Function

Python strings have a function called replace that take two inputs, the character to be replaced, and the character to replace it with. For example:

string = 'taco cat'
new_string = string.replace(' ', '')
print(new_string) # tacocat
Enter fullscreen mode Exit fullscreen mode

With this information, we can now make a palindrome checker that will catch "taco cat" like so:

palindrome_checker = lambda string: string.replace(' ', '') == string[::-1].replace(' ', '')
print(palindrome_checker('taco cat')) # Outputs True
Enter fullscreen mode Exit fullscreen mode

This is great, but now we come to our last challenge, "a man, a plan, a canal, Panama." This won't work with our current implementation for two reasons: the capital "P" in "Panama," and all the commas. Take a look:

palindrome = "a man, a plan, a canal, Panama"
print(is_palindrome(palindrome)) # Outputs False
Enter fullscreen mode Exit fullscreen mode

The first thing we'll have to do is cast the strings being compared to lowercase. Then, we'll have to get rid of all non alphanumeric characters. For this, we'll use a list comprehension and the join function.

List Comprehensions

List comprehensions are concise ways to create lists in Python. For example, if I wanted a list of the numbers 1 through 100, I simply have to write:

one_through_one_hundred = [i for i in range(1, 101)]
Enter fullscreen mode Exit fullscreen mode

For our palindrome checker, what we'll do is use a list comprehension to make a list out of only the alphanumeric characters in the string we're checking. Luckily, Python strings have a built in isalnum function that checks if the string contains only letters and numbers:

print("x".isalnum()) # Outputs True
print("3".isalnum()) # Outputs True
print("&".isalnum()) # Outputs False
Enter fullscreen mode Exit fullscreen mode

With this function, we can make a list of only the palindrome's alphanumeric characters:

palindrome = "a man, a plan, a canal, Panama"
arr = [char for char in palindrome if char.isalnum()]
print(arr)
# Outputs ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a', 'n', 'a', 'l', 'P', 'a', 'n', 'a', 'm', 'a']
Enter fullscreen mode Exit fullscreen mode

But wait, we have to make sure the letters are lowercase so that the capital "P" doesn't throw our checker off:

palindrome = "a man, a plan, a canal, Panama"
arr = [char.lower() for char in palindrome if char.isalnum()]
print(arr)
# Outputs ['a', 'm', 'a', 'n', 'a', 'p', 'l', 'a', 'n', 'a', 'c', 'a', 'n', 'a', 'l', 'p', 'a', 'n', 'a', 'm', 'a']
Enter fullscreen mode Exit fullscreen mode

Putting it All Together

Now, let's combine everything we learned to make a robust palindrome checker. We could do this with a lambda but it'll get too long to make much sense, let's make a full function. Check this out:

def palindrome_checker(string):
  palindrome_list = [char.lower() for char in string if char.isalnum()]
  return palindrome_list == palindrome_list[::-1]
Enter fullscreen mode Exit fullscreen mode

What we've done here is used a list comprehension along with lower and isalnum to get all the alphanumeric characters in our string into a list, then we return True if the list is the same forward as backwards. Let's test it out:

tests = ["racecar", "taco cat", "a man, a plan, a canal, Panama", "not a palindrome"]
for test in tests:
  print(palindrome_checker(test))
# True
# True
# True
# False
Enter fullscreen mode Exit fullscreen mode

The function works perfectly, nicely done!

Conclusion

This concludes our quick palindrome tutorial. If you like my content, please check out my blog where I write multi-part articles on intermediate to advanced level programming topics, or follow me on Twitter. Let me know if you have any questions!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .