Reputation: 1806
I feel silly having to ask this question, but my memory evades me of better alternatives. Two appraoches that spring to mind:
First:
def f1(v):
return sum(2**i for i,va in enumerate(v) if va)
>>> f1([True, False, True])
5
Second:
def f2(v):
return int('0b' + "".join(str(int(va)) for va in v),2)
>>> f2([True, False, True])
5
I feel that f1 is almost to clunky to be pythonic, and f2 is plainly too ugly as I'm jumping between multiple datatypes. Maybe its my age...?
Upvotes: 2
Views: 127
Reputation: 1010
Just for contrast here's a way that you would do this if you were writing python as if you were writing something like c.
def f(l):
output = 0
for i in range(len(l)):
output |= l[i] << i
return output
Upvotes: 2
Reputation: 3385
Its little more rigid solution but its very computationally efficient
>>> import numpy as np
>>> predefined_bytes = 2**(np.arange(32))
>>> predefined_bytes
array([ 1, 2, 4, 8, 16,
32, 64, 128, 256, 512,
1024, 2048, 4096, 8192, 16384,
32768, 65536, 131072, 262144, 524288,
1048576, 2097152, 4194304, 8388608, 16777216,
33554432, 67108864, 134217728, 268435456, 536870912,
1073741824, 2147483648])
def binary2decimal(bits,predefined_bytes):
bits = np.array(bits)
return np.sum(bits*predefined_bytes[:bits.shape[0]])
>>> binary2decimal([1,1,1,1,1,1,1,1],predefined_bytes)
255
Upvotes: 0
Reputation: 55933
Using a left shift is slightly faster than raising to powers (at least on my machine). Using a bitwise operation encourages the reader of the code to think in terms of binary data.
>>> sum(v << i for i, v in enumerate([True, False, True]))
5
Upvotes: 4
Reputation: 17911
Using booleans in arithmetic operations (also lambda functions) is very pythonic:
lst = [True, False, True]
func = lambda x: sum(2 ** num * i for num, i in enumerate(x))
print(func(lst))
# 5
Upvotes: 1
Reputation: 11972
This is another hacky way I came up with:
def f1(v):
return int(''.join(str(int(b)) for b in v), 2)
Example:
>>> def f1(v):
... return int(''.join(str(int(b)) for b in v), 2)
...
>>> f1([True, False, True])
5
>>>
Another identical example using map
(more readable in my view):
def f1(v):
return int(''.join(map(str, map(int, v))), 2)
Upvotes: 0