1

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)

2 Answers 2

1

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]]
Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.