2015-02-16 2 views
0

Привет, Я пытаюсь сделать функцию, которая проверяет наличие Palindromes, и я думал, что могу легко использовать функцию list.reverse(), но что-то странное происходит, и мне было интересно, почему. Вот мой код:Использование list.reverse() в копии меняет оригинал

x = list('hey') 
x 
['h', 'e', 'y'] 
y = x 
y 
['h', 'e', 'y'] 
y.reverse() 
y 
['y', 'e', 'h'] 
x 
['y', 'e', 'h'] 

Мой вопрос почему это, что, когда я реверс список у него также переворачивает лист х?

+1

Также см http://stackoverflow.com/questions/17331290/how- to-check-for-palindrome-using-python-logic – CoryKramer

+0

@Cyber: переустановил этот код на [Как изменить список в python?] (http://stackoverflow.com/q/3940128) –

+2

Это действительно обман? Я чувствую, что OP просто хочет знать, почему «x» также изменяется. –

ответ

2

x и y относятся к тому же местоположению памяти.

>>> x = [1,2,3] 
>>> id(x) 
141910924 
>>> y = x 
>>> id(y) 
141910924 
>>> z = list(x) 
>>> id(z) 
141676844 
>>> x.append(10) 
>>> x 
[1, 2, 3, 10] 
>>> y 
[1, 2, 3, 10] 
>>> z 
[1, 2, 3] 

использование копии и DeepCopy, когда мы хотим присвоить список значений других переменных например

>>> import copy 
>>> x = [1,2,3, [4,5]] 
>>> y = copy.copy(x) 
>>> id(x) 
141913324 
>>> id(y) 
139369964 
>>> x.append(10) 
>>> x 
[1, 2, 3, [4, 5], 10] 
>>> y 
[1, 2, 3, [4, 5]] 
>>> x[3].append(20) 
>>> x 
[1, 2, 3, [4, 5, 20], 10] 
>>> y 
[1, 2, 3, [4, 5, 20]] 
>>> z = copy.deepcopy(x) 
>>> z 
[1, 2, 3, [4, 5, 20], 10] 
>>> x[3].append(50) 
>>> x 
[1, 2, 3, [4, 5, 20, 50], 10] 
>>> z 
[1, 2, 3, [4, 5, 20], 10] 
>>> 
+1

и метод 'reverse()' мутирует список непосредственно –

+0

, добавляя к нему, вы можете использовать команду 'is', чтобы убедиться, что это действительно то же самое,' x = [1,2,3] '' y = [1,2,3] '' x is y' (это ложь), 'z = x'' z is x' (это правда) – TehTris

+0

Awesome !! Спасибо, ребята, это именно то, что мне нужно. –

-2

В Вивек сказал, y указывает на то же место, x. Чтобы обойти эту проблему, используйте deepcopy из copy модуля:

import copy 
x = list('hey') 
y = copy.deepcopy(x) 

Это гарантирует, что они указывают на отдельные места и являются независимыми.

Для тех, кто думает, что deepcopy это плохая идея, я решительно не согласен - рассмотреть этот код:

x = [45, 54] 
y = [x, 56] 
z = y[::] 
print z 
x[0] = 1 
print z 

Выход есть:

[[45, 54], 56] 
[[1, 54], 56] 

, потому что мелкая копия возвращает ссылки на элементы списка, где это возможно. Я просто пытаюсь научить OP универсальному методу создания полностью независимой копии - независимо от типа объекта, который они пытаются копировать.

Даже само виду объекты обрабатываются deepcopy:

>>> a = [2] 
>>> a.append(a) 
>>> a 
[2, [...]] 
>>> import copy 
>>> b = copy.deepcopy(a) 
>>> b 
[2, [...]] 
+0

На самом деле вам нужна только мелкая копия, например '[::]' или просто с помощью 'reverseed' –

+1

deepcopy почти всегда ошибочно –

+0

Да, в этом простом примере, где все элементы целые,' deepcopy' не нужно. Но если у вас есть список со встроенным списком, вам нужна глубокая копия. – texasflood

0

Копия x по значению, а не по ссылке

x = list('hey') 
x 
['h', 'e', 'y'] 
y = list(x) 
y 
['h', 'e', 'y'] 
y.reverse() 
y 
['y', 'e', 'h'] 
x 
['h', 'e', 'y'] 
Смежные вопросы