Reputation:
I am trying to create a powerset by multiplying binary counter with array to get
Value of Counter Subset
000 -> Empty set
001 -> a
010 -> b
011 -> ab
100 -> c
101 -> ac
110 -> bc
111 -> abc
My code:
A = ['a','b','c']
n = len(A)
for i in range(2**n):
print format(i,'b') and A
I get all the outputs as ['a','b','c']
. Is there a different way to do the print statement to get the required result.
Upvotes: 1
Views: 192
Reputation: 1875
You cant use bitwise operation between a string and a list.
I tried the following way.
A = ['a','b','c']
n = len(A)
for i in range(2**n):
s = format(i,'b')[::-1]
print(''.join( (A[j] for j in range(len(s)) if s[j]=='1' )))
Upvotes: 0
Reputation: 12157
Try this
d = {0b1: 'a', 0b10: 'b', 0b100: 'c'}
for i in range(0b1000):
s = ''
for k, v in d.items():
if i & k:
s += v
print s
Edit: Some explination
So you're trying to associate 'a', 'b', 'c'
to 1, 2 and 4
respectively. To do this I used the dictionary above (using binary literals for clarity).
Then, looping through all 0 <= i < 8, you can see if there is a 1
at the relevant position using the &
operator.
e.g. is there a 1
at the second position from the right: 0b00 & 0b10 == 0b01 & 0b10 == 0
is false, whereas 0b10 & 0b10 == 0b11 & 0b10 != 0
is true.
Upvotes: 0
Reputation: 82899
The expression format(i,'b') and A
is not the same as "bitwise-and of the binary number i
with the elements of list A
". X and Y
is logical-and and is interpreted as Y if X else X
, thus you always get A
as a result.
You can use a list comprehension, checking the bitwise &
of 2**i
(i
being the current index) and the running number. Also, no explicit conversion to binary is needed.
>>> [[e for i, e in enumerate(A) if 2**i & x] for x in range(2**n)]
[[], ['a'], ['b'], ['a', 'b'], ['c'], ['a', 'c'], ['b', 'c'], ['a', 'b', 'c']]
Upvotes: 1