2015-01-24 2 views
1

Я пытаюсь построить перестановки списка с i-м битом, перевернутым каждый раз.Карта Python со списком в качестве входного

Например:

С вводом:

[1,0,0,0] 

Чтобы получить:

[0,0,0,0] 

[1,1,0,0] 

[1,0,1,0] 

[1,0,0,1] 

Я написал метод, который дал список возвращает тот же список с битом в положении р изменилось :

def flipBit(l,p): 
    l[p] = ~l[p]&1 
    return l 

И я пытаюсь применить его с помощью map(), но я не могу даже получить простой пример работает:

p=list(map(flipBit, [[1,0,0]]*3,range(3)))) 

Это то, что она возвращает:

[[0, 1, 1], [0, 1, 1], [0, 1, 1]] 

, ожидая:

[[0, 0, 0], [1, 1, 0], [1, 0, 1]] 

Что я делаю неправильно? (если кто-то может предложить еще более короткий код для этого, возможно, без использования флипбитного метода, я бы это оценил, так как я не буду использовать флипбит, кроме этой цели, и я хочу, чтобы код был кратким и чистым)

ответ

1

Проблема заключается в том, что [[1,0,0]]*3 создает список, содержащий три ссылки тому же подсписку. Когда вы меняете один подсписчик, все они меняются.

Вот один из способов исправить это:

>>> list(map(flipBit, [[1,0,0] for _ in range(3)], range(3))) 
         ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ 
[[0, 0, 0], [1, 1, 0], [1, 0, 1]] 

А вот способ реализовать эту функцию без использования вспомогательной функции:

>>> 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]] 
1

код размещен является не действует на всех, но я полагаю, что вам нужно это:

>>> p=list(map(lambda x: flipBit([1, 0, 0], x), range(3))) 
>>> p 
[[0, 0, 0], [1, 1, 0], [1, 0, 1]] 

в принципе, вы карту с lambda функцией, которая частично применяет [1, 0, 0] как l, а затем принимает каждый элемент в range(3) и применяется к p.