#python #python-3.x #list #dynamic
#питон #python-3.x #Список #динамический
Вопрос:
Версия Python: 3.9.5
Мой Код:
cells = [[i, i] for i in range(3)] steps = [] for t in range(2): for i in range(len(cells)): xrand = random.randint(-5, 5) yrand = random.randint(-5, 5) cells[i][0] = xrand cells[i][1] = yrand steps.append(list(cells)) print(steps)
Фактический Объем Производства:
[[[3, 3], [2, 3], [6, 3]]] [[[4, 7], [-3, 2], [8, 3]], [[4, 7], [-3, 2], [8, 3]]]
Ожидаемый Результат:
[[[3, 3], [2, 3], [6, 3]]] [[[3, 3], [2, 3], [6, 3]], [[4, 7], [-3, 2], [8, 3]]]
Я каждый раз меняю значение ячеек списка во внешнем цикле и добавляю измененный список в список шагов. Как вы можете видеть на выходных данных, на второй итерации первый элемент ячеек также изменяется, хотя я только добавляю элемент в список.
Первым элементом шагов является список ячеек из предыдущей итерации. Но на второй итерации оба элемента динамически изменяются, хотя я добавляю только элемент, и поэтому первый элемент не должен быть затронут.
Почему это происходит и как вы это преодолеваете?
Ответ №1:
list(cells)
создает неглубокую копию, таким образом, изменение изменяемого содержимого cells
также изменит содержимое неглубокой копии — или, скорее, содержимое неглубокой копии на самом деле является тем же объектом, что и содержимое cells
.
То, что вам нужно, — это глубокая копия:
import copy cells = [[i, i] for i in range(3)] steps = [] for t in range(2): for i in range(len(cells)): xrand = 1 yrand = 1 cells[i][0] = xrand cells[i][1] = yrand steps.append(copy.deepcopy(cells)) print(steps)
Выход:
[[[1, 1], [2, 2], [3, 3]]] [[[1, 1], [2, 2], [3, 3]], [[2, 2], [3, 3], [4, 4]]]
Я заменил random.randint
детали статическими значениями, поэтому продемонстрированный результат меньше … Случайный.
Ответ №2:
Списки обрабатываются на месте
Это связано с тем, что список обрабатывается со ссылкой на реальный объект (место хранения) на диске. См. Следующий пример:
l = [2] x = [l, l] print(x) gt;gt;gt; [[2], [2]] l[0] = 4 print(x) gt;gt;gt; [[4], [4]]
Вы можете преодолеть это, используя либо новую переменную, либо copy.deepcopy()
gt;gt;gt; import copy gt;gt;gt; l = [2] gt;gt;gt; x = [copy.deepcopy(l), l] gt;gt;gt; print(x) [[2], [2]] gt;gt;gt; l[0] = 4 gt;gt;gt; print(x) [[2], [4]]