빈 리스트가 N개 나열된 중첩리시트를 만들고 싶어서 다음과 같은 코드를 실행했더니 엄청난 오류가 생겼다.
# N은 임의의 정수
answer_lst = [[]] * N
answer_lst[0] = ['1']
# print(answer_lst) # for문 돌기 전 리스트 상태 : [['1'], [], []]
for i in range(N):
answer_lst[i].append('1')
print(i, '번째')
print('answer_lst[i]:', answer_lst[i])
print('answer_lst:', answer_lst)
# 출력값
# 0 번째
# answer_lst[i]: ['1', '1']
# answer_lst: [['1', '1'], [], []]
# 1 번째
# answer_lst[i]: ['1']
# answer_lst: [['1', '1'], ['1'], ['1']]
# 2 번째
# answer_lst[i]: ['1', '1']
# answer_lst: [['1', '1'], ['1', '1'], ['1', '1']]
# [['1', '1'], ['1', '1'], ['1', '1']]
문제는 리스트 복사와 얕은 복사(shallow copy)때문이다.
answer_lst는 [[], [], []]처럼 보이지만, 실제로는 같은 리스트 객체를 세 번 참조하고 있다.
즉, 내부 리스트 []는 하나만 생성되고 , 그 참조가 여러 번 반복된 것이다.
answer_lst = [[]] * N
print([id(lst) for lst in answer_lst])
위 코드를 실행하면 같은 id값이 세 번 출력된다.
즉, answer_lst[0]을 변경하면 answer_lst[1]과 answer_lst[2]도 함께 바뀌는 것.
하지만, 다음과 같이 리스트가 아니라 숫자 0을 반복하는 것은 괜찮다.
answer_lst = [0] * 9
answer_lst[0] = 1 # 첫 번째 요소만 변경
print(answer_lst)
# [1, 0, 0, 0, 0, 0, 0, 0, 0] ✅
왜냐하면,
리스트 [ ] 는 mutable(가변 객체) 를 * 연산자로 복제하면 모두 같은 리스트를 참조하지만,
숫자 0과 같은 immutable(불변 객체) 는 서로 영향을 주지 않는다.
📌 결론
- [0] * 9 같은 immutable(불변 객체)는 안전 → 각각 독립적인 정수 값
- [[]] * 3 같은 mutable(가변 객체)는 문제 발생 → 동일한 리스트 객체를 참조
- 리스트나 딕셔너리 같은 가변 객체를 여러 개 만들려면 for 문이나 리스트 컴프리헨션을 사용해야 함.
따라서 다음과 같이 만들어야한다.
answer_lst = [[] for _ in range(N)]
728x90
'Python' 카테고리의 다른 글
[Python] all 함수 (0) | 2025.04.11 |
---|---|
[Python] sys.setrecursionlimit() (재귀 깊이 제한 설정) (0) | 2025.04.06 |
[파이썬] 큐(Queue) (0) | 2025.01.24 |
[파이썬] Django, Flask, FastAPI (0) | 2025.01.01 |
[파이썬]dictionary의 value의 최대값, 최소값의 key 값 찾기 (0) | 2024.12.12 |