Python

Стал изучать программирование. Зачем сам не знаю честно говоря, но не суть. В общем, в языке python есть такая интересная особенность. Если я буду создавать матрицу вот так: [[0]*3]*3 то при изменении одной строки матрицы, изменятся все. Я прочитал что это происходит потому, что ссылочная модель данных и создаётся на самом деле один список [0, 0, 0], а в матрицу помещается просто 3 ссылки на него. Но вот почему так происходит и как это работает я хоть убей не могу понять. Почему при умножении списка, создаются ссылки а не новые списки. Если есть тут бывалые питонисты объясните пожалуйста максимально понятно. Может хоть тут пойму

Поскольку получилось не совсем понятно что я имел ввиду, прикладываю скрин

Python

Как тут видно, когда я меняю элемент А[0][0], то меняется не только он, а так же элементы А[1][0] и А[2][0]

Правила сообщества

Публиковать могут пользователи с любым рейтингом. Однако!


Приветствуется:

• уважение к читателям и авторам

• конструктивность комментариев

• простота и информативность повествования

• тег python2 или python3, если актуально

• код публиковать в виде цитаты, либо ссылкой на специализированный сайт


Не рекомендуется:

• допускать оскорбления и провокации

• распространять вредоносное ПО

• просить решить вашу полноценную задачу за вас

• нарушать правила Пикабу

2
Автор поста оценил этот комментарий
Непонятно, в чем вопрос. При любом нормальном копировании (присваивание, передача параметра и т.п.) передается ссылка. Умножение - копирование. Поэтому ссылки.
Почему так сделано - вопрос к авторам. Скорее всего, для экономии.
Впрочем, для нетривиальных объектов так во всех языках, кмк. Только более явно.
раскрыть ветку (1)
1
Автор поста оценил этот комментарий
Вооот. Я не мог понять, потому, что не понимал, что умножение это копирование, а не создание нового идентичного обьекта. Об этом нигде не написано, видимо считается что по дефолту это все должны понимать. А я вот не понял. И из за этого у меня не складывалось. Спасибо большое)
показать ответы
2
Автор поста оценил этот комментарий

в следующий раз лучше копируйте код, не всегда понятно о чем идет речь без него.
насчет где хранится и почему так, если на пальцах, то есть два хранищила: стек и куча.

первый быстрый, но маленький. второй медленный, но большой.

в стек помешаются локальные переменные(с заранее известным размером), структуры и тд. и в стек попадают ссылки. ссылки эти ведут на большие или динамические данные, такие как списки, массивы и тд. сами данные списков, массивов и тд хранятся на куче. но это основа основ в программировании, которая актуальна для компилируемых языков. в питоне эту систему слегка изменили:
Управление памятью в Python включает в себя частную кучу, содержащую все объекты и структуры данных Python. Управление этой частной кучей обеспечивается менеджером памяти Python. Диспетчер памяти Python имеет различные компоненты, которые имеют дело с различными аспектами управления динамическим хранилищем, такими как совместное использование, сегментация, предварительное выделение или кэширование.
https://docs.python.org/2/c-api/memory.html

раскрыть ветку (1)
0
Автор поста оценил этот комментарий
Отредактировал пост, вставил скрин с кодом
0
Автор поста оценил этот комментарий

А можно подробнее: что Вы понимаете под изменением строки матрицы?

Просто, если создать таким образом квадратную матрицу, а затем заменить ей первую строку, ничего криминального не происходит

Иллюстрация к комментарию
раскрыть ветку (1)
0
Автор поста оценил этот комментарий
Отредактировал пост, вставил скрин с кодом
0
Автор поста оценил этот комментарий
Хорошо. Тогда из подводных камней, могу предостеречь от того, чтобы указывать литерал в качестве значения аргумента по умолчанию. Например, попробуй:
def a(value, items = []):
items.append(value)
return items

print(a(1))
print(a(1))

Лучше делать так:
def a(value, items = None):
items = items if items is not None else []
items.append(value)
return items

print(a(1))
print(a(1))
раскрыть ветку (1)
Автор поста оценил этот комментарий
А вот это интересно). Почему так происходит в первом случае? Мы же вроде при повторном вызове функции переопределяем items на пустой список.
показать ответы
1
Автор поста оценил этот комментарий
Как вариант, можно использовать list-compehentions:
A = [[0 for _ in range(3)] for _ in range(3)]
_ - обозначение переменной, значение которой не нужно
раскрыть ветку (1)
Автор поста оценил этот комментарий
Да это я знаю. Было интересно почему именно в этом случае так работает. Потому что если механику какого то процесса не понимаешь, то дальше это обязательно где нибудь вылезет
показать ответы

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества