Reputation: 7529
I'm trying to construct permutations of a list with the i-th bit flipped every time.
For example:
With input:
[1,0,0,0]
To get:
[0,0,0,0]
[1,1,0,0]
[1,0,1,0]
[1,0,0,1]
I wrote a method which given a list returns the same list with the bit at position p changed:
def flipBit(l,p):
l[p] = ~l[p]&1
return l
And I'm trying to apply it using a map()
, but I can't even get a basic example working:
p=list(map(flipBit, [[1,0,0]]*3,range(3))))
This is what it returns:
[[0, 1, 1], [0, 1, 1], [0, 1, 1]]
while expecting:
[[0, 0, 0], [1, 1, 0], [1, 0, 1]]
What I'm I doing wrong? (if anyone can suggest an even shorter code for this maybe without using a flipbit method I'd appreciate it as I won't really use flipbit other than this purpose and I want to keep the code concise and clean)
Upvotes: 1
Views: 122
Reputation: 500893
The issue is that [[1,0,0]]*3
creates a list containing three references to the same sublist. When you change one sublist, they all change.
Here is one way to fix this:
>>> list(map(flipBit, [[1,0,0] for _ in range(3)], range(3)))
↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
[[0, 0, 0], [1, 1, 0], [1, 0, 1]]
And here is a way to implement this functionality without using a helper function:
>>> l = [1, 0, 0]
>>> [l[:i] + [1-l[i]] + l[i+1:] for i in range(len(l))]
[[0, 0, 0], [1, 1, 0], [1, 0, 1]]
Upvotes: 1
Reputation: 7716
The code you posted is was not valid at all, but I presume you need this:
>>> p=list(map(lambda x: flipBit([1, 0, 0], x), range(3)))
>>> p
[[0, 0, 0], [1, 1, 0], [1, 0, 1]]
Basically, you map with a lambda
function, that partially applies [1, 0, 0]
as l
, and then takes each element in range(3)
and applies it to p
.
Upvotes: 1