2016-01-15 9 views
2

Я новичок в Python и только что узнал о изменяемых и неизменяемых объектах. Похоже, что когда мы меняем элементы внутри списка, Python создает копии отдельных элементов, а затем копирует их обратно в список.Как Python меняет элементы внутри списка?

enter image description here

В приведенном выше примере, мы начинаем с n = [[1, 2], [3, 4]]. Первый подписок, [1, 2] занимает номер ID 24, а второй подписок [3, 4] занимает ID # 96. Сначала я думал, что, поскольку списки изменяемы, после замены, ID # 24 содержит [3, 4] и ID # 96 проводит [1, 2]. Но, как мы видим в вышеприведенном тесте, это не так. Скорее, Python указывает на объекты способом, определенным нашим свопом; первый слот списка указывает на 96, а второй слот указывает на 24.

Конечно, идентификатор № n не изменился, поэтому n не нарушил определение изменяемого объекта. Но способ, которым подсекреты были заменены, кажется, является оговоркой. Можете ли вы любезно подтвердить или объяснить более точный язык?

+2

Пожалуйста, не используйте изображения. Вместо этого вставьте свой код в виде текста и используйте уценку для правильного форматирования. –

+0

Когда я попытался это исправить, я понял, почему вы предпочитаете текст поверх изображения. Хорошо, в следующий раз. –

ответ

2

От documentation:

Назначение объекта к целевому списку рекурсивно определена следующим образом.

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

Если вы читали, что внимательно, вы увидите, что у вас есть сценарий:

target_list = expression_list 

Список выражение вычисляется первый и оценивает в кортеж:

Оператор присваивания оценивает список выражений (помните, что это может быть одно выражение или список, разделенный запятыми, последний из которых имеет кортеж)

Так что если у вас есть:

a = [1, 2] 
a[1], a[0] = a[0], a[1] 

Это эффективно, как писать следующее:

a = [1, 2] 
temp = (a[0], a[1]) # Expression list evaluates to tuple. 

# target_list assignment to corresponding elements from expression list. 
a[1] = temp[0] 
a[0] = temp[1] 
+0

Извините за поздний ответ. Кортеж 'temp' является объектом вне' a'. Как первый и второй слот в 'a' относятся к кортежу? В частности, я хочу узнать, если после замены первый и второй слоты в списке 'a' указывают на значения, хранящиеся в кортеже' temp', или Python перезаписывает адрес памяти первой и второй партии новыми значениями. –

+0

Если я правильно понимаю ваш вопрос и если вы хотите подумать о списках Python в терминах структур данных C - список «python» представляет собой массив C указателей на «PyObjects». Когда вы меняете элементы в списке, вы перенацеливаете эти указатели. Отвечает ли это на ваш вопрос? – mgilson

3

Вы ошибаетесь об идентификаторах. Идентификатор № 24 - это идентификатор списка [1,2]. Это НЕ адрес памяти или идентификатор индекса 0 в n.

Вы можете попробовать пример, как это подтвердить:

>>> x = [1, 2] 
>>> id(x) 
4332120256 
>>> l = [x, 3] 
>>> id(l[0]) 
4332120256 
>>> 
+0

Итак, когда я написал 'n = [[1, 2], [3, 4]]', как в приведенном выше, у меня нет доступа к ID первого слота 'n'? В отличие от того, что вы сделали, я никогда не назначал имя для первого слота .... –

+0

Насколько я знаю, нет никакого способа сделать это. Тот факт, что вы не присвоили имя, не имеет значения. – LIProf

Смежные вопросы