on1ystar 머릿속을 정리, 기록하는 곳

Python 2차원 리스트 초기화 방법


python은 다른 언어보다는 간편하게 2차원 리스트를 초기화 할 수 있는데, 기존에 알고 있던 방식에 치명적인 오류가 있었다.

기존에 알고 있던 방식

# N x M 크기의 2차원 리스트
n = 3
m = 3
li = [[0]*m]*n
print(li)

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

큰 문제가 없어 보이지만 특정 인덱스 값을 변경해 보면 예상과는 다른 결과가 나온다.

li[2][2] = 3
print(li)

# [[0, 0, 3], [0, 0, 3], [0, 0, 3]]

li[2][2]의 값만 변경된 것이 아니라 li[0][2], li[1][2], li[2][2] 의 값, 즉 행렬로 나타내면 3열의 값이 모두 변경됬다. 이는 내부적으로 포함된 3개의 리스트가 모두 동일한 객체에 대한 3개의 레퍼런스로 인식되기 때문이다.

>>> li[0] is li[1]
True
>>> id(li[0])
140304626835328
>>> id(li[1])
140304626835328

따라서 리스트 컴프리헨션을 사용한 초기화 방법이 옳은 방법이다.

옳은 방법

n = 3
m = 3
li = [[0]*3 for _ in range(n)]
print(li)

li[1][1] = 3
print(li)

# [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
# [[0, 0, 0], [0, 3, 0], [0, 0, 0]]

id값 역시 각 리스트가 고유의 값를 가지게 된다.

>>> li[0] is li[1]
False
>>> id(li[0])
140304569869440
>>> id(li[1])
140304569868992


Reference

이것이 취업을 위한 코딩 테스트다 - 나동빈