Check for Palindrome Using Python

A sequence (string/number/phrase) is said to be a palindrome if the sequence reads the same backward as forward. For example, madam, civic, refer, 14541, and level.

This article discusses four methods of checking if a sequence object is a palindrome in Python. These methods include

  • Method 1: Using object indexing and slicing,
  • Method 2: Using an iterative loop (for-loop or while loop),
  • Method 3: Using the inbuilt reversed() function,
  • Method 4: Using a recursive approach (you may find this in a coding interview).

In the last section, we will also cover some potential caveats when using those methods to check for palindrome.

Method 1: Using object indexing and slicing

The general syntax for object slicing is given by object[start:stop:step], and the syntax object[::-1] is used to reverse the sequence.

Here are the reasons why that works:

  • If start and stop are not supplied, the sequence is sliced from the beginning to the end. This is what we want to do.
  • Negative values are used for indexing from the end of the sequence.

The following is an example of using reverse indexing to check for palindrome in Python.

def isPalindrome(str1):
    # reverse str1
    str1_reversed = str1[::-1]
    # check if str1 is same as str1 reversed.
    if str1 == str1_reversed:
        return True
    return False

str1 = "refer"
str2 = "python"
result1 = isPalindrome(str1)
print(str1, result1)
result2 = isPalindrome(str2)
print(str2, result2)

Output:

refer True
python False

Method 2: Using an iterative loop (for-loop or while loop)

Run a loop from the start to the midpoint of the string and check the first character to the last character, the second to the second last, and so on. If any character mismatches, the string is not a palindrome.

The following figure shows how a loop to identify palindrome works.

def PalindromeForLoop(str1):
    # palindrome in python using for loop
    # Turn a string into lower cases.
    str1 = str1.lower()
    # Run loop from 0 to the midpoint of the string.
    # print(len(str1)/2)
    for i in range(0, len(str1) // 2):
        # Loop through the first half and compare it with
        # characters on the last half.
        if str1[i] != str1[len(str1) - i - 1]:
            # if the character at index i is not equal to the
            # character at index len-i-i then str1 is not
            # palindrom
            return False
    return True

str2 = "python"
str3 = "saippuakivikauppias"
result2 = PalindromeForLoop(str2)
print(str2, result2)
result3 = PalindromeForLoop(str3)
print(str3, result3)

Output:

python False
saippuakivikauppias True
def PalindromeWhileLoop(str1):
    # palindrome python while loop
    i = 0
    str1 = str1.lower()
    while i <= len(str1) // 2:
        if str1[i] != str1[-i - 1]:
            return False
        i += 1
    return True

print(PalindromeWhileLoop("refer"))
print(PalindromeWhileLoop("goose"))
print(PalindromeWhileLoop("moooom"))

Output:

True
False
True

Method 3: Using reversed() function

The reversed(<seq>) function returns a generator of sequence objects in reversed order.

# reverse palindrome python
str1 = "refer"
# reversed() by default returns a generator
# of str1 reversed. join is used to join the
# items on a generator to get a reversed string.
str1_reversed = "".join(reversed(str1))
if str1 == str1_reversed:
    print("is a palindrome.")
else:
    print("is not a palindrome.")

Output:

is a palindrome.

Method 4: Using a recursive function

This method can show up in a coding interview in the form of a question like this:

“Write a code to check if a string is a palindrome using a recursive approach.”

def PalindromeRecursive(str1):
    # turn str1 into lowercase.
    str1 = str1.lower()
    # length of str1. eg, len(refer)=5
    len_s = len(str1)
    # if str1 has 0 or 1 character then it is
    # palindrome and the function is terminated with
    # return True.
    if len_s <= 1:
        return True
    # If str1[0] and str1[len_s- 1] are equal
    # the function calls itself a substring
    # that has not been checked.
    elif str1[0] == str1[len_s - 1]:
        str1 = str1[1 : len_s - 1]
        # Call the function with the str1[1: len_s - 1]
        # You can uncomment the following print statement
        # to see what's happening
        # print(str1)
        return PalindromeRecursive(str1)
    else:
        return False

str2 = "python"
str3 = "saippuakivikauppias"
r2 = PalindromeRecursive(str2)
print(str2, r2)
r3 = PalindromeRecursive(str3)
print(str3, r3)

Output:

python False
saippuakivikauppias True

The following figure shows how the recursive function explained above works.

Bonus: Checking for palindromes in a list

# palindrome list python
lst1 = ["refer", "dad", "python", "malayalam", "rotary", "aba"]
print("Original list of strings:\n",lst1)
# apply the lambda function to each value in lst1 and
# filter those that evaluate to true
result = list(filter(lambda x: x == x[::-1], lst1))
print("Palindromes:\n", result)

Output:

Orginal list of strings:
 ['refer', 'dad', 'python', 'malayalam', 'rotary', 'aba']
Palindromes:
 ['refer', 'dad', 'malayalam', 'aba']

Wrapping Up – 3 essential points

There are at least three things that affect whether Python correctly identifies a palindrome. They are

  • Data type – the methods discussed above require the input to be a string type.
  • Whether the string is lowercase or uppercase – Python is case-sensitive. For that reason, Mom, Refer, and Redivider will not be identified as palindromes because the first characters are upper case. To solve this potential problem, convert the input into lowercase or uppercase before checking if a given string is a palindrome.
  • Punctuations also affect if a word is identified as a palindrome or not. For example, without punctuation marks, the following phrase is a palindrome:

“A man, a plan, a canal: Panama”.

A simple way to solve the problem of punctuation is to remove them. Here is how to do that:

import string

str1 = "A man, a plan, a canal: Panama"
# Remove punctuation marks.
str1 = str1.translate(str.maketrans('', '', string.punctuation))
print(str1)
# Remove white spaces
str1 = str1.replace(" ", "")
print(str1)
# Turn str1 to lowercase.
str1 =  str1.lower()
print(str1)

Output:

A man a plan a canal Panama
AmanaplanacanalPanama
amanaplanacanalpanama

The following code shows how to incorporate those three points into the solution discussed in method 1.

import string

def isPalindrome(str1):
    # convert to string - works when non-string input is passed.
    str1 = str(str1)
    # Turn the input into lowercase and remove whitespace
    str1 = str1.lower().replace(" ", "")
    # remove punctuations
    str1 = str1.translate(str.maketrans("", "", string.punctuation))
    # reverse str1
    str1_reversed = str1[::-1]
    # check if str1 is same as str1 reversed.
    if str1 == str1_reversed:
        return True
    return False

str1 = "Refer"
str4 = "A man, a plan, a canal: Panama"
num5 = 12321
result1 = isPalindrome(str1)
print(str1, result1)
result2 = isPalindrome(str4)
print(str4, result2)
result3 = isPalindrome(num5)
print(num5, result2)

Output:

Refer True
A man, a plan, a canal: Panama True
12321 True

Conclusion

This article covered four ways of checking if a Python sequence is a palindrome. The first method should suffice in most cases, but in some cases (like in coding interviews), you might be required to use one of the other methods discussed in the article.

You also need to go through the three points mentioned in the last section. They provide solutions to caveats you might face when checking for palindrome.