@Onigire

Kак сделать иммутабельный список?

Здравствуйте, как известно, списки в пайтоне передаются по ссылке, что не дает адекватно их передавать в функции.
def minor(n, array):
    array.pop(0)
    for item in array:
        item.pop(n)
    return array

a = [[1, 2, 9],
     [4, 5, 6],
     [7, 8, 9]]

с = minor(1 ,a)
print(a)

(Редактировано)

Список "а" изменяется. Я пробовал передавать список таким образомс = minor(1, a[:]), в таком случае
array.pop(0) - не работает,
а for item in array: item.pop(n)
по какой-то причине все равно изменяет входящий список "а"

  • Вопрос задан
  • 165 просмотров
Решения вопроса 1
trapwalker
@trapwalker Куратор тега Python
Программист, энтузиаст
Вы меня удивляете, сударь.
Вроде не новичок и понимаете концепию иммутаельности, передачи аргументов по значению и по ссылке, но с непониманием элементарной базовой особенности языка вы идёте задавать тривиальный вопрос у живых людей, когда самые-самые новички знакомятся с этим в первых главах любой книжки про питон для чайников.

К питону не применимы понятия "передачи аргументов по значению" или "по ссылке".
В Питоне переменные раотают иначе, чем в Си или Паскале.
Переменная в Си - это ящичек, куда вы что-то можете положить. В том числе в ящичке может лежать ссылка на другой ящичек.
В питоне переменная больше похожа на ярлычок, привязанный к объекту. Число, строка, список, словарь, класс, инстанс класса, None, ... - всё это объекты и они лежат где-то в памяти.
Какие-то объекты мутабельны, какие-то иммутаельны, но это не важно. У любого объекта может быть много ярлычков (например имен). Также ярлычком будет элемент списка, ключ или значение в словаре и т.д.
От обычного указателя в си это отличается тем, что его не нужно разыменовывать, чтобы обратиться к объекту. Употребляем имя - подразумеваем значение. Присвоение перевешивает ярлычок, удаление удаляет ярллычок.
Да, чем-то это смахивает на смартпоинтеры, но не полностью.
Да, в питоне не принято изменять мутабельные входные параметры. По крайней мере можно яно скопировать мутабельный объект поверхностно или глубоко. Для этого есть специальные методы или функция copy.

Ох и предстоит вам еще поудивляться побочному эффекту мутабельности в дефолтных значениях аргументов функций.

Подавите свои амбиции и прочитайте хотя бы бегло какую-нибуь книжку по питону. Вам можно даже не шибко детскую.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
leahch
@leahch
3D специалист. Dолго, Dорого, Dерьмово.
Но есть нюансы, Dr. Bacon ! Увы, copy, и прочие ухищрения не помогают - нужно делать deepcopy, а это очень и очень накладно бывает....

Поэтому я и ушел в clojure :)

>>> a = [[1,2,3], [11,12,13], [22,33,44]]
>>> a[1][1]
12
>>> b = a[:] # копируем!
>>> b[1][1]=0
>>> b
[[1, 2, 3], [11, 0, 13], [22, 33, 44]]
>>> a
[[1, 2, 3], [11, 0, 13], [22, 33, 44]]
>>>
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы