2013-03-27 3 views
4
>>> CM = [[0 for _ in range(10)]] * 10 
>>> CM  
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 
>>> CM[0][0] = CM[0][0] + 1 
>>> CM 
[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 

Я пытался создать матрицу замешательства. Он содержит в основном число пар (i, j). Сначала я создал список списков, а затем увеличил соответствующую переменную. Однако это не сработало, как ожидалось. CM [i] [0] был увеличен для всех значений i.В чем разница между [[0 для _ в диапазоне (10)] для _ в диапазоне (10)] и [0 для _ в диапазоне (10)] * 10?

Я нашел работу вокруг.

>>> CM = [[0 for _ in range(10)] for _ in range(10)] 
>>> CM 
[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 
>>> CM[0][0] = CM[0][0] + 1 
>>> CM 
[[1, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] 

Но я был бы признателен, если бы кто-нибудь мог объяснить, почему первый метод не удался.

+0

Спасибо! Я попытался выполнить поиск, но, возможно, не использовал правильный запрос. – user1944668

+0

Обратите внимание, что 'CM = [[0] * 10 для _ в диапазоне (10)]' также будет работать здесь – Eric

+0

А! Благодарю. Я запомню это. – user1944668

ответ

3
>>> CM = [[0 for _ in range(10)]] * 10 

Копирует ссылку на один и тот же объект, десять раз. Это эквивалентно этому:

>>> x = [0 for _ in range(10)] 
>>> CM = [x, x, x, x, x, x, x, x, x, x] 

Таким образом, манипулирование одним элементом вызывает побочные эффекты. Ваше обходное решение элегантно и правильно.

>>> CM = [[0 for _ in range(10)]] * 10 

Копирует ссылку на один и тот же объект десять раз. Это эквивалентно этому:

>>> x = [[0 for _ in range(10)]] 
>>> CM = [x, x, x, x, x, x, x, x, x, x] 

Таким образом, манипулирование одним элементом вызывает побочные эффекты. Ваше обходное решение элегантно и правильно.

Примечание:

Это происходит, так как элементы списков (списки, которые являются изменяемыми). Если бы они были, например, строками, которые неизменяемы, это не было бы проблемой, если бы одна и та же строка была указана в разных списках, так как ими нельзя манипулировать. Python не любит тратить память (если явно не указано, то есть deepcopy), поэтому копии списков просто скопируют их ссылки.

+0

Спасибо! Это мой первый вопрос о переполнении стека и сразу получил ответ! Большое спасибо! – user1944668

Смежные вопросы