20231230 파이썬 리스트 복사

Copy

파이썬에서 =로 진행되는 일반적 복사.

  • listB = listA listB를 listA를 copy(=)해서 만들었을 때, listB의 수정사항이 listA에도 반영됨.
>>> listA = ["ABC", "DEF"]

>>> listB = listA

>>> listB.append("GHI")

>>> print(listA)
["ABC", "DEF", "GHI"]

따라서 단순히 =로 복사하는 경우에는 문제가 발생 할 수 있다.

Shallow Copy

위와 같은 문제가 발생하는 이유는 리스트가 변형 객체이기 때문이다.
따라서 리스트와 같은 변형 객체에서는 다른 방법으로 복사를 해야 listB를 수정해도 listA가 바뀌지 않게 된다. 이 때 사용하는 것이 shallow copy(얕은 복사)이다.

shallow copy에는 두가지 방법이 있다.

  • listA.copy()
  • listA[:]
>>> listA = ["ABC", "DEF"]

>>> listB = listA.copy()

>>> listB.append("GHI")

>>> print(listB)
["ABC", "DEF", "GHI"]

>>> print(listA)
["ABC", "DEF"]

이렇게 shallow copy를 하게 되면 listB를 수정해도 listA에는 수정사항이 반영되지 않는다.

하지만 shallow copy에도 문제점이 존재하는데, listA와 listB는 shallow copy를 했기 때문에 다른 객체를 가리키게 되지만 listA와 listB안에 존재하는 요소들은 서로 같은 특징을 갖는다는 것이다.
즉, 리스트는 shallow copy가 되지만, 리스트안의 요소가 변형 객체(ie. 리스트)였다면 그 요소는 그냥 copy된다.

>>> listA = ["ABC", ["DEF","GHI"]]

>>> listB = listA.copy()

>>> listB[1][0] = ["GHI"]

>>> print(listA, listB)
["ABC", ["GHI","GHI"]] ["ABC", ["GHI","GHI"]]

이렇게 listA 안에 변형 객체인 리스트로 값을 넣어두고 복사한 listB에서 변경하게 되면 그 수정사항이 listA에도 반영되어 변경된다.

Deep Copy

shallow copy에서 발생하는 문제점을 해결한 것이 deep copy(깊은 복사)이다.
객체의 변형성에 따라 불변형 객체는 그대로 가져오고 변형 객체는 새로운 공간에 값을 복사하여 가져와 어느 한 쪽을 수정하더라도 다른 쪽에 영향을 주지 않게 된다.
deep copy는 copy 모듈을 import해서 사용할 수 있다.

  • copy.deepcopy(listA)
>>> import copy

>>> listA = ["ABC", ["DEF","GHI"]]

>>> listB = copy.deepcopy(listA)

>>> listB[1][0] = ["GHI"]

>>> print(listA, listB)
["ABC", ["DEF","GHI"]] ["ABC", ["GHI","GHI"]]

이렇게 listB의 변형 객체 요소를 수정해도 listA에는 반영되지 않는 것을 알 수 있다.

# 동일한 객체인지 판별

>>> listA is listB
False

>>> listA[0] is listB[0]
True

>>> listA[1] is listB[1]
False

deep copy의 경우 완벽한 복사를 할 수 있지만 새로운 곳에 값을 복사하여 가져오는 것이기 때문에 시간이 오래 걸리고 메모리를 많이 사용한다는 단점이 존재한다.
그래서 항상 deep copy를 사용하는 것이 아니라 상황에 따라서 shallow copy도 같이 사용하게 된다.

Categories:

Updated:

Leave a comment