6회차: 리스트 & 딕셔너리
6회차: 리스트 & 딕셔너리
선수 학습: 5회차 (함수)
학습 목표
- 리스트(List)의 개념을 이해하고 다양하게 활용할 수 있다.
- 딕셔너리(Dictionary)의 개념을 이해하고 다양하게 활용할 수 있다.
- 리스트와 딕셔너리를 반복문과 함께 사용할 수 있다.
- 리스트 안에 딕셔너리를 담는 복합 구조를 이해할 수 있다.
6.1. 리스트(List)
6.1.1. 리스트란?
리스트(List)는 여러 개의 값을 순서대로 담는 자료형이다. 대괄호([])를 사용하며, 각 값은 쉼표(,)로 구분한다.
리스트를 일상에 비유하면 번호가 매겨진 서랍장이다. 첫 번째 서랍(0번), 두 번째 서랍(1번), … 순서대로 물건을 보관하고 번호로 꺼낼 수 있다.
6.1.2. 리스트 선언하기
1nums = [10, 20, 30, 40, 50]2names = ["홍길동", "김영희", "이철수"]3mixed = [1, "파이썬", True, 3.14]4empty = []5
6print(nums)7print(names)8print(mixed)9print(empty)| 줄 | 설명 |
|---|---|
| 1 | 정수 5개를 담은 리스트이다. |
| 2 | 문자열 3개를 담은 리스트이다. |
| 3 | 리스트는 서로 다른 자료형을 섞어서 담을 수 있다. |
| 4 | 아무것도 없는 빈 리스트이다. 나중에 값을 추가할 때 사용한다. |
실행 결과
1[10, 20, 30, 40, 50]2['홍길동', '김영희', '이철수']3[1, '파이썬', True, 3.14]4[]6.1.3. 인덱스로 요소 접근하기
리스트의 각 요소에는 위치를 나타내는 인덱스(Index)가 있다. 인덱스는 0부터 시작한다.
1리스트: ["홍길동", "김영희", "이철수"]2인덱스: 0 1 21names = ["홍길동", "김영희", "이철수"]2
3print(names[0])4print(names[1])5print(names[2])6print(names[-1])7print(names[-2])| 줄 | 설명 |
|---|---|
| 3 | names[0] 은 인덱스 0, 즉 첫 번째 요소 "홍길동" 이다. |
| 4 | names[1] 은 두 번째 요소 "김영희" 이다. |
| 5 | names[2] 는 세 번째 요소 "이철수" 이다. |
| 6 | names[-1] 은 뒤에서 첫 번째, 즉 마지막 요소 "이철수" 이다. |
| 7 | names[-2] 는 뒤에서 두 번째 요소 "김영희" 이다. |
실행 결과
1홍길동2김영희3이철수4이철수5김영희6.1.4. 리스트 슬라이싱
리스트도 문자열처럼 [시작:끝] 으로 일부분을 잘라낼 수 있다.
1nums = [10, 20, 30, 40, 50]2
3print(nums[1:4])4print(nums[:3])5print(nums[2:])6print(nums[::2])| 줄 | 설명 |
|---|---|
| 3 | 인덱스 1~3까지의 요소 [20, 30, 40] 를 반환한다. 끝 인덱스 4는 포함되지 않는다. |
| 4 | 처음부터 인덱스 2까지 [10, 20, 30] 를 반환한다. |
| 5 | 인덱스 2부터 끝까지 [30, 40, 50] 를 반환한다. |
| 6 | [::2] 는 2칸씩 건너뛰며 [10, 30, 50] 를 반환한다. |
실행 결과
1[20, 30, 40]2[10, 20, 30]3[30, 40, 50]4[10, 30, 50]6.1.5. 리스트 요소 수정하기
인덱스로 특정 위치의 요소를 수정할 수 있다.
1items = ["검", "방패", "화살"]2print("수정 전:", items)3
4items[1] = "갑옷"5print("수정 후:", items)| 줄 | 설명 |
|---|---|
| 1 | 3개 아이템을 담은 리스트를 선언한다. |
| 4 | items[1] 은 두 번째 요소이다. "방패" 를 "갑옷" 으로 바꾼다. |
실행 결과
1수정 전: ['검', '방패', '화살']2수정 후: ['검', '갑옷', '화살']6.1.6. 리스트 주요 메서드(Method)
1items = ["검", "방패"]2print("초기:", items)3
4items.append("화살")5print("append 후:", items)6
7items.insert(1, "갑옷")8print("insert 후:", items)9
10items.remove("방패")11print("remove 후:", items)12
13popped = items.pop()14print("pop 후:", items)15print("꺼낸 값:", popped)16
17items.sort()18print("sort 후:", items)19
20print("길이:", len(items))| 줄 | 설명 |
|---|---|
| 4 | append("화살"): 리스트 끝에 "화살" 을 추가한다. |
| 7 | insert(1, "갑옷"): 인덱스 1번 자리에 "갑옷" 을 삽입한다. 기존 요소들은 뒤로 밀린다. |
| 10 | remove("방패"): "방패" 값을 찾아 첫 번째로 발견된 것을 삭제한다. |
| 13 | pop(): 마지막 요소를 삭제하고 그 값을 반환한다. popped 에 저장된다. |
| 17 | sort(): 리스트를 오름차순으로 정렬한다. 문자열이면 가나다순이다. |
| 20 | len(items): 현재 리스트의 요소 개수를 반환한다. |
6.1.7. 리스트와 for 반복문
1scores = [85, 92, 78, 95, 60]2total = 03
4for s in scores:5 total += s6
7avg = total / len(scores)8print(f"합계: {total}")9print(f"평균: {avg:.1f}")10print(f"최고점: {max(scores)}")11print(f"최저점: {min(scores)}")| 줄 | 설명 |
|---|---|
| 1~2 | 점수 리스트와 합계 변수를 선언한다. |
| 4~5 | 리스트의 각 점수를 s 에 담으며 반복한다. 매 반복마다 total 에 s 를 더한다. |
| 7 | 합계를 점수 개수로 나누어 평균을 계산한다. |
| 8~11 | 합계, 평균, 최고점, 최저점을 출력한다. max(), min() 은 리스트의 최댓값과 최솟값을 반환하는 내장 함수이다. |
실행 결과
1합계: 4102평균: 82.03최고점: 954최저점: 606.2. 딕셔너리(Dictionary)
6.2.1. 딕셔너리란?
딕셔너리(Dictionary)는 키(Key) 와 값(Value) 의 쌍으로 데이터를 저장하는 자료형이다. 중괄호({})를 사용한다.
실사전에서 단어(키)를 찾으면 그 뜻(값)을 알 수 있는 것과 같은 구조이다.
리스트는 순서(번호)로 접근하지만, 딕셔너리는 이름(키) 으로 접근한다.
6.2.2. 딕셔너리 선언하기
1char = {2 "name": "홍길동",3 "job": "전사",4 "lv": 30,5 "hp": 1200.0,6 "is_alive": True7}8
9print(char)| 줄 | 설명 |
|---|---|
| 1 | 중괄호 {} 로 딕셔너리를 시작한다. |
| 2~6 | 키: 값 형식으로 각 항목을 작성한다. 키는 주로 문자열을 사용한다. |
| 7 | 중괄호 } 로 딕셔너리를 닫는다. |
6.2.3. 값 읽기
딕셔너리[키] 형식으로 값을 읽는다.
1char = {"name": "홍길동", "job": "전사", "lv": 30}2
3print(char["name"])4print(char["job"])5print(char["lv"])| 줄 | 설명 |
|---|---|
| 3 | char["name"] 은 키 "name" 에 해당하는 값 "홍길동" 을 반환한다. |
| 4 | 키 "job" 에 해당하는 값 "전사" 를 반환한다. |
| 5 | 키 "lv" 에 해당하는 값 30 을 반환한다. |
실행 결과
1홍길동2전사330주의
존재하지 않는 키를 사용하면 KeyError 오류가 발생한다. 키가 있는지 확인할 때는 in 연산자를 사용한다. "name" in char 처럼 쓰면 키가 있으면 True, 없으면 False 를 반환한다.
6.2.4. get() 메서드로 안전하게 읽기
get() 메서드는 키가 없을 때 오류 대신 기본값(기본은 None)을 반환한다.
1char = {"name": "홍길동", "lv": 30}2
3print(char.get("name"))4print(char.get("job"))5print(char.get("job", "직업 없음"))| 줄 | 설명 |
|---|---|
| 3 | 키 "name" 이 있으므로 "홍길동" 을 반환한다. |
| 4 | 키 "job" 이 없으므로 None 을 반환한다. 오류가 발생하지 않는다. |
| 5 | 두 번째 인수로 기본값 "직업 없음" 을 지정했으므로 키가 없을 때 "직업 없음" 을 반환한다. |
실행 결과
1홍길동2None3직업 없음6.2.5. 값 추가, 수정, 삭제
1char = {"name": "홍길동", "lv": 30}2print("초기:", char)3
4char["lv"] = 315print("수정:", char)6
7char["job"] = "전사"8print("추가:", char)9
10del char["name"]11print("삭제:", char)| 줄 | 설명 |
|---|---|
| 4 | 이미 있는 키 "lv" 에 새 값 31 을 대입하면 기존 값이 수정된다. |
| 7 | 없는 키 "job" 에 값을 대입하면 새 항목이 추가된다. |
| 10 | del 딕셔너리[키] 로 해당 키-값 쌍을 삭제한다. |
실행 결과
1초기: {'name': '홍길동', 'lv': 30}2수정: {'name': '홍길동', 'lv': 31}3추가: {'name': '홍길동', 'lv': 31, 'job': '전사'}4삭제: {'lv': 31, 'job': '전사'}6.2.6. 딕셔너리 주요 메서드
1char = {"name": "홍길동", "job": "전사", "lv": 30}2
3print(char.keys())4print(char.values())5print(char.items())6print("lv" in char)7print("hp" in char)| 줄 | 설명 |
|---|---|
| 3 | keys() : 딕셔너리의 모든 키를 반환한다. |
| 4 | values() : 딕셔너리의 모든 값을 반환한다. |
| 5 | items() : 딕셔너리의 모든 키-값 쌍을 (키, 값) 형태로 반환한다. |
| 6 | "lv" in char : 키 "lv" 가 딕셔너리에 있으면 True 를 반환한다. |
| 7 | "hp" in char : 키 "hp" 가 없으므로 False 를 반환한다. |
실행 결과
1dict_keys(['name', 'job', 'lv'])2dict_values(['홍길동', '전사', 30])3dict_items([('name', '홍길동'), ('job', '전사'), ('lv', 30)])4True5False6.2.7. 딕셔너리와 for 반복문
1char = {"name": "홍길동", "job": "전사", "lv": 30, "hp": 1200}2
3print("[ 키만 반복 ]")4for k in char.keys():5 print(k)6
7print("[ 값만 반복 ]")8for v in char.values():9 print(v)10
11print("[ 키-값 동시 반복 ]")12for k, v in char.items():13 print(f"{k}: {v}")| 줄 | 설명 |
|---|---|
| 4 | keys() 로 키만 반복한다. |
| 8 | values() 로 값만 반복한다. |
| 12 | items() 로 키와 값을 동시에 반복한다. k 에 키, v 에 값이 담긴다. |
실행 결과
1[ 키만 반복 ]2name3job4lv5hp6[ 값만 반복 ]7홍길동8전사93010120011[ 키-값 동시 반복 ]12name: 홍길동13job: 전사14lv: 3015hp: 12006.3. 리스트 안에 딕셔너리 담기
6.3.1. 복합 구조란?
실제 프로그램에서는 여러 사람의 정보를 관리해야 한다. 이때 리스트 안에 딕셔너리를 넣는 복합 구조를 사용한다.
1students = [2 {"name": "홍길동", "score": 88},3 {"name": "김영희", "score": 95},4 {"name": "이철수", "score": 72},5]이 구조는 아래처럼 생각하면 된다.
students: 전체 학생 리스트students[0]: 첫 번째 학생 딕셔너리{"name": "홍길동", "score": 88}students[0]["name"]: 첫 번째 학생의 이름"홍길동"students[0]["score"]: 첫 번째 학생의 점수88
6.3.2. 복합 구조 접근하기
1students = [2 {"name": "홍길동", "score": 88},3 {"name": "김영희", "score": 95},4 {"name": "이철수", "score": 72},5]6
7print(students[0])8print(students[0]["name"])9print(students[1]["score"])| 줄 | 설명 |
|---|---|
| 7 | students[0] 은 첫 번째 딕셔너리 전체를 반환한다. |
| 8 | students[0]["name"] 은 첫 번째 딕셔너리의 "name" 키 값을 반환한다. |
| 9 | students[1]["score"] 는 두 번째 딕셔너리의 "score" 키 값을 반환한다. |
실행 결과
1{'name': '홍길동', 'score': 88}2홍길동3956.3.3. 복합 구조와 for 반복문
1students = [2 {"name": "홍길동", "score": 88},3 {"name": "김영희", "score": 95},4 {"name": "이철수", "score": 72},5]6
7for stu in students:8 print(f"{stu['name']}: {stu['score']}점")| 줄 | 설명 |
|---|---|
| 7 | 반복마다 stu 에 각 딕셔너리가 담긴다. 첫 번째 반복에서 stu = {"name": "홍길동", "score": 88} 이다. |
| 8 | stu['name'] 과 stu['score'] 로 딕셔너리의 값에 접근한다. f-string 안에서 따옴표를 쓸 때는 작은따옴표(')를 사용한다. |
실행 결과
1홍길동: 88점2김영희: 95점3이철수: 72점6.4. 종합 예제: 학생 성적 관리 프로그램
1students = [2 {"name": "홍길동", "kor": 80, "math": 90, "eng": 85},3 {"name": "김영희", "kor": 95, "math": 88, "eng": 92},4 {"name": "이철수", "kor": 70, "math": 75, "eng": 68},5]6
7print("===== 성적표 =====")8
9for stu in students:10 total = stu["kor"] + stu["math"] + stu["eng"]11 avg = total / 312 print(f"{stu['name']}: 국어 {stu['kor']} / 수학 {stu['math']} / 영어 {stu['eng']} | 평균 {avg:.1f}")13
14print("------------------")15
16all_avgs = []17for stu in students:18 avg = (stu["kor"] + stu["math"] + stu["eng"]) / 319 all_avgs.append(avg)20
21best_idx = all_avgs.index(max(all_avgs))22print(f"전체 평균 1등: {students[best_idx]['name']} ({max(all_avgs):.1f}점)")| 줄 | 설명 |
|---|---|
| 1~5 | 학생 3명의 국어, 수학, 영어 점수를 리스트 안의 딕셔너리 형태로 저장한다. |
| 9~12 | 각 학생의 세 과목 합계와 평균을 계산하여 출력한다. |
| 15~18 | 각 학생의 평균을 all_avgs 리스트에 추가한다. |
| 20 | max(all_avgs) 로 최고 평균을 구하고, index() 로 그 위치(인덱스)를 찾는다. |
| 21 | 가장 높은 평균을 가진 학생의 이름과 점수를 출력한다. |
실행 결과
1===== 성적표 =====2홍길동: 국어 80 / 수학 90 / 영어 85 | 평균 85.03김영희: 국어 95 / 수학 88 / 영어 92 | 평균 91.74이철수: 국어 70 / 수학 75 / 영어 68 | 평균 71.05------------------6전체 평균 1등: 김영희 (91.7점)6.5. 실습 과제
과제 1. 나만의 영어 단어장
단어(영어)와 뜻(한국어)을 딕셔너리에 5개 이상 저장하고, 아래처럼 목록을 출력한다.
1===== 단어장 =====2apple: 사과3banana: 바나나4...5총 5개의 단어1words = {2 "apple": "사과",3 "banana": "바나나",4 "cherry": "체리",5 "grape": "포도",6 "mango": "망고",7}8
9print("===== 단어장 =====")10for en, ko in words.items():11 print(f"{en}: {ko}")12print(f"총 {len(words)}개의 단어")과제 2. 쇼핑몰 장바구니 프로그램
상품 이름과 가격을 담은 딕셔너리를 리스트에 3개 이상 저장하고, 전체 목록 출력 후 가장 저렴한 상품과 가장 비싼 상품, 총 금액을 출력한다.
1cart = [2 {"name": "라면", "price": 800},3 {"name": "과자", "price": 1500},4 {"name": "음료수", "price": 2000},5 {"name": "아이스크림", "price": 1200},6]7
8print("===== 장바구니 =====")9total = 010for item in cart:11 print(f"{item['name']}: {item['price']}원")12 total += item['price']13
14prices = [item["price"] for item in cart]15cheap = cart[prices.index(min(prices))]16exp = cart[prices.index(max(prices))]17
18print("--------------------")19print(f"합계: {total}원")20print(f"최저가: {cheap['name']} ({cheap['price']}원)")21print(f"최고가: {exp['name']} ({exp['price']}원)")