brunch

You can make anything
by writing

C.S.Lewis

by crtlife noah Jun 29. 2023

파이썬 이상한 리스트 초기화 예제 분석

일단 아래와 같은 리스트 초기화 예제는 많이 알고 있을 것이다. 


[실험 코드]


size_x = 3

list = [0] * size_x

print(list)


[결과]

[0, 0, 0]


그러면 문득 위의 리스트 초기화 예제를 응용하다가 아래와 같은 잘못된 이차원 리스트 초기화를 시도할 수 있다.


[실험 코드]


size_x = 3

size_y = 3

list = [[0] * size_x] * size_y

print(list)


[결과]

[[0, 0, 0], [0, 0, 0], [0, 0, 0]]



결과만 보면 우리가 의도한 방식대로 출력되었기 때문에 문제가 있다고 생각하지 않을 수 있다. 그러나 위의 코드에서 특정 위치의 값을 변경해 보면 의도한 내용과 달리 결과가 이상함을 알 수 있다.


[실험 코드]


size_x = 3

size_y = 3

list = [[0] * size_x] * size_y

list[0][0] = 1

print(list)


[결과]

[[1, 0, 0], [1, 0, 0], [1, 0, 0]]


잠시 설명을 읽기 전에 왜 이렇게 결과가 나왔는지 진짜로 이렇게 결과가 나오는지 생각해 보자.



.


..


...


....


.....


......


.......


........


.........


잘 모르겠다면 아래 힌트 키워드를 참조하여 다시 한번 생각해 보자.


[힌트 키워드]

파이썬에서 함수 인자 전달 방식, Mutable, Immutable


충분히 생각을 해보았다면 내가 추론한 이유에 대하여 설명을 시작하도록 하겠다.


일단 초기 코드에서 [0] * size_x가 하는 일에 대해서 알아보자. 


편의를 위해 간단한 코드로 초기화를 가능하게 하고 있지만 해당 코드가 호출될 때 초기화를 시켜주는 일정한 루틴이 호출되게 될 것이다. 결과를 가지고 해당 루틴에 대해서 유추해 보면 아래의 과정을 진행할 것이다. 


- 앞의 list([0]) 안에 있는 값(0)을 size_x번만큼 복사하여 list에 추가한다.


그렇다면  [[0] * size_x] * size_y가 하는 일에 대해서 알아보자. [0]*size_x의 동작은 이미 알아보았기 때문에 해당 부분을 풀어서 [[0,0,0]] *size_y가 하는 일에 대해서 알아보자.


- 앞의 list([[0,0,0]]) 안에 있는 값([0,0,0])을 size_y번만큼 복사하여 list에 추가한다.


이 과정에서 의도한 다른 코드를 작성한 이유는 list의 안에 있는 값을 잘못 인식했기 때문이다. 해당 코드를 사용한 사람은 Immutable 한 [0, 0, 0]이라는 값이 존재할 것이라고 생각했을 했고 해당 값이 함수 전달 방식에서 call by value로 전달되어서 잘 처리되었을 것이라고 생각했을 것이다. 그런데 실제로 생각해 보면 [0, 0, 0]은 Mutable 한 list 객체이고 해당 객체가 전달되게 되면 call by reference로 전달되기 때문에 list의 결과로 동일한 list가 전달되어 저장되게 된다.


해당 설명이 어려운 사람은 파이썬의 함수 전달 방식에 대해서 좀 더 공부해 보면 쉽게 이해할 수 있을 것이다. 다시 한번 예제를 통해서 설명하면 정확히 동일한 동작을 하는 코드는 아니지만 아래와 같은 코드를 동작시킨 것으로 생각하면 된다.


[실험 코드]


mutable_list_object = [0, 0, 0]

list = []

list.append(mutable_list_object)

list.append(mutable_list_object)

list.append(mutable_list_object)

list[0][0] = 1

print(list)


[결과]

[[1, 0, 0], [1, 0, 0], [1, 0, 0]]

 









매거진의 이전글 사람의 관점에서 보는 프로그래밍 언어의 소수점
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari