When candidates interview for a software engineering role, they are sometimes asked to demonstrate their coding abilities by writing a function to check if an input string is a palindrome. For a string of length n, this function will need to compare the i-th character with the n-i-th character for every value of i between 0 and n/2. Here are a few common implementations:

1) Calculate the index for the n-i-th character using n

def is_palindrome(text):
    n = len(text)
    for i in range(n//2):
        if text[i] != text[n-i]:
            return False
    return True

2) Calculate the index for the n-i-th character using negative indices (-i-1)

def is_palindrome(text):
    for i in range(len(text)//2):
        if text[i] != text[-i-1]:
            return False
    return True

3) Reverse the entire string and compare it whole against the initial string

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

Palindromes using the ~

Each of the above solutions is perfectly fine, but it's always fun to come up with additional solutions. So today, I'm here to show you an implementation using the tilde (~) operator! It simplifies the second implementation above:

def is_palindrome(text):
    for i in range(len(text)//2):
        if text[i] != text[~i]:
            return False
    return True

This works because the tilde operator is a unary operator that calculates the two's complement for integers, while the minus sign is used for the one's complement. As a general rule of thumb, this means:

~i = -i-1

This makes the tilde operator a great tool for simplifying operations that need to be performed on a list in either the forwards or backwards directions. You'll no longer need to consider how accessing list elements in the forward direction is 0-indexed (first element is my_list[0]) while accessing them in the backwards direction is 1-indexed (last element is my_list[-1]). That's because -0 evaluates to 0, so my_list[-0] can't be used to access the last element!

Bitwise, not boolean

An important distinction to keep in mind is that the tilde operator performs the bitwise NOT operation and should not be confused with the boolean NOT operation, which is performed by the not keyword. To illustrate the difference:

>>> not 5
False
>>> ~5
-6

When used with the built-in boolean constants, the tilde operator first coerces them to integers. So ~True becomes the same as ~1 and ~False the same as ~0:

>>> not True
False
>>> ~True
-2
>>> not False
True
>>> ~False
-1

The tilde operator is commonly used with the numpy and pandas libraries, but until this week, I'd never considered using it for my simple indexing needs. Neat!