8장: Collections — 여러 값을 담는 자료형¶
왜 여러 값을 담는 자료형이 필요한가?¶
학생 5명의 점수를 저장하려면 어떻게 할까요?
# 변수를 따로따로 만들면?
score1 = 90
score2 = 85
score3 = 78
score4 = 92
score5 = 88
학생이 100명이면 변수를 100개 만들어야 합니다. 번거롭고, 반복문과도 연결되지 않습니다.
# 리스트 하나면 충분
scores = [90, 85, 78, 92, 88]
Python은 여러 값을 하나의 이름으로 묶는 네 가지 자료형을 제공합니다.
iamList = ["Kor", "Math", "Eng", "Sci"] # list
iamTuple = ("Kor", "Math", "Eng", "Sci") # tuple
iamSet = {"Apple", "Banana", "Orange", "Apricot"} # set
iamDic = {"Apple":150, "Banana":200, "Orange":45, "Apricot":40} # dict
| 자료형 | 특징 | 예시 |
|---|---|---|
list |
순서 있음, 값 변경 가능 | [1, 2, 3] |
tuple |
순서 있음, 값 변경 불가 | (1, 2, 3) |
set |
순서 없음, 중복 제거 | {1, 2, 3} |
dict |
키–값 쌍, 키로 접근 | {"name": "지민"} |
리스트 (List)¶
리스트 만들기¶
대괄호 []로 만들고, 쉼표로 요소를 구분합니다.
fruits = ["apple", "banana", "cherry"]
numbers = [10, 20, 30, 40, 50]
mixed = [1, "hello", True, 3.14] # 다른 타입도 섞을 수 있음
empty = [] # 빈 리스트
인덱싱 (Indexing)¶
인덱스(위치 번호)로 요소에 접근합니다. 인덱스는 0부터 시작합니다.
fruits = ["apple", "banana", "cherry"]
# 0 1 2 (앞에서)
# -3 -2 -1 (뒤에서)
print(fruits[0]) # apple
print(fruits[1]) # banana
print(fruits[-1]) # cherry (마지막)
print(fruits[-2]) # banana (뒤에서 두 번째)
apple
banana
cherry
banana
슬라이싱 (Slicing)¶
[시작:끝]으로 일부를 잘라냅니다. 끝 인덱스는 포함되지 않습니다.
nums = [0, 1, 2, 3, 4, 5]
print(nums[1:4]) # [1, 2, 3] (인덱스 1, 2, 3)
print(nums[:3]) # [0, 1, 2] (처음부터 인덱스 2까지)
print(nums[3:]) # [3, 4, 5] (인덱스 3부터 끝까지)
print(nums[::2]) # [0, 2, 4] (2칸씩 건너뜀)
print(nums[::-1]) # [5, 4, 3, 2, 1, 0] (뒤집기)
리스트 수정¶
리스트는 변경 가능(mutable)합니다.
fruits = ["apple", "banana", "cherry"]
fruits[1] = "mango" # 값 바꾸기
print(fruits) # ['apple', 'mango', 'cherry']
주요 메서드¶
| 메서드 | 설명 | 예시 |
|---|---|---|
.append(x) |
끝에 추가 | lst.append(4) |
.insert(i, x) |
위치 i에 삽입 | lst.insert(1, 99) |
.remove(x) |
값 x 제거 (첫 번째) | lst.remove(2) |
.pop() |
마지막 요소 꺼내기 | lst.pop() |
.pop(i) |
인덱스 i 요소 꺼내기 | lst.pop(0) |
.sort() |
오름차순 정렬 | lst.sort() |
.sort(reverse=True) |
내림차순 정렬 | lst.sort(reverse=True) |
.reverse() |
순서 뒤집기 | lst.reverse() |
.index(x) |
값 x의 인덱스 반환 | lst.index(3) |
len(lst) |
요소 개수 | len(lst) |
nums = [3, 1, 4, 1, 5]
nums.append(9)
print(nums) # [3, 1, 4, 1, 5, 9]
nums.remove(1) # 첫 번째 1만 제거
print(nums) # [3, 4, 1, 5, 9]
last = nums.pop()
print(last) # 9
print(nums) # [3, 4, 1, 5]
nums.sort()
print(nums) # [1, 3, 4, 5]
print(len(nums)) # 4
리스트 순회¶
scores = [90, 85, 78, 92, 88]
for score in scores:
print(score)
90
85
78
92
88
인덱스와 값을 동시에 얻으려면 enumerate()를 씁니다.
fruits = ["apple", "banana", "cherry"]
for i, fruit in enumerate(fruits):
print(i, fruit)
0 apple
1 banana
2 cherry
in 연산자¶
fruits = ["apple", "banana", "cherry"]
print("banana" in fruits) # True
print("grape" in fruits) # False
튜플 (Tuple)¶
튜플 만들기¶
소괄호 ()로 만들거나, 괄호 없이 쉼표만으로도 만들 수 있습니다.
point = (3, 7)
colors = ("red", "green", "blue")
single = (42,) # 요소가 하나일 때는 반드시 쉼표 필요
no_paren = 1, 2, 3 # 괄호 없이도 튜플
주의:
(42)는 int이고,(42,)가 튜플입니다.
print(type((42))) # <class 'int'>
print(type((42,))) # <class 'tuple'>
튜플은 변경 불가 (Immutable)¶
리스트와 달리, 한 번 만든 튜플은 수정할 수 없습니다.
point = (3, 7)
point[0] = 10 # TypeError: 'tuple' object does not support item assignment
인덱싱·슬라이싱은 리스트와 동일합니다.
colors = ("red", "green", "blue")
print(colors[0]) # red
print(colors[-1]) # blue
print(colors[1:]) # ('green', 'blue')
print(len(colors)) # 3
튜플 언패킹 (Unpacking)¶
튜플의 값을 여러 변수에 한 번에 대입합니다.
point = (3, 7)
x, y = point
print(x) # 3
print(y) # 7
# 변수 값 교환 — Python 관용적 방법
a = 10
b = 20
a, b = b, a # 내부적으로 튜플 언패킹
print(a, b) # 20 10
함수에서 여러 값 반환¶
함수가 여러 값을 반환할 때 내부적으로 튜플이 사용됩니다.
def min_max(nums):
return min(nums), max(nums) # 튜플로 반환
lo, hi = min_max([3, 1, 4, 1, 5, 9])
print(lo, hi) # 1 9
list vs tuple¶
| 항목 | list | tuple |
|---|---|---|
| 괄호 | [] |
() |
| 변경 | 가능 | 불가 |
| 속도 | 상대적으로 느림 | 빠름 |
| 용도 | 추가·삭제가 필요한 경우 | 변하지 않는 좌표·설정값 등 |
셋 (Set)¶
셋 만들기¶
중괄호 {}로 만들지만 키:값 쌍이 없고, 중복이 자동으로 제거됩니다.
fruits = {"Apple", "Banana", "Orange", "Apricot"}
numbers = {1, 2, 2, 3, 3, 3} # 중복 제거
print(numbers) # {1, 2, 3}
주의:
{}만 쓰면 빈 dict가 됩니다. 빈 set은set()으로 만듭니다.
셋의 특징¶
- 순서 없음: 인덱싱·슬라이싱 불가
- 중복 없음: 같은 값은 한 번만 저장
- 집합 연산 가능: 합집합(
|), 교집합(&), 차집합(-)
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b) # {1, 2, 3, 4, 5, 6} 합집합
print(a & b) # {3, 4} 교집합
print(a - b) # {1, 2} 차집합
list vs set¶
favorite_animal = ['cat', 'cat', 'python', 'dog', 'python', 'dog', 'dog']
# list → 중복 포함, 순서 유지
print(favorite_animal) # ['cat', 'cat', 'python', ...]
# set → 중복 제거
print(set(favorite_animal)) # {'cat', 'dog', 'python'}
딕셔너리 (Dictionary)¶
list vs dict¶
list는 인덱스(위치 번호)로, dict는 키(이름)로 접근합니다.
listA = [100, 90, 80, 50]
dictA = {"Kor":60, "Eng":80, "Math":60, "Science":90}
# list 접근: listA[0], listA[1], listA[2], listA[3]
# dict 접근: dictA['Kor'], dictA['Eng'], dictA['Math'], dictA['Science']
| List | Dictionary | |
|---|---|---|
| 구조 | Index → Element | Key → Value |
| 접근 | listA[0] |
dictA['Kor'] |
| 용도 | 순서가 중요한 데이터 | 이름이 필요한 데이터 |
# list로 혈액형 빈도 → 어떤 인덱스가 어떤 혈액형인지 알기 어려움
b_type_list = ['A','AB','B','O','AB','O','B','O','O','O','B','A','B','AB','A']
# dict로 만들면 의미가 명확
b_type_dict = {'A':3, 'AB':3, 'B':4, 'O':5}
딕셔너리 만들기¶
중괄호 {}로 만들고, 키: 값 쌍을 쉼표로 구분합니다.
dict_name = {key1:value1, key2:value2, ..., keyN:valueN}
scores = {'KOR':50, 'MATH':80, 'ENG':40, 'PROG':95}
student = {"name": "지민", "age": 17, "score": 92}
empty = {}
키(key)는 보통 문자열, 값(value)은 어떤 타입이든 가능합니다.
값에 접근하기¶
student = {"name": "지민", "age": 17, "score": 92}
print(student["name"]) # 지민
print(student["score"]) # 92
없는 키를 사용하면 KeyError가 발생합니다. 안전하게 접근하려면 .get()을 씁니다.
print(student.get("grade")) # None (오류 없이 None 반환)
print(student.get("grade", "없음")) # 없음 (기본값 지정)
값 추가·수정·삭제¶
student = {"name": "지민", "age": 17}
student["score"] = 92 # 새 키 추가
student["age"] = 18 # 기존 키 값 수정
del student["score"] # 키 삭제
print(student) # {'name': '지민', 'age': 18}
주요 메서드¶
| 메서드 | 설명 | 반환 |
|---|---|---|
.keys() |
모든 키 | dict_keys |
.values() |
모든 값 | dict_values |
.items() |
(키, 값) 쌍 | dict_items |
.get(k) |
키 k의 값 (없으면 None) | 값 |
.get(k, d) |
키 k의 값 (없으면 d) | 값 |
k in d |
키 존재 여부 | bool |
scores = {'KOR':50, 'MATH':80, 'ENG':40, 'PROG':95}
print(scores.keys()) # dict_keys(['KOR', 'MATH', 'ENG', 'PROG'])
print(scores.values()) # dict_values([50, 80, 40, 95])
print(scores.items()) # dict_items([('KOR', 50), ('MATH', 80), ('ENG', 40), ('PROG', 95)])
Q1: 모든 과목명 출력
sum = 0
for i in scores.keys() :
print(i)
# KOR
# MATH
# ENG
# PROG
Q2: 점수 평균 계산
sum = 0
for i in scores.values() :
sum += i
print(sum/4) # 66.25
딕셔너리 순회¶
student = {"name": "지민", "age": 17, "score": 92}
# 키만
for key in student:
print(key)
# 키와 값 동시에
for key, value in student.items():
print(key, ":", value)
name : 지민
age : 17
score : 92
list comprehension과 딕셔너리¶
dict.values()를 list comprehension과 함께 사용하면 값 목록을 쉽게 변환할 수 있습니다.
scores = {'KOR':50, 'MATH':80, 'ENG':40, 'PROG':95}
# 값만 list로
v_list = [x for x in scores.values()]
print(v_list) # [50, 80, 40, 95]
# 70 이상이면 'Pass', 미만이면 'Fail'
result = ['Pass' if x >= 70 else 'Fail' for x in scores.values()]
print(result) # ['Fail', 'Pass', 'Fail', 'Pass']
in 연산자¶
딕셔너리에서 in은 키를 검색합니다.
student = {"name": "지민", "age": 17}
print("name" in student) # True
print("score" in student) # False
print("지민" in student) # False (값은 검색 안 함)
네 자료형 비교¶
| 항목 | list | tuple | set | dict |
|---|---|---|---|---|
| 생성 | [1, 2] |
(1, 2) |
{1, 2} |
{"k": "v"} |
| 접근 | 인덱스 [0] |
인덱스 [0] |
불가 | 키 ["key"] |
| 변경 | 가능 | 불가 | 가능 | 가능 |
| 순서 보장 | O | O | X | O (Python 3.7+) |
| 중복 | 허용 | 허용 | 불가 | 키는 불가 |
| 주요 용도 | 목록 관리 | 불변 데이터 | 중복 제거·집합 연산 | 이름 있는 데이터 |
실습 미션¶
미션 1: 리스트 통계¶
아래 점수 리스트에서 최댓값, 최솟값, 합계, 평균을 출력하세요.
scores = [78, 92, 85, 90, 88, 76, 95]
# 여기에 코드 작성
# 최댓값: 95
# 최솟값: 76
# 합계: 604
# 평균: 86.28...
미션 2: 리스트 필터링¶
점수 리스트에서 80점 이상인 점수만 골라 새 리스트로 만드세요.
scores = [78, 92, 85, 90, 88, 76, 95]
# 여기에 코드 작성
# 결과: [92, 85, 90, 88, 95]
미션 3: 튜플 언패킹¶
(이름, 나이, 점수) 형태의 튜플 리스트를 순회하며 출력하세요.
students = [
("지민", 17, 92),
("수현", 16, 88),
("민준", 17, 95),
]
# 여기에 코드 작성
# 지민 (17세): 92점
# 수현 (16세): 88점
# 민준 (17세): 95점
미션 4: 딕셔너리 활용¶
아래 딕셔너리에서 점수가 90점 이상인 학생의 이름과 점수를 출력하세요.
grade_book = {
"지민": 92,
"수현": 88,
"민준": 95,
"하은": 79,
"태양": 91,
}
# 여기에 코드 작성
# 지민: 92
# 민준: 95
# 태양: 91
미션 5: 딕셔너리 구축¶
학생 이름 리스트와 점수 리스트를 받아 딕셔너리로 합치세요. (zip() 활용)
names = ["지민", "수현", "민준"]
scores = [92, 88, 95]
# 여기에 코드 작성
# {'지민': 92, '수현': 88, '민준': 95}
핵심 요약¶
| 개념 | 설명 |
|---|---|
list |
[], 순서 있음, 변경 가능 |
tuple |
(), 순서 있음, 변경 불가 |
set |
{}, 순서 없음, 중복 제거 |
dict |
{}, 키–값 쌍, 키로 접근 |
| 인덱싱 | lst[0], lst[-1] — 0부터, 음수는 뒤에서 |
| 슬라이싱 | lst[1:4] — 끝 인덱스 미포함 |
.append() |
리스트 끝에 추가 |
.sort() |
리스트 정렬 |
| 튜플 언패킹 | x, y = (3, 7) |
.keys() / .values() / .items() |
딕셔너리 키·값·쌍 순회 |
.get(k, d) |
KeyError 없이 안전하게 접근 |
| list comprehension | [x for x in d.values()] |
in |
list/tuple/set: 값 검색, dict: 키 검색 |