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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 |
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.
1 2 3 4 5 6 7 8 9 10 |
# 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.”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
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
1 2 3 4 5 6 7 |
# 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:
1 2 3 4 5 6 7 8 9 10 11 12 |
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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
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.