Python 함수·객체·참조와 공통 알고리즘
이름의 재바인딩과 공유 객체의 변경을 구별한다.
실기 학습 목표
이름의 재바인딩과 공유 객체의 변경을 구별한다.
핵심 이론
a=b는 같은 객체를 가리키는 별칭을 만든다. a.copy()와 a[:]는 바깥 리스트만 복사하므로 중첩 리스트는 공유될 수 있다. [[0]*2]*3도 같은 내부 리스트를 반복 참조한다.
기본 인수 객체는 함수 정의 시 만들어져 호출 사이에 공유될 수 있다. def f(x=[]): 같은 코드에서 누적 변화를 추적한다. None을 기본값으로 두고 함수 내부에서 새 리스트를 만드는 방법과 비교한다.
람다는 표현식의 값을 반환하며 map은 함수를 각 원소에 적용하는 반복자를 만든다. class의 인스턴스 속성과 클래스 속성을 나눠 확인한다.
재귀는 종료 조건과 복귀 시점을 표시한다. 짧은 정렬·스택·큐·트리 코드는 자료구조 상태를 한 단계씩 갱신한다. 스택은 LIFO, 큐는 FIFO, 이진트리 전위·중위·후위는 루트 방문 위치가 각각 앞·중간·뒤다.
개념 도식
얕은 복사는 바깥 목록만 새로 만든다
a=[[1],[2]]; b=a.copy()는 바깥 리스트 두 개를 만들지만 안쪽 리스트는 공유한다. b[0].append(3)을 하면 a도 [[1,3],[2]]로 보인다. 이후 b[1]=[9]는 b의 두 번째 연결만 새 리스트로 바꾸므로 a의 두 번째 원소 [2]는 그대로다.
| 변경 | a에 보이는가 | 이유 |
|---|---|---|
| 공유 안쪽 리스트 append | 보임 | 같은 객체 내부 변경 |
| b의 특정 원소 재대입 | 그 연결 변경은 안 보임 | 별도 바깥 리스트의 칸 변경 |
함수의 기본 인수 객체는 함수를 정의할 때 만들어진다. 기본 리스트에 계속 append하는 예제는 호출 사이에 값이 누적될 수 있다. 매 호출마다 새 리스트를 만든 경우와 구별한다. 이 동작을 이해하는 것과 실무에서 가변 기본 인수를 권장하는 것은 별개다.
스택은 마지막에 넣은 것을 먼저 빼고, 큐는 먼저 넣은 것을 먼저 뺀다. 짧은 알고리즘 문제는 각 연산 뒤 자료구조 내용을 적고, pop 등의 반환값을 출력 칸으로 옮긴다. 재귀와 중첩 컨테이너를 함께 쓰면 호출별 지역변수와 공유 객체 표를 나눠 작성한다. 고급 알고리즘 설계나 외부 라이브러리 암기는 필요하지 않다.
풀이 예시
다음 Python 3.11 이상 프로그램이 표준 출력에 기록하는 내용을 쓰시오. 마지막 줄바꿈의 유무는 답안에서 구별하지 않는다.
a = [[1, 2], [3, 4]]
b = a[:]
c = [row[:] for row in a]
b[0].append(5)
c[1][0] = 9
print(len(a[0]), a[1][0], c[1][0])
예시 정답
3 3 9
풀이 과정
b는 내부 리스트를 a와 공유하여 b[0]의 append가 a[0]에도 보인다. c는 각 내부 리스트도 복사했으므로 c[1][0]의 변경은 a에 영향을 주지 않는다.
답안 점검
위 풀이 예시의 답을 가린 뒤, 핵심 이론의 규칙을 적용해 직접 풀어 보세요. 코드와 계산 문제는 중간값·단위·최종 출력의 순서를, 용어 문제는 지문의 핵심 단서와 답의 의미를 점검하세요. 해설과 다른 부분이 있으면 어느 조건을 놓쳤는지 확인하고 연결된 실기 문제로 다시 연습하세요.