Форум сайта python.su
Пытаюсь разобраться со вложенными списками и вложенными списками. Вот такой пример кода. Не понимаю следующее. Я задаю элемент, в который добравляю числа от 0 до j, а сам j oт 0 до i. Если я задаю элемент (внутренний список) внутри цикла i (el2 в примере), то все понятно и хорошо, он при переходе к новому i обнуляется, логично. Но, если элемент задан ДО цикла i (el1), то вот тут все странно. Почему он цепляет все значения j i раз? Т.е. 2 вещи смущают. 1) как он обнуляется при переходе к новому i? 2) как так внутри меньшего i у этого цикла оказываются в доступе j большего значения? т.е. на прогоне i равного 1, почему-то есть и j = 1 и j = 2. Как так?
ml1, ml2, el1 = [], [], [] for i in range(4): el2 = [] for j in range(i): print(i, j) el1.append(j) el2.append(j) ml1.append(el1) ml2.append(el2) print(ml1, ml2, sep='\n') OUTPUT 1 0 2 0 2 1 3 0 3 1 3 2 [[0, 0, 1, 0, 1, 2], [0, 0, 1, 0, 1, 2], [0, 0, 1, 0, 1, 2], [0, 0, 1, 0, 1, 2]] [[], [0], [0, 1], [0, 1, 2]]
Офлайн
APytBОн не обнуляется, а выбрасывается. А вместо него создаётся новый пустой список. Соответственно, у разных списков разные адресы в памяти и разное содержимое. На следующем круге происходит то же самое и остаётся уже три списка с разными адресами в памяти и разным содержимым. И так далее. И вот эти разные списки добавляются в список ml2. У них разные адресы в памяти и разное содержимое у всех.
Если я задаю элемент (внутренний список) внутри цикла i (el2 в примере), то все понятно и хорошо, он при переходе к новому i обнуляется, логично.
APytBОн не обнуляется, а остаётся и продолжает заполняться дальше. У него один адрес в памяти и поэтому при его добавлении в список ml1 добавляется просто копия его адреса в памяти. Поэтому на каждом шаге ты добавляешь его же самого. А так как он растёт всё время, то к концу основного цикла этот список вырастает полностью.
Но, если элемент задан ДО цикла i (el1), то вот тут все странно. Почему он цепляет все значения j i раз? Т.е. 2 вещи смущают. 1) как он обнуляется при переходе к новому i?
>>> a = [] >>> lst = [a, a, a] >>> lst [[], [], []] >>> a.append(1) >>> lst [[1], [1], [1]] >>> a.append(2) >>> lst [[1, 2], [1, 2], [1, 2]] >>> a.append(3) >>> lst [[1, 2, 3], [1, 2, 3], [1, 2, 3]] >>> >>> c = [] >>> d = [] >>> e = [] >>> >>> lst = [a, c, a, d, a, e] >>> lst [[1, 2, 3], [], [1, 2, 3], [], [1, 2, 3], []] >>> c.append(10) >>> lst [[1, 2, 3], [10], [1, 2, 3], [], [1, 2, 3], []] >>> d.append(20) >>> lst [[1, 2, 3], [10], [1, 2, 3], [20], [1, 2, 3], []] >>> e.append(30) >>> lst [[1, 2, 3], [10], [1, 2, 3], [20], [1, 2, 3], [30]] >>> a.append(4) >>> lst [[1, 2, 3, 4], [10], [1, 2, 3, 4], [20], [1, 2, 3, 4], [30]] >>>
Офлайн
py.user.nextСпасибо! Да, тогда понятно
Офлайн
Немного дополню py.user.next. Вот посмотри приложенное объяснение “12345.jpg”
А еще посмотри, как одна и та же переменная может иметь разный адрес в памяти (id):
a = [] print('Адрес в памяти переменной "а" = ', id(a)) for i in range(4): b = [] print('Адрес в памяти переменной "b" = ', id(b))
Отредактировано Olezhka (Янв. 5, 2023 14:46:42)
Прикреплённый файлы:
12345.jpg (521,4 KБ)
Офлайн