Я попытался написать свою проблему с ошибкой воспроизводимым образом, чтобы платформа могла быть видна и управляема. Я не вижу своего логического пробела, почему возникает эта ошибка.
У меня есть внутренний цикл, который приносит новые элементы при очистке и добавляет их в список с именем list_inner
. Затем в список внешнего цикла с именем list_outer
добавляется этот новый список. Но окончательный результат дает правильное количество членов, но элементы списка list_outer такие же, последний элемент списка списка list_inner
. Как это может произойти? Если это будет один элементный список, то я пойму.
import random
list_inner=[]
list_outer=[]
for i in range(5):
for r in range(random.randint(1,10)):
list_inner.append(r)
print(r)
list_outer.append(list_inner)
print(list_outer)
print(list_outer)
Я делюсь двумя результатами, поскольку даю представление о том, что есть на самом деле, и о том, чего я ожидал. Я получил этот результат:
0
1
2
3
[[0, 1, 2, 3]]
0
1
2
3
4
[[0, 1, 2, 3, 0, 1, 2, 3, 4], [0, 1, 2, 3, 0, 1, 2, 3, 4]]
Но я ожидал такого результата:
[[0,1,2,3],[0,1,2,3,4]]
Здесь действительно две проблемы:
list_inner
в конце каждого внешнего цикла, поэтому он сохраняет все элементы из всех итераций до сих пор.list_inner
непосредственно к list_outer
вместо добавления копии list_inner
. Это означает, что когда list_inner
изменяется, ссылка на него, которая уже была помещена внутри list_outer
, также изменяется. Таким образом, вы получите то же самое, что и в list_outer
.Все, что вам нужно сделать, это изменить свой код на копирование list_inner
перед его добавлением, а также очистить list_inner
в конце каждого внешнего цикла:
import random
list_inner = []
list_outer = []
for i in range(5):
for r in range(random.randint(1,10)):
list_inner.append(r)
list_outer.append(list_inner.copy())
list_inner.clear()
print(list_outer)
Пример вывода:
[[0, 1, 2, 3, 4, 5, 6, 7, 8], [0, 1, 2], [0, 1, 2, 3, 4, 5, 6], [0, 1], [0, 1, 2, 3]]
@xlmaster list_inner.copy()
и list(list_inner)
делают одно и то же — делают копию списка — хотя использование list_inner.copy()
лучше, так как ясно, что на самом деле делается. Причина, по которой нам нужно скопировать список, заключается в том, что если мы этого не сделаем, мы добавим ссылку на list_inner
, которая также будет изменяться всякий раз, когда изменяется list_inner
. Поэтому, когда мы очистим список и начнем добавлять новые значения, ссылка, которую мы вставили в list_outer
, также изменится таким же образом. Вот почему вы получаете несколько копий одного и того же объекта в list_outer
. Копирование списка предотвращает это.
Я решил проблему, добавив список методов в inner_loop
перед методом добавления и поместив список во внешний цикл. Вот код
import random
list_outer=[]
for i in range(5):
list_inner = []
for r in range(random.randint(1,5)):
list_inner.append(r)
print(r,list_inner)
list_outer.append(list(list_inner))
print('list outer',list_outer)
print(list_outer)
Что трудно переварить, почему мы должны использовать в вашем ответе
list_inner.copy
в моем ответе я сказал это так,list_outer.append(list(list_inner))
. Вроде пробовал и получилось. Но зачем нужно копировать или составлять список добавленных данных, чтобы добавить его в виде списка? Был бы признателен, если бы ответил на это