2D-список имеет странное поведение при попытке изменить одно значение
Возможный дубликат:
Неожиданная функция в списке списков Python
Итак, я относительно новичок в Python, и мне трудно работать с 2D-списками.
Здесь мой код:
data = [[None]*5]*5
data[0][0] = 'Cell A1'
print data
и вот результат (отформатированный для удобочитаемости):
[['Cell A1', None, None, None, None],
['Cell A1', None, None, None, None],
['Cell A1', None, None, None, None],
['Cell A1', None, None, None, None],
['Cell A1', None, None, None, None]]
Почему каждой строке присваивается значение?
Ответы
Ответ 1
Это делает список с пятью ссылками на список тот же:
data = [[None]*5]*5
Вместо этого используйте что-то вроде этого, которое создает пять отдельных списков:
>>> data = [[None]*5 for _ in range(5)]
Теперь он делает то, что вы ожидаете:
>>> data[0][0] = 'Cell A1'
>>> print data
[['Cell A1', None, None, None, None],
[None, None, None, None, None],
[None, None, None, None, None],
[None, None, None, None, None],
[None, None, None, None, None]]
Ответ 2
Как ссылка на библиотеку python для типов последовательностей, которая включает в себя списки, говорит
Обратите внимание, что копии неглубокие; вложенные структуры не копируются. Это часто преследует новых программистов на Python; рассмотреть следующие вопросы:
>>> lists = [[]] * 3
>>> lists
[[], [], []]
>>> lists[0].append(3)
>>> lists
[[3], [3], [3]]
Что случилось, так это то, что [[]] - это список из одного элемента, содержащий пустой список, поэтому все три элемента из [[]] * 3 (указывают на) этот единственный пустой список. Изменение одного из элементов списков изменяет этот единственный список.
Вы можете создать список разных списков таким образом:
>>> lists = [[] for i in range(3)]
>>> lists[0].append(3)
>>> lists[1].append(5)
>>> lists[2].append(7)
>>> lists
[[3], [5], [7]]
Ответ 3
В python каждая переменная является объектом и поэтому ссылкой. Сначала вы создали массив из 5 Nones, а затем вы создаете массив с 5-кратным тем же объектом.