Почему это не назначить копию - PullRequest
1 голос
/ 02 августа 2011

У меня есть следующий код, и мне интересно, почему он возвращает тот же список вместо копии:

x = [2,1,3]
y = x
y.sort()
print y
print x

Почему это возвращает тот же отсортированный список?

Ответы [ 6 ]

5 голосов
/ 02 августа 2011

Потому что он модифицирован на месте.

Списки Python имеют ссылочную семантику, что означает, что когда вы назначаете список другой переменной, они фактически указывают на тот же список.

Если вы хотите сделать копию, сделайте следующее:

x = [2,1,3]
y = x[:]
y.sort()
print y
print x

Запись slice действительно приводит к тому, что список (в данном случае весь список, хотя вы можете сделать небольшую модификацию, чтобы запросить определенный подсписок) будет скопирован.

4 голосов
/ 02 августа 2011

Вы имеете дело с ссылками в Python. Оператор y = x заставляет y указывать на то же самое, что и x, поэтому изменения в y отражаются в x (поскольку они указывают на один и тот же базовый список).

Вы можете изменить копию, выполнив:

y = list(x) # make a copy of the list so we can change y without disturbing x
y.sort()

или

y = sorted(x) # return a new sorted copy of what is in x
2 голосов
/ 02 августа 2011

x - это имя («ссылка на») списка (объекта). Линия

y=x

просто делает у вас другое имя для того же списка. Если вы хотите скопировать список, используйте один из

y = x[:]
y = list(x)

(Первый синтаксис - просто обычный фрагмент списка, но с пропущенными начальными и конечными значениями, что означает, что он занимает весь список.)

Обратите внимание, что список - это список объектов, и копирование списка не приведет к копированию объектов. Если вам нужно такое поведение - копия deep - вы должны сделать это явно с

import copy
y = copy.deepcopy(x)

Естественно, это будет медленнее.

0 голосов
/ 02 августа 2011

Когда вы говорите y = x, вы просто назначаете другое имя (y) содержимому x. Если x является изменяемым значением и вы что-то делаете для его изменения, вы изменяете единственную копию с двумя разными именами.

Распространенный способ предотвратить это - присвоить фрагменту, который всегда является копией исходного списка.

y = x[:]
0 голосов
/ 02 августа 2011

Поскольку вы копируете только ссылку.

Инструкции по клонированию списка («глубокое копирование») см. В Как клонировать или скопировать список?

0 голосов
/ 02 августа 2011

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

y = x[:]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...