2015-10-30 2 views
-1

Я сделал эту строку кода:Каким .append() функция работы в питона

alist = [8,6,9,2,4] 

blist = [4,5,6] 

alist.append(blist) 

blist = [7,8,9] 

print(alist) 

Я, однако, что это будет печатать [8, 6, 9, 2, 4, [7, 8 , 9]], но он печатает [8, 6, 9, 2, 4, [4, 5, 6]]. Не выполняет ли функция .append() ссылку, но вместо этого добавляет глубокую копию?

+1

@MorganThrapp 'append' не делает копию. – jme

+0

@MorganThrapp * напротив * - это правда. –

+0

@MorganThrapp. Вместо записи 'b = [7, 8, 9]', попробуйте 'b.append (42)'. – jme

ответ

1

blist = [7,8,9] не мутировать объект ссылается blist. Скорее, имя blist теперь относится к новому объекту. Старый объект все еще существует как последний элемент alist.

>>> alist = [8,6,9,2,4] 
>>> blist = [4,5,6] 
>>> alist.append(blist) 
>>> id(blist) 
37490560 
>>> id(alist[-1]) # should be the same as blist 
37490560 
>>> blist = [7,8,9] # blist now refers to a new object 
>>> id(blist) # its a new object so the id is different 
71420104 
>>> id(alist[-1]) 
37490560 

Ваша ментальная модель, кажется, это: alist[-1] относится к blist, который относится к объекту [4,5,6]. Если бы эта модель была правильной, то blist = [7,8,9] сделало бы alist[-1] ссылкой на новое значение blist.

Однако эта модель неправильная. alist.append(blist) не делает последний элемент alist относится к blist. Это делает последний элемент ссылкой непосредственно на объект, который blist ссылается на момент добавления к alist. Название blist не является звеном в цепочке в отношениях между alist[-1] и [4,5,6]. Вот почему присвоение blist не влияет на содержимое alist.

Для подробного обсуждения этого вопроса см. Facts and myths about Python names and values от Ned Batchelder.

+0

Это имеет большой смысл. Спасибо! –

0

Нет, вы неправильно поняли ссылки и копии. На самом деле, противоположность тому, что вы говорите, истинно; append добавит ссылку на то, что в настоящее время находится в blist. Но это содержание blist, а не само имя, являющееся ссылкой; поэтому, если позже вы измените то, что назначено blist, ссылка, которая также находится в alist, не будет затронута.

Однако, если вы мутировали содержимое, которые будут затронуты:

alist.append(blist) 
blist[0] = 7 
print(alist) # => [8, 6, 9, 2, 4, [7, 5, 6]] 
Смежные вопросы