함께 배우는 수업 · 컴퓨터/정보

프로그래밍 기초 - 변수와 자료형

변수와 객체 참조 모델, 정적 타이핑과 동적 타이핑의 차이, 파이썬 핵심 컬렉션(list, tuple, dict, set)의 시간 복잡도와 가변·불변성(Mutability)을 학습합니다.

이 수업에서 해 볼 일

  • 파이썬 자료형과 연산의 의미를 코드에서 구별한다

먼저 알면 좋은 것: 순차 실행에서 변수 대입과 표현식의 결과 추적 · 값과 이름을 구분하고 정수·실수·문자열을 계산하는 기초 · 리스트 인덱스와 키-값 쌍을 표로 읽는 기초

오늘의 목표

가입 없이 시작할 수 있어요. 설명을 읽고, 함께 연습한 뒤, 처음 보는 문제에서 직접 확인합니다.

판단 과정과 비교 사례

파이썬 변수는 객체를 가리키는 이름이다. 리스트에 다른 이름을 붙인 뒤 내용을 수정하는 것과, 이름에 새 객체를 다시 대입하는 것은 다르다.p=[5]; q=p 후 q.append(6)을 하면 두 이름이 같은 리스트를 보므로 p도 [5,6]이다. 반면 q=[9]로 재대입하면 p가 가리키는 리스트는 그대로다.불변 객체라는 성질과 해시 가능한 성질도 구별하자. 튜플 안에 리스트가 있으면 튜플의 요소 위치는 고정이어도 전체 튜플을 해시 키로 쓸 수는 없다.

1. 변수의 메모리 바인딩과 정적 타이핑 vs 동적 타이핑

- 정적 타이핑 (Static Typing - C, C++, Java, Go, Rust, TypeScript): - 변수를 선언할 때 자료형을 명시(int count = 10;)하며, 컴파일(Compile) 시점에 타입 일치 여부를 엄격히 검사합니다. 실행 속도가 빠르고 대규모 프로젝트에서 타입 안정성이 높습니다. - 동적 타이핑 (Dynamic Typing - Python, JavaScript, Ruby): - 변수 선언 시 타입을 적지 않으며(x = 10 후 x = "hello" 가능), 프로그램 실행(Runtime) 시점에 할당되는 값(객체)에 따라 타입이 동적으로 결정됩니다. - 파이썬의 객체 참조 모델 (Name Binding): - C언어의 변수가 값을 직접 담는 '메모리 상자'라면, 파이썬의 변수는 힙(Heap) 메모리에 생성된 객체(Object)의 주소를 가리키는 '이름표(포인터 참조)'입니다. - 따라서 b = a를 실행하면 데이터가 복사되는 것이 아니라, 변수 b가 변수 a와 동일한 메모리 객체 주소를 함께 가리키게(참조 공유) 됩니다.파이썬에서 a == b는 두 객체의 '값(Value)이 같은지'를 비교하는 연산자이고, a is b는 두 변수가 가리키는 '실제 메모리 주소(id)가 완전히 동일한 객체인지'를 비교하는 연산자입니다.

2. 불변 객체(Immutable) vs 가변 객체(Mutable)와 얕은/깊은 복사

