Today I learned about the symmetry in indexing from the beginning and end of a list with the bitwise invert operator.

The text “~i” inside a pair of square brackets in front of a highly geometrical building.

Negative indexing

As you might be aware of, Python allows indexing with negative indices:

>>> s = "Hello, there!"
>>> s[-1]
'!'

In case this is new to you, you can check out this Pydon't on the subject.

One thing to note is that the index for the nth element is n - 1, but the index for the nth element from the end is -n. This is just “how it works”, but it is kind of a bummer because it is very asymmetrical:

>>> seq = "ABCDCBA"
>>> seq[0], seq[-1]     # 0 and -1
('A', 'A')
>>> seq[1], seq[-2]     # 1 and -2
('B', 'B')
>>> seq[2], seq[-3]     # 2 and -3
('C', 'C')
>>> seq[3], seq[-4]     # 3 and -4
('D', 'D')

By looking at the correspondences above, we can see that the positive index n pairs up with the index -n - 1.

Bitwise invert

Python has a couple of bitwise operations, one of them being bitwise invert ~. Bitwise invert ~n is defined as -(n+1):

>>> n = 38
>>> ~n
-39
>>> -(n+1)
-39
>>> n = -73
>>> ~n
72
>>> -(n+1)
72

Now, maybe you can see where I'm going with this, but -(n+1) simplifies to -n - 1.

Symmetrical indexing with bitwise inversion

If we put these two pieces of knowledge together, we can see how we can use bitwise inversion ~ to index symmetrically from the beginning and end of a sequence, like a string or a list:

>>> seq = "abccba"
>>> seq[1], seq[~1]
('b', 'b')
>>> for i in range(len(seq) // 2):
...     print(seq[i], seq[~i])
...
a a
b b
c c

Doesn't this look beautiful?

I feel like this is one of those things that you really won't use that often, but there will come a time in your life when you'll want to exploit this symmetry! And, you either remember what you just learned about ~, or you'll be writing the uglier version with subtractions:

>>> seq = "abccba"
>>> seq[1], seq[~1]
('b', 'b')
>>> for i in range(len(seq) // 2):
...     print(seq[i], seq[-i - 1])
...
a a
b b
c c

Thanks a lot to Tushar Sadhwani from bringing this to my attention:

That's it for now! Stay tuned and I'll see you around!

I hope you learned something new! If you did, consider following the footsteps of the readers who bought me a slice of pizza 🍕. Your small contribution helps me produce this content for free and without spamming you with annoying ads.

References

Previous Post Next Post

Blog Comments powered by Disqus.