# 2차원 리스트 초기화 (모두 동일한 요소로)
num_rows = 3
num_cols = 4
initial_value = 0 # 초기화할 값
# 방법 1: 중첩된 리스트 컴프리헨션 사용
my_2d_list = [[initial_value for _ in range(num_cols)] for _ in range(num_rows)]
paper = [[0]*num_cols]*num_rows
# 방법 2: 반복문을 사용한 초기화
my_2d_list = []
for _ in range(num_rows):
row = [initial_value] * num_cols
my_2d_list.append(row)
# 결과 출력
for row in my_2d_list:
print(row)
#############################################
#잘못된 방식
paper = [[0]*100]*100 #객체를 참조하는 리스트가 만들어짐 (C언어 배울 때 사용하는 것)
"""
+--------------------------+
| [0, 0, 0, ..., 0] | <- 참조
| [0, 0, 0, ..., 0] | <- 참조
| [0, 0, 0, ..., 0] | <- 참조
| ... |
+--------------------------+
↑
참조 (100번 반복)
"""
# 설명 : 리스트를 복사하는 것이 아니라, 같은 행을 100번 반복한 리스트를 생성 -> 각 행은 동일한 객체를 참조 -> 한 행을 수정하면 다른 행에도 같은 변경이 반영
#############################################
# 올바른 방식
#1.
paper = [[0]*100 for _ in range(100)]
#2.
paper = [[0 for _ in range(100)] for _ in range(100)]
"""
+--------------------------+
| [0, 0, 0, ..., 0] | <- 참조
| [0, 0, 0, ..., 0] | <- 참조
| [0, 0, 0, ..., 0] | <- 참조
| ... |
+--------------------------+
↑ ↑ ↑ ↑
참조 참조 참조 참조
"""
#############################################
# => 파이썬 '가변' & '불변' 객체 차이
# 가변 객체 (객체 내용 변경 가능) ex. 딕셔녀리, 리스트
# 불변 객체 (객체 내용 변경 불가능) ex. 정수ㅡ 문자열
# 리스트 초기화시
# 1. '*' 연산자 사용 -> 같은 객체 참조
# 2. comprehension 사용 -> 각 요소 독립적인 객체 참조
#+) list comprehension 일반적인 구조
# [표현식 for 항목 in iterable if 조건] (*조건문은 필요시에만 사용)
#############################################
# list comprehension vs '*'
# 1.연산자:
# 리스트를 반복하여 새로운 리스트를 생성합니다.
# 모든 요소가 동일한 객체를 참조합니다.
# 1차원 리스트의 경우: [0] * 10은 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]을 생성합니다.
# 2차원 리스트의 경우: [[0] * 3] * 4는 4개의 행이 각각 동일한 [0, 0, 0] 리스트를 참조합니다.
# 2. 리스트 컴프리헨션:
# 새로운 리스트를 만들기 위해 반복문과 조건문을 사용합니다.
# 각 요소가 독립적인 객체를 참조하게 만들 수 있습니다.
# 차원 리스트의 경우: [0 for _ in range(10)]은 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]을 생성합니다.
# 2차원 리스트의 경우: [[0 for _ in range(3)] for _ in range(4)]는 4개의 행이 각각 독립적인 [0, 0, 0] 리스트를 참조합니다.
# 따라서,
# 리스트 컴프리헨션 = 각 요소를 독립적으로 생성하여 리스트를 만들어냄
# * 연산자 = 요소들이 동일한 객체를 참조하는 리스트를 반복적으로 생성
#############################################
# 얕은 복사 & 깊은 복사
# 1. 얕은 복사 : 객체 복사 하지만 내부 객체는 동일한 참조 유지
# 2. 깊은 복사 : 객체와 내부 모두 복사
#############################################
####### 결론 #######
# 우리가 아는 일반적인 리스트를 만들고 사용하기 위해서는 리스트 comprehension을 이용해 생성하자