Не знаю, как сформулировать вопрос...
Предположим, что я делаю следующее:
>>> l = [[]]*2
>>> l
[[], []]
>>> l[0].append(1)
>>> l
[[1], [1]]
Почему 1 добавляется в оба списка?
Не знаю, как сформулировать вопрос...
Предположим, что я делаю следующее:
>>> l = [[]]*2
>>> l
[[], []]
>>> l[0].append(1)
>>> l
[[1], [1]]
Почему 1 добавляется в оба списка?
[[]]*2
- это список двух ссылок на тот же список. Вы присоединяетесь к нему, а затем видите его дважды.
Потому что есть действительно только один список. Рассмотрим это:
>>> l = [[]]
>>> l2 = l*2
>>> l2[0] is l[0]
True
>>> l2[1] is l[0]
True
*2
, выполненный в списке, не копирует список, а возвращает список длины 2
, заполненный той же ссылкой.
Вероятно, вам понравилось следующее:
>>> l = [[] for _ in xrange(2)]
Как отмечает @Asterisk в комментарии, такое же поведение обнаруживается всеми общими коллекциями. Поэтому, как правило, лучше использовать только умножение на неизменяемые типы со значением-семантикой.
Вот как я инициализирую список списков. Строки меняются медленнее.
nrows = 3; ncols = 5
l_of_ls = [[0]*ncols for i in range(nrows )]
for rix, r in enumerate(l_of_ls):
for cix, c in enumerate(r):
print rix, cix, 'val = ',c
РЕЗУЛЬТАТ
0 0 val = 0
0 1 val = 0
0 2 val = 0
0 3 val = 0
0 4 val = 0
1 0 val = 0
1 1 val = 0
1 2 val = 0
1 3 val = 0
1 4 val = 0
2 0 val = 0
2 1 val = 0
2 2 val = 0
2 3 val = 0
2 4 val = 0
Также стоит отметить цели индексирования
for rix in range(nrows):
for cix in range(ncols):
print l_of_ls[rix][cix],
print
РЕЗУЛЬТАТ
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
Показывая разницу с макетом памяти:
listOfLists = [[]] * 3
listOfListsRange = [[] for i in range(0, 3)]