[python] The tilde operator in Python

What's the usage of the tilde operator in Python?

One thing I can think about is do something in both sides of a string or list, such as check if a string is palindromic or not:

def is_palindromic(s):
    return all(s[i] == s[~i] for i in range(len(s) / 2)) 

Any other good usage?

This question is related to python operators

The answer is


Besides being a bitwise complement operator, ~ can also help revert a boolean value, though it is not the conventional bool type here, rather you should use numpy.bool_.


This is explained in,

import numpy as np
assert ~np.True_ == np.False_

Reversing logical value can be useful sometimes, e.g., below ~ operator is used to cleanse your dataset and return you a column without NaN.

from numpy import NaN
import pandas as pd

matrix = pd.DataFrame([1,2,3,4,NaN], columns=['Number'], dtype='float64')
# Remove NaN in column 'Number'
matrix['Number'][~matrix['Number'].isnull()]

I was solving this leetcode problem and I came across this beautiful solution by a user named Zitao Wang.

The problem goes like this for each element in the given array find the product of all the remaining numbers without making use of divison and in O(n) time

The standard solution is:

Pass 1: For all elements compute product of all the elements to the left of it
Pass 2: For all elements compute product of all the elements to the right of it
        and then multiplying them for the final answer 

His solution uses only one for loop by making use of. He computes the left product and right product on the fly using ~

def productExceptSelf(self, nums):
    res = [1]*len(nums)
    lprod = 1
    rprod = 1
    for i in range(len(nums)):
        res[i] *= lprod
        lprod *= nums[i]
        res[~i] *= rprod
        rprod *= nums[~i]
    return res

This is minor usage is tilde...

def split_train_test_by_id(data, test_ratio, id_column):
    ids = data[id_column]
    in_test_set = ids.apply(lambda id_: test_set_check(id_, test_ratio)) 
    return data.loc[~in_test_set], data.loc[in_test_set]

the code above is from "Hands On Machine Learning"

you use tilde (~ sign) as alternative to - sign index marker

just like you use minus - is for integer index

ex)

array = [1,2,3,4,5,6]
print(array[-1])

is the samething as

print(array[~1])


~ is the bitwise complement operator in python which essentially calculates -x - 1

So a table would look like

i  ~i  
0  -1
1  -2
2  -3
3  -4 
4  -5 
5  -6

So for i = 0 it would compare s[0] with s[len(s) - 1], for i = 1, s[1] with s[len(s) - 2].

As for your other question, this can be useful for a range of bitwise hacks.


The only time I've ever used this in practice is with numpy/pandas. For example, with the .isin() dataframe method.

In the docs they show this basic example

>>> df.isin([0, 2])
        num_legs  num_wings
falcon      True       True
dog        False       True

But what if instead you wanted all the rows not in [0, 2]?

>>> ~df.isin([0, 2])
        num_legs  num_wings
falcon     False       False
dog        True        False

One should note that in the case of array indexing, array[~i] amounts to reversed_array[i]. It can be seen as indexing starting from the end of the array:

[0, 1, 2, 3, 4, 5, 6, 7, 8]
    ^                 ^
    i                ~i