5 Best Ways to Check if Two Parts of a String are Palindrome in Python

πŸ’‘ Problem Formulation: In this article, we aim to solve the problem of checking whether two specified parts of a string are palindromes. A palindrome is a word, phrase, or sequence of characters that reads the same forward and backward. The input would be a string and indices to denote two parts, while the output would be a Boolean indicating whether both parts are palindromes. For example, given the string “abbaeae”, and parts defined by indices (0,3) and (4,6), the returned result should be True since both “abba” and “eae” are palindromes.

Method 1: Using Slicing and a Helper Function

This method involves creating a helper function that checks if a given string segment is a palindrome by comparing it with its reverse, which is obtained through slicing. A string is a palindrome if it remains unchanged when reversed.

Here’s an example:

def is_palindrome(segment):
    return segment == segment[::-1]

def check_palindrome_parts(string, part1, part2):
    return (is_palindrome(string[slice(*part1)]) and
            is_palindrome(string[slice(*part2)]))

# Example usage
part1_indices = (0, 4)  # Indices are inclusive for start and exclusive for end
part2_indices = (4, 7)
print(check_palindrome_parts("abbaeae", part1_indices, part2_indices))

Output:True

The is_palindrome function takes a string segment and compares it to its reverse. The check_palindrome_parts function applies this to two parts of a string, as defined by the provided index tuples, and returns True only if both parts are palindromes.

Method 2: Using the reversed() Function

This approach also utilizes a helper function but uses the built-in reversed() function combined with the ''.join() method to reverse the string segment before performing the comparison.

Here’s an example:

def is_palindrome(segment):
    return segment == ''.join(reversed(segment))

def check_palindrome_parts(string, part1, part2):
    return (is_palindrome(string[slice(*part1)]) and
            is_palindrome(string[slice(*part2)]))

# Example usage
print(check_palindrome_parts("abbaeae", (0, 4), (4, 7)))

Output:True

The reversed() function provides an iterator that reads the string in reverse, which is then joined into a string for comparison. The check_palindrome_parts function checks both parts of the string as in Method 1.

Method 3: In-place Comparison

This method checks for palindromes without creating additional strings by comparing characters in-place. It performs comparison from the beginning and the end of the segments until the middle is reached or a mismatch is found.

Here’s an example:

def is_palindrome(string, start, end):
    while start < end:
        if string[start] != string[end-1]:
            return False
        start += 1
        end -= 1
    return True

def check_palindrome_parts(string, part1, part2):
    return (is_palindrome(string, *part1) and 
            is_palindrome(string, *part2))

# Example usage
print(check_palindrome_parts("abbaeae", (0, 4), (4, 7)))

Output:True

The is_palindrome function iteratively compares characters from opposite ends of the string segment until a difference is found or all character checks pass, indicating a palindrome. The main function checks both segments accordingly.

Method 4: With Recursion

This recursive method checks for palindromes by reducing the problem size at each step, comparing the outermost characters and then calling itself on the remaining substring if they match.

Here’s an example:

def is_palindrome(segment):
    if len(segment) <= 1:
        return True
    if segment[0] != segment[-1]:
        return False
    return is_palindrome(segment[1:-1])

def check_palindrome_parts(string, part1, part2):
    return (is_palindrome(string[slice(*part1)]) and
            is_palindrome(string[slice(*part2)]))

# Example usage
print(check_palindrome_parts("abbaeae", (0, 4), (4, 7)))

Output:True

The is_palindrome function compares the outer characters and recursively calls itself with the inner substring if they match, until the base condition of a single character or empty string (both cases are palindromes) is satisfied.

Bonus One-Liner Method 5: Using Lambda and All

A one-liner using Python’s all() function and a lambda expression to compactly check if both string segments are palindromes, utilizing slicing for the reversal check.

Here’s an example:

check_palindrome_parts = lambda s,p1,p2: all(s[i:j] == s[i:j][::-1] for i,j in [p1, p2])

# Example usage
print(check_palindrome_parts("abbaeae", (0, 4), (4, 7)))

Output:True

This method uses a lambda function to iterate over both parts, applies slicing to check if each part is equal to its reverse, and employs the all() function to ensure that both parts pass the palindrome check.

Summary/Discussion

    Method 1: Slicing and Helper Function. Strength: Readable; easy to understand. Weakness: Additional function overhead. Method 2: reversed() Function. Strength: Pythonic and concise. Weakness: Slightly less efficient due to join(). Method 3: In-place Comparison. Strength: Space-efficient; no extra strings created. Weakness: More complex code. Method 4: Recursion. Strength: Elegant reduction of the problem. Weakness: Potential overhead of recursive calls; not as readable. Method 5: Lambda and All. Strength: Extremely concise one-liner. Weakness: Potentially less readable due to compactness.