리스트. List
여러 개의 값을 한 묶음으로 관리하기 위한 자료형이다.
• 순서가 존재
• 값을 자유롭게 추가·삭제·변경 가능
• 여러 데이터를 담을수 있음
• 대괄호 [ ]를 사용하여 리스트 생성
# 1. 리스트 생성
my_list = [1, 2, 3, 4, 5]
# 2. list()함수 사용
chars = list('hello')
# 3. 리스트의 기본 구조 츨력
print(my_list) # 출력: [1, 2, 3, 4, 5]
print(chars) # 출력: ['h', 'e', 'l', 'l', 'o']
• 대괄호 [ ] - 여러 개의 값을 담는 자료형 이란 선언
• 쉼표 , - 각 값은 독립된 요소(element) 라는 의미
• 순서가 있다 - 1 → 2 → 3 → 4 → 5
1. 리스트 인덱싱과 슬라이싱
1회차때 배웠던것 기억하기....
인덱싱 = 번호→ 리스트 안에서 “몇 번째 값인가”를 기준으로 접근하는 방법
my_list = [1, 2, 3, 4, 5]
my_list[0]
이 코드는...
“리스트에서 0번째 위치에 있는 값을 가져와라”
→ my_list의 0번째에 있는 1 을 가져옴
fruits = ['apple', 'banana', 'cherry', 'date']
print(fruits[0]) # 출력: apple
print(fruits[2]) # 출력: cherry
print(fruits[-1]) # 출력: date (마지막 요소)
print(fruits[-2]) # 출력: cherry
문자열 또한 인덱싱이 가능하다!
슬라이싱 = 원하는 부분을 자르는 것.
sequence[start:stop:step]
• start: 슬라이싱을 시작할 인덱스 (포함).
• stop: 슬라이싱을 종료할 인덱스 (불포함).
• step: 요소를 건너뛰는 간격.
2. 리스트의 변경 가능성(Mutability)
리스트는 변경 가능한 객체로, 생성 후에도 요소의 추가, 삭제, 변경이 가능하다.
이게 가능하다는 건, 같은 리스트를 유지하면서 내용만 계속 업데이트 가능 하단 의미
⭐데이터 전처리에서 매우 중요하니 기억할것⭐
요소의 변경
fruits = ['apple', 'banana', 'cherry']
fruits[1] = 'blueberry'
print(fruits) # 출력: ['apple', 'blueberry', 'cherry']
슬라이싱을 통한 요소의 변경
numbers = [0, 1, 2, 3, 4, 5]
numbers[1:3] = [9, 9]
print(numbers) # 출력: [0, 9, 9, 3, 4, 5]
3. 리스트 메소드(List Methods)
파이썬은 리스트를 조작하기 위한 다양한 내장 메서드를 제공한다.
append / insert / extend (요소의 추가)
my_list.append(6)
my_list.insert(2, 10)
my_list.extend([7, 8, 9])
• append - 리스트에 하나의 값(요소) 을 맨 뒤에 추가
• insert - 기존 순서를 유지하면서, 지정한 위치(index) 에 값을 삽입 (이때 기존 값들은 오른쪽으로 한 칸씩 밀린다 )
• extend- 여러 개의 값을 풀어서 추가 → “리스트와 리스트를 이어 붙인다”란 개념으로 접근
remove / pop / clear (요소의 제거)
my_list.remove(3)
popped_value = my_list.pop(5)
my_list.clear()
• remove - 값을 기준으로 첫 번째로 일치하는 요소를 제거
• pop - 지정한 인덱스의 요소를 제거하고 그 요소를 반환한다. 반환 인덱스를 지정하지 않으면 마지막 요소를 제거
• clear - 모든 요소를 제거
index / count ( 요소 검색 및 개수 세기 )
my_list.index(4)
my_list.count(7)
• index - 요소의 인덱스를 반환. 특정 값이 처음 등장하는 위치를 알려준다
• count - 요소의 개수를 반환. 특정 값이 몇 번 등장하는지 세어준다
sort / reverse ( 정렬 )
my_list.sort()
my_list.reverse()
• sort - 리스트의 요소를 오름차순으로 정렬
• reverse - 리스트의 요소 순서를 반대로 뒤집는다
3. 리스트 연산
리스트 연결(Concatenation)
+ 연산을 사용해 리스트를 연결할수 있다.
list1 = [1, 2, 3]
list2 = [4, 5, 6]
result = list1 + list2
print(result) # 출력: [1, 2, 3, 4, 5, 6]
리스트 반복(Repetition)
연산자를 이용해 리스트를 반복할 수도 있다.
list1 = ['a', 'b']
print(list1 * 3) # 출력: ['a', 'b', 'a', 'b', 'a', 'b']
⭐ 4. 리스트 컴프리헨션(List Comprehension) ⭐ (복습때 따로 다룰 예정)
기존 for문 + 조건문 패턴을 한 줄로 표현해 간결하고 효율적인 방법으로 새로운 리스트를 생성하는 문법
데이터를 다루다 보면 매우 자주 등장하는 작업이 있다.
• 반복하면서
• 조건을 걸고
• 값을 가공한 뒤
• 새로운 리스트를 만든다
이 패턴을 매번 여러 줄의 코드로 작성하는 것은 번거롭고 가독성이 좋지 않다.
이러한 문제를 해결하기 위해 리스트 컴프리헨션을 사용한다.
⭐ 리스트 컴프리헨션을 사용한 코드와 사용하지 않은 코드를 둘 다 작성해보며 비교해보기 ⭐
[표현식 for 변수 in 반복가능객체]
[표현식 for 변수 in 반복가능객체 if 조건]
반복 가능 객체에서 값을 하나씩 꺼내서 표현식을 적용한 결과로 리스트를 만든다.
읽는 순서
- for x in range(...)
- if 조건
- 맨 앞의 표현식
언제 사용하는것이 좋은가?
- 결과가 하나의 리스트로 끝날 때
- 중첩이 2단계를 넘지 않을 때
- 조건과 가공이 명확할 때
간단한 예제로 시작하기
예제: 숫자를 그대로 복사하는 리스트
수도코드로 보기
| 빈 리스트 생성 1부터 5까지 반복 현재 숫자를 리스트에 추가 |
# 일반적인 for문
result = []
for x in range(1, 6):
result.append(x)
# 리스트 컴프리헨션
result = [x for x in range(1, 6)]