파이썬의 자료형은 생성 후 내부 값을 바꿀 수 있는지에 따라 두 부류로 엄격히 나뉩니다: 1. 불변 객체 (Immutable - 수정 불가): int, float, bool, str(문자열), tuple(튜플) - 한 번 생성되면 메모리 내부 값을 절대 바꿀 수 없습니다. x = x + 1이나 문자열 연결을 수행하면 기존 메모리가 바뀌는 게 아니라 새로운 객체가 생성되어 이름표가 옮겨 붙습니다. - 불변성과 해시 가능성은 같은 뜻이 아닙니다. 튜플은 불변 컨테이너지만, 모든 원소가 해시 가능할 때만 튜플 자체도 딕셔너리 키나 집합 원소가 될 수 있습니다. 예를 들어 (1, "서울")은 해시 가능하지만 (1, ["서울"])은 리스트 원소 때문에 해시할 수 없습니다. ([Python 공식 용어집: hashable](https://docs.python.org/3/glossary.html#term-hashable)) 2. 가변 객체 (Mutable - 수정 가능): list(리스트), dict(딕셔너리), set(집합) - 객체의 메모리 주소를 유지한 채로 내부 원소를 추가·수정·삭제할 수 있습니다. - 참조 공유 주의점: 가변 리스트 a = [1, 2, 3]에 대해 b = a로 대입한 뒤 b.append(4)를 실행하면 원본 a도 함께 [1, 2, 3, 4]로 변경(Side Effect)됩니다! 원본을 보호하려면 슬라이싱(b = a[:])이나 copy.deepcopy()를 사용해야 합니다.

예제로 살펴보기

다음 파이썬 코드 실행 후 출력되는 a, b, s1의 값을 각각 구하고 그 이유를 메모리 참조 관점에서 설명하시오.
a = [10, 20]
b = a
b.append(30)

s1 = 'Hello'
s2 = s1
s2 = s2 + ' World'
  1. 1) 리스트 a와 b의 결과: - list는 가변 객체(Mutable)입니다. b = a는 리스트를 새로 복사하지 않고 [10, 20] 객체의 메모리 주소를 공유합니다. - 따라서 b.append(30)으로 해당 객체에 30을 추가하면, 같은 객체를 바라보는 a와 b 모두 [10, 20, 30]이 됩니다. 2) 문자열 s1의 결과: - str은 불변 객체(Immutable)입니다. s2 = s2 + ' World'를 실행하면 기존 'Hello' 객체를 수정할 수 없으므로 새로운 문자열 객체 'Hello World'를 만들어 s2의 이름표만 새 객체로 옮깁니다. - 따라서 원본 s1은 전혀 영향을 받지 않고 그대로 'Hello'를 유지합니다.
확인: 파이썬의 변수는 값을 직접 담는 상자가 아니라 힙 메모리에 생성된 객체의 주소를 가리키는 참조 이름표다.

3. 파이썬 4대 컬렉션 자료형 특징 및 연산 성능 비교

적절한 기본 자료형 선택 하나가 알고리즘 실행 시간을 수천 배 단축시킵니다. - list (동적 배열): 순서(인덱스)가 있고 중복 허용. 인덱스 조회 O(1)O(1), append/pop() O(1)O(1), 포함 여부 검사(x in list)는 처음부터 끝까지 찾으므로 O(N)O(N) 소요. - tuple (불변 시퀀스): 소괄호 (1, 2) 사용. 수정이 불가능하고, 딕셔너리의 복합 키(예: 좌표 (r, c))로 쓰려면 모든 원소가 해시 가능해야 합니다. - dict (해시 테이블): {Key: Value} 쌍 저장 (Python 3.7+부터 입력 순서 보장). 키를 통한 조회·삽입·삭제 및 k in dict 검사 모두 평균 O(1)O(1)! - set (해시 집합): 중복을 허용하지 않고 순서가 없는 원소 모음. 중복 제거와 교집합(&)·합집합(|)·차집합(-) 연산 및 원소 존재 확인(x in set)이 평균 O(1)O(1)에 수행됨.실무 최적화: 해시 가능한 값의 포함 여부를 여러 번 확인할 때는 집합으로 바꾸면 평균 조회 비용을 줄일 수 있습니다. 단, 순서가 필요한지와 모든 원소가 해시 가능한지 먼저 확인하세요.

참고 근거와 확인 범위

설명·예제·문제 구성 및 오류 수정 책임: 프리런. 위 자료는 표시한 주제를 확인하거나 더 읽기 위한 근거이며, 외부 기관의 공식 수업이나 감수본을 뜻하지 않습니다.

참고 자료 연결 점검: 2026-11-02. 제작 방식·검수 범위와 수정 기록에서 확인 범위를 볼 수 있습니다. 오류는 상단의 의견 보내기 또는 contact@freelearn.io로 알려 주세요.

이 단원의 개념서 읽기 →