Копирование списков питонов

Просто когда я подумал, что понял, как работают списки Python...

>>> a = [1,2,3]
>>> b = a[:]
>>> b
[1,2,3]
>>> b[1]=100
>>> b
[1,100,3]
>>> a
[1,2,3]

Все идет нормально. Я инициализирую b содержимым a, так что b указывает на другой объект. Как следствие, изменения в b не влияют на a.

Теперь взгляните на этот другой пример:

>>> a = [[1,2,3],[4,5,6],[7,8,9]]
>>> b = a[:][:]
>>> b
[[1,2,3],[4,5,6],[7,8,9]]
>>> b[1][1] = 100
>>> b
[[1,2,3],[4,100,6],[7,8,9]]
>>> a
[[1,2,3],[4,100,6],[7,8,9]]

Почему изменение b повлияло на a на этот раз? Чем отличается от предыдущего примера?

3 ответа

Решение

Операция нарезки x[:] делает мелкую копию. Это означает, что внешний список отличается, но содержит точно такие же элементы. предполагать a = [[1]]:

b = a[:] # is the same as:
b = [x for x in a]

>>> a[0] is b[0]
True

Двойная нарезка ([:][:]) больше ничего не делает - опять

b = a[:][:] # is the same as:
b = [y for y in [x for x in a]]

>>> a[0] is b[0]
True

Мелкая копия мелкой копии, ну, в общем, мелкая копия.

Так b все еще мелкая копия a - эти списки являются разными объектами, но содержат одинаковые элементы. Затем вы изменяете внутренний список в b, но это тот же список в a,

2-уровневая мелкая копия может быть сделана с b=[x[:] for x in a], Это распространяется так же для копирования n-уровня.

Кстати, термин "мелкая копия" имеет одинаковое значение для любого класса или контейнера.

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

Silcing [:] делает неглубокую копию. но внутренние объекты остаются не скопированными, поэтому, если они изменчивы, и вы их измените, они будут изменены;) и в обоих списках вы увидите это

использовать список понимания

b = [i[:] for i in a]

или copy.deepcopy()

import copy
b = copy.deepcopy(a)

Попробуй это:

In [38]: import copy

In [39]: a = [[1,2,3],[4,5,6],[7,8,9]]

In [40]: b=copy.deepcopy(a)

In [41]: b[1][1] = 100

In [42]: a
Out[42]: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

In [43]: b
Out[43]: [[1, 2, 3], [4, 100, 6], [7, 8, 9]]

Читать дальше @ http://docs.python.org/2/library/copy.html

Другие вопросы по тегам