실행 순서 (Line by Line)
| 1. range(1, 6) 생성 2. 첫 값 x = 1 3. 표현식 x 실행 → 1 4. 리스트에 추가 5. 반복 종료까지 반복 |
예제: 짝수만 골라 제곱하기
수도코드로 보기
| 빈 리스트 생성 1부터 10까지 반복 만약 짝수라면 제곱해서 리스트에 추가 |
# 일반적인 for문
squares = []
for x in range(1, 11):
if x % 2 == 0:
squares.append(x ** 2)
# 리스트 컴프리헨션
squares = [x ** 2 for x in range(1, 11) if x % 2 == 0]
실행 순서 (Line by Line)
| 1. range(1, 11) 생성 2. 값을 생성 (첫값 1) 3. if 구문 판단 4_1. 거짓일경우 다시 반복 4_2. 참일경우 값을 제곱한 후 리스트에 추가 5. 반복 종료까지 반복 (10이 될때 까지) |
5. 리스트의 반복문 활용
리스트의 각 요소에 접근하거나 처리하기 위해 반복문을 사용할 수 있다.
fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
print(fruit, end = ' ')
# 출력: apple banana cherry
인덱스와 함께 반복할수도 있다.
# enumerate : 인덱스와 값을 함께 불러올 수 있습니다.
for index, value in enumerate(fruits):
print(f'인덱스 {index}: {value}')
6. 중첩 리스트(Nested Lists)
리스트 안에 또 하나의 리스트를 넣을수도 있다.
nested_list = [
[1,2,3],
[4,5,6],
[7,8,9]]
nested_list[1][0] # 출력: 4
⭐ 중첩 리스트는 이렇게 이해하자! ⭐
nested_list[1] - 두 번째 “리스트 묶음”
[0] - 그 안에서 첫 번째 값
합쳐서 보면...
nested_list[1][0] 두 번째 “리스트 묶음"에서 첫 번째 값: 4
7. 리스트의 얕은 복사와 깊은 복사 (복습때 따로 다룰 예정)
파이썬에서의 리스트는 값이 아닌 객체이다.
변수는...
리스트를 직접 들고있는것이 아닌, 리스트가 저장된 위치를 가리키는 이름표라 생각하면 편하다.
얕은 복사(Shallow Copy)란?
리스트의 가장 바깥 구조만 새로 만들고, 그 안에 들어 있는 요소들은 원본과 동일한 객체를 참조하는 복사 방식
• 리스트 껍데기는 새 것
• 안에 들어 있는 객체들은 공유
다음과 같은 방법들이 얕은 복사를 만들어낸다.
• 슬라이싱 [:]
• list() 함수
• list.copy()
얕은 복사의 구조를 그림으로 이해하기
original = [1, 2, [3, 4]]
shallow_copy = original[:]
메모리의 관점
| original → [1 , 2 , → [3, 4]] shallow_copy → [1 , 2 ,→ [3, 4]] |
• 바깥 리스트는 서로 다름
• 안쪽 리스트 [3, 4]는 같은 객체
간단예제
original = [1, 2, [3, 4]]
shallow_copy = original[:]
shallow_copy[2][0] = 'a'
print(original) # [1, 2, ['a', 4]]
print(shallow_copy) # [1, 2, ['a', 4]]

