# find the binarian
binarian = sum(2**a for a in A)
# find the powers of two that are present in A
# We do this by making a list of which bits are True in the binarian.
# we check each bit, using len(bin()) to as an easy log2
# we only include powers of two that produce 1 when and'ed with the binarian
B = [pwr for pwr in range(len(bin(binarian)) - 2) if (2**pwr & binarian)]
There's no way more efficient to construct a number out of powers of two, then to simply list which bits are flipped. This is what that does. It scans through bits from least-significant to most-significant, and only outputs if the bit is flipped.
This produces an ascending list (e.g. [0, 2, 3]
. If you want a descending list (e.g. [3, 2, 0]
, you can wrap the range()
call in reversed()
.