파이썬(Python)

[ Basic ] 파이썬 리스트 데이터타입, 파이썬 리스트 복사하기

카루루1007 2022. 9. 20. 23:27
728x90
반응형
SMALL
◆ 리스트와 튜플의 데이터 타입

앞에서 언급한 리스트와 튜플은 어떤 데이터 타입이라도 포함할 수 있습니다.

그 말은 튜플이 리스트를 포함할 수도

리스트가 튜플을 포함할 수도 있다는 의미입니다.

물론 리스트 안에 리스트를 넣을 수도 있고

튜플 안에 튜플을 넣을 수도 있습니다.

a = [ 1, 2 ]
b = [ 3, 4 ]
print(type(a), type(b))

위 코드를 실행해 보면 a, b 모두 리스트라는 것을 확인할 수 있습니다.

a = [ 1, 2 ]
b = [ 3, 4 ]
c = [ a, b ]
print(type(a), type(b), type(c))

위 코드에서 c 역시 리스트입니다.

그럼 c 에는 어떤식으로 값이 들어있는지 살펴보겠습니다.

a = [ 1, 2 ]
b = [ 3, 4 ]
c = [ a, b ]
print(c)

위 코드를 실행하면 다음과 같이 결과가 나타납니다.

[[1, 2], [3, 4]]

즉 c는 a, b를 리스트 형태로 포함하고 있습니다.

앞서 리스트에 포함된 값은 모두 위치번호를 가지고 있다고 말씀드렸습니다.

c에 포함된 값들의 위치번호는 어떻게 되어있는지 살펴보겠습니다.

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

print(c[0][0], c[0][1], c[1][0], c[1][1])

위 코드를 실행하면 1 2 3 4 가 출력됩니다.

위치 0 1
0 1 2
1 3 4

위 표처럼 c[0]은 [ 1, 2 ]라는 리스트를 가지고 있고

c[1]은 [ 3, 4 ]라는 리스트를 가지고 있습니다.

그리고 그 안에서 위치값이 다시 배정되어 있는 배열의 형태입니다.

 

◆ 리스트의 복사

먼저 코드를 살펴보겠습니다.

a=1
b=a
print(b)
a=5
print(b)

위 코드는 a에 1이라는 값을 할당하고

b에 a를 복사합니다.

b를 출력하면 1이라는 결과가 나타나고

a를 5로 바꾼 후 b를 출력하면 역시 1이라는 결과가 나타납니다.

변수 a의 값 변화가 b에 영향을 주지는 않습니다.

 

하지만 리스트는 이야기가 조금 다릅니다.

list1 = [ 1, 2, 3]
list2 = list1

list1[1] = 4
print(list1, list2)

list1은 [ 1, 2, 3 ]이라는 값을 가지고 있습니다.

동일하게 list2에 list1을 복사한 후

list2를 출력하면 [ 1, 2, 3 ]이라는 결과가 나타납니다.

여기서 list1의 값 중 하나를 4로 변경한 후

list1, list2를 모두 출력하면 

똑같이 [ 1, 4, 3 ]이라는 결과가 나타납니다.

하나의 리스트의 값을 변경하게 되면

나른 리스트의 값에도 영향을 미칩니다.

 

파이썬에서 리스트를 위와 같이 사용하면

list1의 값을 list2에 복사하는 것이 아닌

list1이라는 리스트에 할당되어있는 메모리의 주소를

list2에 복사하는 것이 됩니다.

결과적으로 똑같은 장소를 2개의 이름으로 부르는 것이 됩니다.

결국 두개의 이름이 가리키는 곳이 같기 때문에

하나의 내용을 바꾸면 다른 하나의 내용까지 바뀐 것 처럼 보이게 됩니다.

 

다시말해 list1에 포함된 값들이 저장된 컴퓨터상의 주소를 임의로 100이라고 가정하면

list1을 list2에 복사했을 때

list2에는 컴퓨터상의 다른 주소에 값이 복사되는 것이 아닌

list1의 주소인 100을 함께 가리키게 됩니다.

 

이는 파이썬의 내장함수인 id()를 사용하면 확인이 가능합니다.

id()함수는 입력받은 객체의 주소값을 반환하는 함수입니다.

list1 = [ 1, 2, 3]
list2 = list1

list1[1] = 4
print(id(list1), id(list2))

위 코드의 결과는 2707285214144 2707285214144 입니다.

위 결과의 값은 주소값이기 때문에 다르게 나타날 수 있습니다.

 

리스트의 값을 복사하려면 다음과 같이 코드를 작성하여 사용할 수 있습니다.

list1 = [ 1, 2, 3 ]
list2 = list1[:]
print(id(list1), id(list2))

위 코드는 리스트1의 각각의 값을 list2로 복사하라는 의미입니다.

두개의 리스트의 주소값을 살펴보면 다음과 같이 다르게 나타나는 것을 알 수 있습니다.

1760780812352 1760780813888

 

list1 = [ 1, 2, 3 ]
list2 = list1[:]

list2[0] = 9
print(list1, list2)

그렇기 때문에 이런식으로 복사할 경우

하나의 리스트의 값을 바꾸더라도 다른 리스트의 값에는 영향을 주지 않게 됩니다.

 

하지만 리스트가 다른 리스트를 품고 있다면 이야기가 달라지게 됩니다.

list3 = [[1,2], [3, 4]]
print(id(list3), id(list3[0]), id(list3[1]))

list4=list3[:]
print(id(list4), id(list4[0]), id(list4[1]))

먼저 위 코드의 결과값은 다음과 같습니다.

1365873310976 1365873311360 1365873394560
1365873306944 1365873311360 1365873394560

lis3은 [ 1, 2 ]와 [ 3, 4 ] 두개의 리스트를 가지고 있습니다.

이를 list4에 위 코드와 같이 복사면

list3과 list4의 주소값은 다르지만, 

그 안에 포함된 리스트의 주소값은 동일합니다.

즉, 리스트 안에 리스트가 있을 경우 위와 같이 복사를 하게되면

하나의 리스트를 변경하였을 때 다른 리스트에도 영향을 끼치게 됩니다.

list3 = [[1,2], [3, 4]]
list4=list3[:]

list4[0][0] = 9
print(list3)

위 코드처럼 list4의 값 중 하나를 변경하고 list3을 출력하면 

[[9, 2], [3, 4]] 과 같은 결과가 나타납니다.

 

참고로 위 코드에서

list4=list3[:] 는 list4=list3.copy()

와 동일합니다.

 

그러면 순수하게 값만을 복사하려면 어떻게 하는 지 살펴보겠습니다.

먼저 copy 모듈을 불러온 후 deepcopy() 함수를 사용하면 값을 복사할 수 있습니다.

import copy

list3 = [[1,2], [3, 4]]
list4=copy.deepcopy(list3)
list4[0][0] = 9
print(list3)

위 코드의 결과는 [[1, 2], [3, 4]] 입니다.

list4의 값을 바꾸더라도 list3에 영향을 미치지 않습니다.

 

마지막으로 [:] 또는 copy() 함수를 사용하여 하는 복사를 shallow copy

deepcopy() 함수를 사용하여 하는 복사를 deepcopy라고 부릅니다.

 

 

728x90
반응형
LIST