실행 흐름
| 1. original 생성 2. shallow_copy 생성 → 바깥 리스트만 새로 복사 3. shallow_copy[2] → 원본과 같은 [3, 4]를 가리킴 4. [0] 위치의 값을 'a'로 변경 5. 공유 중인 내부 리스트가 수정됨 |
복사했는데 같이 바뀌는 이유는 안쪽 리스트를 공유하고 있기 때문이다.
깊은 복사(Deep Copy) 란?
바깥 리스트, 그 안의 모든 하위 객체를 전부 새로 복사한다.
원본과 복사본이 어느 수준에서도 객체를 공유하지 않는다
깊은 복사의 구조를 그림으로 이해하기
import copy
deep_copy = copy.deepcopy(original)
메모리의 관점
| original → [1 , 2 , → [3, 4]] deep_copy → [1 , 2 , → [3, 4]] |
• 바깥 리스트 다름
• 안쪽 리스트도 다름
• 완전히 독립
간단예제
import copy
original = [1, 2, [3, 4]]
deep_copy = copy.deepcopy(original)
deep_copy[2][0] = 'a'
print(original) # [1, 2, [3, 4]]
print(deep_copy) # [1, 2, ['a', 4]]

실행 흐름
| 1. original 생성 2. deep_copy 생성 → 모든 요소 재귀적으로 복사 3. shallow_copy[2] → 원본과 같은 [3, 4]를 가리킴 4. deep_copy[2][0] 값 변경 5. 원본은 영향을 받지 않음 |
표로 정리
| 구분 | 얕은 복사 | 깊은 복사 |
| 바깥 객체 | 새로 생성 | 새로 생성 |
| 내부 객체 | 공유 | 전부 새로 생성 |
| 독립성 | 부분적 | 완전 |
| 중첩 리스트 | 위험 | 안전 |
판단하는 기준
두 변수가 완전히 독립적인가?
아니면 → 얕은 복사
맞으면 → 깊은 복사
8. 리스트와 메모리 관리 (심화내용. 이해안가면 패스.) (복습때 따로 다룰 예정)
리스트의 메모리 주소를 확인
a = [1, 2, 3]
b = a
print(id(a)) # 예: 140254689532736
print(id(b)) # 예: 140254689532736 (같은 메모리 주소)
b = a는 동일한 리스트 객체를 가리킵니다.
새로운 리스트를 생성
b = a[:]
print(id(a)) # 예: 140254689532736
print(id(b)) # 예: 140254689533184 (다른 메모리 주소)
b = a[:]는 새로운 리스트를 생성합니다.
9. 리스트의 실용 예제
중복 제거
# set은 중복을 허용하지 않는 집합 자료형입니다. - 관련 자료 : https://wikidocs.net/1015
numbers = [1, 2, 2, 3, 4, 4, 5]
unique_numbers = list(set(numbers))
print(unique_numbers) # 출력: [1, 2, 3, 4, 5]
컴프리헨션을 이용한 조건부 리스트
# 1부터 20까지의 숫자 중에서 3의 배수만 리스트로 생성
multiples_of_three = [x for x in range(1, 21) if x % 3 == 0]
print(multiples_of_three) # 출력: [3, 6, 9, 12, 15, 18]
2차원 리스트에서 특정 조건의 요소 찾기
matrix = [
[5, 10, 15],
[20, 25, 30],
[35, 40, 45]
]
# 요소 중에서 30보다 큰 값만 리스트로 추출
result = [item for row in matrix for item in row if item > 30]
print(result) # 출력: [35, 40, 45]
튜플. Tuple
여러 개의 값을 하나로 묶어 저장하는 자료형이다.
겉으로 보면 리스트와 거의 똑같아 보이지만, 가장 중요한 차이점....
❗ 튜플은 한 번 만들어지면 절대 바꿀 수 없다 (immutable)❗
• 순서가 존재
• 요소의 추가, 삭제, 변경이 불가능
• 여러 데이터를 담을수 있음
• 대괄호 [ ]를 사용하여 리스트 생성
프로그래밍을 함에 있어 “절대 바뀌면 안 되는 데이터”가 꽤 있는데 이런 데이트를 다룰때 튜플을 사용한다.
불변성이란?
생성된 후에는 요소를 변경할 수 없음을 의미한다.
요소의 변경, 주가, 삭제가 불가능하다.
1. 튜플을 만드는 다양한 방법
괄호 ()를 사용한 생성
# ()를 사용
my_tuple = (1, 2, 3)
print(my_tuple) # 출력: (1, 2, 3)
괄호 없이 생성 (튜플 패킹)
# () 없이 생성 (튜플패킹)
my_tuple = 1, 2, 3
print(my_tuple) # 출력: (1, 2, 3)
print(type(my_tuple)) # 출력: <class 'tuple'>
tuple() 함수를 사용한 생성
# tuple()함수를 사용해 생성
my_list = [1, 2, 3]
my_tuple = tuple(my_list) # 리스트를 튜플로 변환
print(my_tuple) # 출력: (1, 2, 3)
단일 요소 튜플 생성 시 주의점
# 단일요소로 추가할때 (쉼표를 넣지 않으면 일반값으로 인식)
single_element = (5,)
print(single_element) # 출력: (5,)
print(type(single_element)) # 출력: <class 'tuple'>
# 쉼표가 없으면 일반 값으로 인식
not_a_tuple = (5)
print(type(not_a_tuple)) # 출력: <class 'int'>
2. 튜플 인덱싱 & 슬라이싱
기존 알고있는 인덱싱과 슬라이싱과 동일하나 다른점은 ❗수정은 불가능❗
튜플 인덱싱
fruits = ('apple', 'banana', 'cherry', 'date')
print(fruits[0]) # 출력: apple
print(fruits[2]) # 출력: cherry
print(fruits[-1]) # 출력: date (마지막 요소)
print(fruits[-2]) # 출력: cherry
튜플 슬라이싱
numbers = (0, 1, 2, 3, 4, 5, 6)
print(numbers[2:5]) # 출력: (2, 3, 4)
print(numbers[:3]) # 출력: (0, 1, 2)
print(numbers[4:]) # 출력: (4, 5, 6)
print(numbers[::2]) # 출력: (0, 2, 4, 6)
print(numbers[::-1]) # 출력: (6, 5, 4, 3, 2, 1, 0)
3. 튜플 메소드(Tuple Methods)
count()
numbers = (1, 2, 2, 3, 3, 3)
print(numbers.count(2)) # 출력: 2
print(numbers.count(3)) # 출력: 3
- 특정 요소의 개수를 반환. 특정 값이 몇 번 등장했는지
index()
fruits = ('apple', 'banana', 'cherry')
print(fruits.index('banana')) # 출력: 1
- 첫 번째로 일치하는 요소의 인덱스를 반환. 특정 값이 처음 등장한 위치 확인
4. 튜플과 리스트의 차이점
| 구분 | 리스트 | 튜플 |
| 변경 가능 | O | X (불변성 때문) |
| 추가/삭제 | 가능 | X (불변성 때문) |
| 용도 | 데이터 조작이 필요한 경우 | 변경이 불필요한 테이터 key |
| 성격 | 작업용 | 고정데이터, 보관용 |
| 비유 | 메모장 | 인쇄된 문서 |
5. 튜플의 활용
딕셔너리의 키로 활용
my_dict = { (1, 2): "Point A", (3, 4): "Point B" }
print(my_dict[(1, 2)]) # 출력: Point A
함수의 복수 반환값
def get_position():
x = 10
y = 20
return x, y # 튜플로 반환
pos = get_position()
print(pos) # 출력: (10, 20)
print(type(pos)) # 출력: <class 'tuple'>
변수의 패킹과 언패킹
패킹: 여러개의 값을 하나의 튜플로 묶는것을 의미
packed_tuple = 1, 2, 3
print(packed_tuple) # 출력: (1, 2, 3)
언패킹: 튜플의 요소를 여러 개의 변수에 할당하는 것을 의미
a, b, c = packed_tuple
print(a) # 출력: 1
print(b) # 출력: 2
print(c) # 출력: 3
순서가 중요한 데이터 저장
point = (10, 20)
date = (2023, 9, 15)
6. 중첩 튜플(Nested Tuples)
튜플 안에 튜플을 요소로 가질 수 있습니다.
nested_tuple = (1, (2, 3), (4, (5, 6)))
print(nested_tuple[1]) # 출력: (2, 3)
print(nested_tuple[2][1]) # 출력: (5, 6)
print(nested_tuple[2][1][0]) # 출력: 5
7. 튜플의 반복문 활용
튜플의 각 요소에 접근하거나 처리하기 위해 반복문을 사용할 수 있다.
fruits = ('apple', 'banana', 'cherry')
for fruit in fruits:
print(fruit)
인덱스와 함께 반복하기
for index, value in enumerate(fruits):
print(f'인덱스 {index}: {value}')
8. 튜플의 비교와 정렬
투플은 요소별로 비교할 수 있으며, 정렬된 시퀀스를 필요로 하는 경우에 유용하다.
# 튜플끼리의 비교
tuple1 = (1, 2, 3)
tuple2 = (1, 2, 4)
print(tuple1 < tuple2) # 출력: True
튜플의 리스트를 정렬 할수도 있다.
students = [('John', 'A', 15), ('Jane', 'B', 12), ('Dave', 'A', 10)]
# 나이를 기준으로 정렬
students_sorted = sorted(students, key=lambda student: student[2])
print(students_sorted)
# 출력: [('Dave', 'A', 10), ('Jane', 'B', 12), ('John', 'A', 15)]
9. 실용예제
두 변수의 값 교환
a = 10
b = 20
a, b = b, a # 값 교환
print(a) # 출력: 20
print(b) # 출력: 10
리스트와 상호 변환
my_tuple = (1, 2, 3)
my_list = list(my_tuple)
print(my_list) # 출력: [1, 2, 3]
my_new_tuple = tuple(my_list)
print(my_new_tuple) # 출력: (1, 2, 3)
여러 변수에 동일한 값 할당
x = y = z = 0
print(x, y, z) # 출력: 0 0 0
딕셔너리.Dictionarty
값을 위치(index)가 아니라, 이름(key)으로 관리하는 자료구조다.
즉, 순서가 아닌 '의미'로 데이터를 찾는다!
키(key)과 값(value)의 쌍을 저정한다.
값(value)은 뭐든 될 수 있다
•숫자
•문자열
•리스트
•튜플
•딕셔너리 조차 가능
⭐ 순서가 목적이 아니다. 딕셔너리는 “몇 번째냐”가 아닌 “무엇이냐”가 중요하다 ⭐
# 빈 딕셔너리 생성
empty_dict = {}
# 키-값 쌍을 가진 딕셔너리
person = {
'name': 'Alice',
'age': 25,
'city': 'New York'
}
print(empty_dict) # 출력: {}
print(person) # 출력: {'name': 'Alice', 'age': 25, 'city': 'New York'}
1. 딕셔너리 생성 방법
중괄호 {} 사용
# 기본적인 딕셔너리 생성
student = {
'id': 12345,
'name': 'John Doe',
'grade': 'A'
}
dict()를 사용
# 키워드 인자를 사용한 생성
car = dict(brand='Ford', model='Mustang', year=1964)
print(car) # 출력: {'brand': 'Ford', 'model': 'Mustang', 'year': 1964}
# 리스트나 튜플의 리스트를 사용한 생성
items = [('apple', 2), ('banana', 3)]
fruit_dict = dict(items)
print(fruit_dict) # 출력: {'apple': 2, 'banana': 3}
2. 딕셔너리 요소 접근 및 변경
접근
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}
# 키를 사용하여 값에 접근
print(person['name']) # 출력: Alice
print(person['age']) # 출력: 25
# `get()` 메서드를 사용하여 값에 접근 (키가 없을 때 기본값 설정 가능)
print(person.get('city')) # 출력: New York
print(person.get('country')) # 출력: None
print(person.get('country', 'USA')) # 출력: USA
변경
person['age'] = 26
print(person) # 출력: {'name': 'Alice', 'age': 26, 'city': 'New York'}
추가
person['country'] = 'USA'
print(person) # 출력: {'name': 'Alice', 'age': 26, 'city': 'New York', 'country': 'USA'}
삭제
# `del` 키워드를 사용하여 요소 삭제
del person['city']
print(person) # 출력: {'name': 'Alice', 'age': 26, 'country': 'USA'}
# `pop()` 메서드를 사용하여 요소 삭제 및 값 반환
age = person.pop('age')
print(age) # 출력: 26
print(person) # 출력: {'name': 'Alice', 'country': 'USA'}
# 모든 요소 삭제
person.clear()
print(person) # 출력: {}
3. 딕셔너리 메소드 (Dictionary Methods)
keys()
모든 키를 dict_keys 객체로 반환 ( 컬럼 목록 확인 느낌 )
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}
keys = person.keys()
print(keys) # 출력: dict_keys(['name', 'age', 'city'])
values()
모든 값을 dict_values 객체로 반환 ( 실제 데이터들만 모아서 보기 )
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}
keys = person.keys()
print(keys) # 출력: dict_keys(['name', 'age', 'city'])
items()
딕셔너리의 모든 키-값 쌍을 튜플로 반환
items = person.items()
print(items) # 출력: dict_items([('name', 'Alice'), ('age', 25), ('city', 'New York')])
(키, 값) 쌍으로 묶어서 제공
5. 딕셔너리의 반복문 활용
키를 통한 반복
for key in person:
print(key, person[key])
keys() 메소드를 통한 반복
for key in person.keys():
print(key)
values() 메소드를 통한 반복
for value in person.values():
print(value)
items() 메소드를 통한 반복
for key, value in person.items():
print(f'{key}: {value}')
6. 딕셔너리 컴프리헨션(Dictionary Comprehension. 이해안가면 패스.)
간결하고 효율적인 방법으로 새로운 딕셔너리를 생성하는 문법
new_dict = {key_expression: value_expression for item in iterable}
예제
1부터 5까지의 숫자를 키로 하고, 그 제곱을 값으로 하는 딕셔너리 생성
squares = {x: x**2 for x in range(1, 6)}
print(squares) # 출력: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
기존 딕셔너리에서 특정 조건에 맞는 요소만 필터링
original = {'apple': 2, 'banana': 3, 'cherry': 5, 'date': 4}
filtered = {k: v for k, v in original.items() if v % 2 == 0}
print(filtered) # 출력: {'apple': 2, 'date': 4}
7. 딕셔너리와 관련된 함수들
len()
딕셔너리의 키-값 쌍의 개수를 반환
person = {'name': 'Alice', 'age': 26, 'city': 'New York', 'country': 'USA'}
print(len(person)) # 출력: 4
in 연산자
딕셔너리에 특정 키가 존재하는지 확인
print('name' in person) # 출력: True
print('email' in person) # 출력: False
del 키워드
딕셔너리 자체를 삭제하거나 모든 요소를 삭제
del person['country'] # 특정 키-값 쌍 삭제
del person # 딕셔너리 전체 삭제
8. 중첩 딕셔너리(Nested Dictionaries)
딕셔너리는 다른 딕셔너리를 값으로 가질 수 있다.
students = {
'student1': {'name': 'Alice', 'age': 25},
'student2': {'name': 'Bob', 'age': 22},
'student3': {'name': 'Charlie', 'age': 23}
}
# 특정 학생의 정보에 접근
print(students['student2']['name']) # 출력: Bob
중첩 딕셔너리의 반복
for student_id, info in students.items():
print(f'ID: {student_id}')
for key, value in info.items():
print(f' {key}: {value}')
9. 딕셔너리의 응용
9.1. 키로 사용할 수 없는 자료형
# 다음 코드는 오류를 발생시킵니다.
my_dict = { [1, 2, 3]: 'Numbers' } # TypeError: unhashable type: 'list'
9.2. 람다(lambda) 함수란?
# 같은 의미
square = lambda x: x * x # 람다
def square(x): return x * x # def
10. 딕셔너리와 JSON 데이터
딕셔너리는 JSON(JavaScript Object Notation) 데이터와 구조가 유사하여, 웹 프로그래밍에서 데이터를 주고받을 때 자주 사용된다.
(오픈/공공 데이터가 JSON 형태인 경우가 많아, 파이썬 딕셔너리 형태로 변환하여 처리하는 경우 다수)
import json
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}
# 딕셔너리를 JSON 문자열로 변환
json_str = json.dumps(person)
print(json_str)
# 출력: {"name": "Alice", "age": 25, "city": "New York"}
# JSON 문자열을 딕셔너리로 변환
data = json.loads(json_str)
print(data)
# 출력: {'name': 'Alice', 'age': 25, 'city': 'New York'}
[보충] immutable? mutable?
1. 객체(Object)란 무엇인가?
값(value)과 기능(Methods)을 함께 가진 데이터 덩어리를 의미한다.
ex)
a=10
• 10은 숫자 객체
• a 는 그 숫자 객체를 가리키는 이름(변수)
2. Immutable / Mutable의 핵심 차이
| 구분 | 뜻 | 정리 |
| Immutable | 바꿀 수 없음 | 객체 자체를 수정할 수 없음 |
| Mutable | 바꿀 수 있음 | 객체 자체를 수정할 수 있음 |
중요한 포인트는 “변수를 바꾼다”와 “객체가 바뀐다”는 전혀 다른 개념
3. Immutable 객체 (변경 불가능)
객체는 기존 내용을 고칠 수 없고, 항상 새 객체를 만들어서 교체합니다
대표적인 Immutable 객체
• int
• float
• str
• tuple
비유로 이해하기
잉크로 글씨를 쓴 종이
→ 이미 써진 글씨는 지울 수 없다
→ 내용을 바꾸려면 새 종이에 다시 써야한다,
예제
a = 10
a = a + 1
print(a)
이때 10이 11로 바뀐 것이 아닌
숫자 11이라는 새 객체가 만들어졌다.
변수 a가 새 객체를 가리키게 된 것
4. Mutable 객체 (변경 가능)
객체 자체의 내용이 바뀐다.
대표적인 Mutable 객체
• list
• dict
• set
비유로 이해하기
연필로 쓴 노트
→ 지울 수 있고
→ 고칠 수 있고
→ 내용을 추가할 수 있다.
예시
nums = [1, 2, 3]
nums[0] = 100
print(nums)
# 출력: [100, 2, 3]
nums = [1, 2, 3]
nums.append(4)
print(nums)
# 출력: [1, 2, 3, 4]
헷갈리기 쉬운 포인트
잘못된 생각
변수 값을 바꾸면 객체도 바뀐다.
정확한 이해
Immutable 객체는 새 객체가 만들어진다,
Mutable 객체는 기존 객체가 수정된다.
정리
| 구분 | Immutable | Mutable |
| 객체 수정 | 불가능 | 가능 |
| 변경 방식 | 새 객체 생성 | 기존 객체 수정 |
| 대표 예시 | int, str, tuple | list, dict, set |
| 비유 | 잉크로 쓴 종이 | 연필로 쓴 노트 |
'A.Today I Learne > 파이썬' 카테고리의 다른 글
| [TIL] 파이썬 5일차 (0) | 2026.01.14 |
|---|---|
| [TIL] 파이썬 4일차 (0) | 2026.01.12 |
| [TIL] 파이썬 2일차 (0) | 2026.01.07 |
| [TIL] 파이썬 1일차 (0) | 2026.01.05 |
