우리는 보통 * 기호를 곱셈을 나타내는 연산자로 익숙하게 사용합니다. 하지만 *의 왼쪽 피연산자가 리스트라면, 이 연산자는 반복 연산자(repetition operator)로 동작합니다. 반복 연산자는 리스트의 복사본을 여러 개 만들어 하나의 리스트로 이어 붙이는 역할을 하며, 이를 활용하면 간결하게 리스트를 생성할 수 있습니다.
기본 예제
가장 단순한 예제를 살펴보겠습니다.
numbers = [0] * 5 print(numbers)
출력 결과
[0, 0, 0, 0, 0]
[0]은 요소가 하나뿐인 리스트입니다. 반복 연산자는 이 리스트를 5번 복사한 뒤 모두 하나의 리스트로 합쳐서 반환합니다.
여러 요소를 가진 리스트 반복하기
요소가 여러 개인 리스트에도 동일하게 적용됩니다.
numbers = [0, 1, 2] * 3 print(numbers)
출력 결과
[0, 1, 2, 0, 1, 2, 0, 1, 2]
원래 리스트 [0, 1, 2]가 통째로 3번 반복되어 새로운 리스트가 만들어진 것을 확인할 수 있습니다.
주의: 얕은 복사(Shallow Copy) 문제
반복 연산자를 사용할 때 가장 중요한 점은 Python이 리스트의 얕은 복사(shallow copy)를 수행한다는 것입니다. 즉, 리스트 안에 들어 있는 객체 자체는 복사되지 않고 같은 객체에 대한 참조만 여러 번 반복됩니다.
따라서 다음과 같이 중첩 리스트를 만들 경우 문제가 발생할 수 있습니다.
matrix = [[0] * 3] * 2 matrix[0][0] = 99 print(matrix)
출력 결과
[[99, 0, 0], [99, 0, 0]]
의도와 달리 한 곳의 값을 변경했는데 두 행 모두 변경된 것을 볼 수 있습니다. 내부 리스트들이 실제로는 같은 객체를 참조하고 있기 때문입니다.
올바른 대안
이러한 동작을 원하지 않는다면 반복 연산자로 중첩 리스트를 만들지 말고, 리스트 컴프리헨션을 사용하는 것이 안전합니다.
matrix = [[0] * 3 for _ in range(2)] matrix[0][0] = 99 print(matrix) # [[99, 0, 0], [0, 0, 0]]
정리
*연산자는 왼쪽 피연산자가 리스트일 때 반복 연산자로 동작합니다.- 리스트 전체가 지정한 횟수만큼 복사되어 하나의 리스트로 연결됩니다.
- 복사는 얕은 복사이므로, 가변 객체(내부 리스트 등)를 포함한 리스트를 반복하면 참조가 공유됩니다.
- 독립적인 중첩 리스트가 필요하다면 리스트 컴프리헨션을 사용하세요.