Вопрос-Ответ

Copying nested lists in Python

Копирование вложенных списков в Python

Я хочу скопировать 2D-список, чтобы, если я изменю один список, другой не был изменен.

Для одномерного списка я просто делаю это:

a = [1, 2]
b = a[:]

И теперь, если я изменяю b, a не изменяется.

Но это не работает для двумерного списка:

a = [[1, 2],[3, 4]]
b = a[:]

Если я изменяю b, a также будет изменено.

Как мне это исправить?

Переведено автоматически
Ответ 1

Для более общего решения, которое работает независимо от количества измерений, используйте copy.deepcopy():

import copy
b = copy.deepcopy(a)
Ответ 2
b = [x[:] for x in a]
Ответ 3

Что b = a[:] не работает для вложенного списка (или, скажем, многоразмерного списка)?


a = [[1, 2],[3, 4]]
b = a [:]


Ответ: Хотя, когда мы копируем список, a используя slicing[:] операцию, но внутренний вложенный список по-прежнему ссылается на внутренний вложенный список list b


Примечание: Мы можем проверить ссылку, используя id() в python.

Давайте разберемся на примере.

>>> a = [[1,2],[3,4]]
>>> id(a)
140191407209856 # unique id of a
>>> b=a
>>> id(b)
140191407209856
>>> b=a[:] # Copying list a to b with slicing
>>> id(b)
140191407209920 # id of list b changed & is not same as id of list a
>>> id(a[0])
140191407188544
>>> id(b[0])
140191407188544
>>> id(a[0])==id(b[0]) # id of both a[0] & b[1] is same.
True

Таким образом, нарезка не изменит ссылку на объекты внутри списка.
Вы можете заметить сверху, что ссылка на a[0] такая же, как b[0].

Когда вы копируете 2D-список в другой, добавляется ссылка на него, а не на сам список.


Вместо этого вы можете использовать:


  • b = copy.deepcopy(a)

  • b = [item[:] for item in a]

  • b = [item.copy() for item in a]

  • b = [list(item) for item in a]

  • b = [copy.copy(item) for item in a]

  • b = []; b.extens[a]

Ниже приведено сравнение временной сложности всех доступных методов копирования (исходный код)


  1. 10.59 сек (105.9us / itn) - copy.deepcopy(old_list)



  2. 10.16 сек (101.6us / itn) - чистый python Copy() метод копирования классов с помощью deepcopy



  3. 1.488 сек (14.88us / itn) - чистый python Copy() метод, не копирующий классы (только dicts / списки / кортежи)



  4. 0,325 секунды (3,25us / itn) - for item in old_list: new_list.append(item)



  5. 0.217 сек (2.17us / itn) - [i for i in old_list] (понимание списка)



  6. 0.186 сек (1.86us / itn) - copy.copy(old_list)



  7. 0.075 сек (0.75us / itn) - list(old_list)



  8. 0.053 сек (0.53us / itn) - new_list = []; new_list.extend(old_list)



  9. 0.039 сек (0.39us / itn) - old_list[:] (нарезка списков)



Ответ 4

Для двумерных вложенных массивов можно использовать следующее: b = [[y для y в x] для x в a]

2024-01-26 23:16 python list