
Python: Bitwise NOT and List  - kirubakaran
I realized that instead of using negative numbers to access elements of a list from the end, we can just use bitwise NOT. That looks more symmetrical (and hence beautiful).<p>For a list x:<p>First element is x[0]<p>Last element is x[~0] (instead of x[-1])<p>You can use x[~0], x[~1], x[~2]... (coz ~0==-1, ~1==-2 etc)<p>Did you guys know this already or is this my fresh insight? If it is the latter, YAY! :-)
======
mrtron
I didn't know that, but I don't know that it really is that helpful. I prefer
the Pythonic way of sticking to one method and having anyone be able to
understand it.

Good little hack though, if it works for you go nuts! (but document it
somewhere and be consistent)

------
nostrademons
I believe this'll only work on machines that use 2s-complement arithmetic,
which is basically all of them. Just saying...it's theoretically possible to
have number representations where ~0 != -1.

~~~
foonamefoo
That wouldn't matter since we are talking about python, not assembly or C.

~~~
BrandonM
I would hazard a guess that CPython (the reference implementation) hooks
directly into C for bitwise NOT, and therefore, it _would_ matter.

------
mulligan
silly me, all this time i've been using x[~-1] to get the first element,
x[~-2] to get the second element, and so forth!

------
llimllib
If you used this in source code that I had to maintain, I would curse you
every time I saw it.

Just saying.

~~~
kirubakaran
If you have to maintain my code, I'm sure you'll curse me anyway.

~~~
marcus
Always write your code as if the person who will maintain it is a deranged ax
murderer who knows where you live

------
jackdied
Clever, but as others pointed out likely to anger anyone who has to read your
code.

NB: python bitwise operations are not super fast like in C. They don't get
optimized down to single CPU instructions but instead are looked up like
regular type methods (e.g. __str__ and __add__). An "ob[~0]" won't kill you
even in a loop but don't bother translating simple math into bit-twiddling
because it won't help (and might hurt if it inflates the number of
operations).

~~~
kirubakaran
I tried profiling these two functions:

    
    
      import cProfile
      
      def flipbits():
          c=0
          for i in range(1,400000):
              b=~i
              c=c+b
          print c
    
      def negnums():
          c=0
          for i in range(1,400000):
              b=-i
              c=c+b
          print c
    
      cProfile.run("flipbits()")

140 function calls in 0.175 CPU seconds

    
    
      cProfile.run("negnums()")

140 function calls in 0.176 CPU seconds

\---

Summary:

Flipping bits is tiny bit _faster_ actually.To make negnums function produce
the same result as flipbits, we need to change b=-i to b=-i-1 and this is even
slower. Poke holes in my experiment please.

------
riobard
what a hack! I LIKE this idea! It's neat!

Look at this code I wrote for Project Euler. it checks if a sequence is
"palindromic". A "palindromic" sequence reads the same both from left and from
right. So the simple idea is to check from the left of the sequence to the
middle, and compare each element during the process with ones read from the
right. Note here I use Python 2.5 integer division (//) to ensure the index is
integer.

Using official Python index syntax, I have to write "s[i] == s[-i-1]" to
compare elements on symmetric positions in the sequence.

    
    
      def ispalindromic(s):
          return all(s[i] == s[-i-1] for i in range(len(s)//2))
    
    

However, using the "bitwise or" trick proposed above, I just write "s[i] ==
[s~i]", really neat!

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

~~~
kirubakaran
_> what a hack! I LIKE this idea! It's neat!_

Thanks, it means a lot...

------
attack
Oh you mean the old

x[::~0][~-1]

trick to get the last item. Thought that's what everyone uses.

~~~
slashcom
You can just use x[-1] to do the exact same thing. ~0 = -1 though, hence the
reason x[~0] has kind of a nice feel to it.

~~~
foonamefoo
your humor detection may be broken.

~~~
BrandonM
I don't get it, either. I mean, I realize that the OP's method would be
obscure to someone who's never seen it, but at least on some level, it's more
intuitive. Your example is simply obfuscated code for no other reason (other
than humor, apparently, which like I said, I missed).

------
thorax
I didn't know this and I do like it. Especially if it caught on and became
more standard.

I'll see if I can get my crew to try it out.

~~~
kirubakaran
Wow that would be awesome. BTW, I like your startup (bug.gd)... Thanks for
that.

------
earle
x | y bitwise or of x and y

x ^ y bitwise exclusive or of x and y

x & y bitwise and of x and y

x << n x shifted left by n bits

x >> n x shifted right by n bits

~x the bits of x inverted

~~~
BrandonM
I'm not going to vote you down, but honestly, what was this for?

