spark_1130   2년 전

preview

3차원 배열을 만들었을 때, row => col => floor 순서로 가서 결과론적이게 맨 처음 나타나는 0만 1이 되어야 할텐데, 왜 전부 1이 되는지 궁금해요.

감사합니다!

recoma   2년 전

전부 1로 변하는 이유는 구조체(list, dict, set, etc..)를 담고 있는 리스트를 * 연산자로 복사하려고 했기 때문입니다. 예를 들어

a = [[0, 0, 0]] * 3

이란 코드는 3x3 크기의 2차원 배열을 선언하는 것 처럼 보입니다.

하지만 a[0], a[1], a[2]의 id값을 확인해 보면 다음과 같이 출력 됩니다.

>>> a = [[0, 0, 0]]*3
>>> id(a[0]), id(a[1]), id(a[2])
(2391336078272, 2391336078272, 2391336078272)

id값이 전부 동일하게 나오는데 이는 똑같은 리스트를 참조하고 있다는 의미가 됩니다. 그렇기 때문에 이 상태에서 a[0][0]의 값만 변경하고 싶어도 a[0], a[1], a[2]는 같은 리스트이기 때문에 a[1], a[2]도 아래와 같이 바뀌게 됩니다.

>>> a
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]
>>> a[0][0] = 1
>>> a
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]

이러한 현상이 일어나는 이유는 * 연산자를 이용해 복사를 할 때, [[0, 0, 0]]나 [{1:0, 2:1, 3:1}] 같이 구조체 형태를 담고 있는 배열을 복사를 하게 되면, 그 구조체 안의 데이터를 하나하나 복사를 하는 것이 아니라 id값만 복사를 하기 때문입니다.

이러한 문제를 해결하려면 소스코드 처럼 for문을 이용해서 다중 배열을 선언해야 합니다. 이러한 방식을 list comprehension 이라고 합니다.

a = [[0] * 3 for _ in range(3)] 또는 a = [[0, 0, 0] for _ in range(3)]

이전에도 백준 게시판에서 비슷한 개념의 질문이 올라와서 답변을 해 드린 적이 있습니다. 아래 두 개의 링크도 참고하시면 좋을 것 같습니다.

https://www.acmicpc.net/board/...

https://stackoverflow.com/ques...

댓글을 작성하려면 로그인해야 합니다.