Type something to search...

6회차: 리스트 & 딕셔너리

6회차: 리스트 & 딕셔너리

선수 학습: 5회차 (함수)


학습 목표

  • 리스트(List)의 개념을 이해하고 다양하게 활용할 수 있다.
  • 딕셔너리(Dictionary)의 개념을 이해하고 다양하게 활용할 수 있다.
  • 리스트와 딕셔너리를 반복문과 함께 사용할 수 있다.
  • 리스트 안에 딕셔너리를 담는 복합 구조를 이해할 수 있다.

6.1. 리스트(List)

6.1.1. 리스트란?

리스트(List)는 여러 개의 값을 순서대로 담는 자료형이다. 대괄호([])를 사용하며, 각 값은 쉼표(,)로 구분한다.

리스트를 일상에 비유하면 번호가 매겨진 서랍장이다. 첫 번째 서랍(0번), 두 번째 서랍(1번), … 순서대로 물건을 보관하고 번호로 꺼낼 수 있다.

6.1.2. 리스트 선언하기

1
nums = [10, 20, 30, 40, 50]
2
names = ["홍길동", "김영희", "이철수"]
3
mixed = [1, "파이썬", True, 3.14]
4
empty = []
5
6
print(nums)
7
print(names)
8
print(mixed)
9
print(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 2
1
names = ["홍길동", "김영희", "이철수"]
2
3
print(names[0])
4
print(names[1])
5
print(names[2])
6
print(names[-1])
7
print(names[-2])
설명
3names[0] 은 인덱스 0, 즉 첫 번째 요소 "홍길동" 이다.
4names[1] 은 두 번째 요소 "김영희" 이다.
5names[2] 는 세 번째 요소 "이철수" 이다.
6names[-1] 은 뒤에서 첫 번째, 즉 마지막 요소 "이철수" 이다.
7names[-2] 는 뒤에서 두 번째 요소 "김영희" 이다.

실행 결과

1
홍길동
2
김영희
3
이철수
4
이철수
5
김영희

6.1.4. 리스트 슬라이싱

리스트도 문자열처럼 [시작:끝] 으로 일부분을 잘라낼 수 있다.

1
nums = [10, 20, 30, 40, 50]
2
3
print(nums[1:4])
4
print(nums[:3])
5
print(nums[2:])
6
print(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. 리스트 요소 수정하기

인덱스로 특정 위치의 요소를 수정할 수 있다.

1
items = ["검", "방패", "화살"]
2
print("수정 전:", items)
3
4
items[1] = "갑옷"
5
print("수정 후:", items)
설명
13개 아이템을 담은 리스트를 선언한다.
4items[1] 은 두 번째 요소이다. "방패""갑옷" 으로 바꾼다.

실행 결과

1
수정 전: ['검', '방패', '화살']
2
수정 후: ['검', '갑옷', '화살']

6.1.6. 리스트 주요 메서드(Method)

1
items = ["검", "방패"]
2
print("초기:", items)
3
4
items.append("화살")
5
print("append 후:", items)
6
7
items.insert(1, "갑옷")
8
print("insert 후:", items)
9
10
items.remove("방패")
11
print("remove 후:", items)
12
13
popped = items.pop()
14
print("pop 후:", items)
15
print("꺼낸 값:", popped)
16
17
items.sort()
18
print("sort 후:", items)
19
20
print("길이:", len(items))
설명
4append("화살"): 리스트 끝에 "화살" 을 추가한다.
7insert(1, "갑옷"): 인덱스 1번 자리에 "갑옷" 을 삽입한다. 기존 요소들은 뒤로 밀린다.
10remove("방패"): "방패" 값을 찾아 첫 번째로 발견된 것을 삭제한다.
13pop(): 마지막 요소를 삭제하고 그 값을 반환한다. popped 에 저장된다.
17sort(): 리스트를 오름차순으로 정렬한다. 문자열이면 가나다순이다.
20len(items): 현재 리스트의 요소 개수를 반환한다.

6.1.7. 리스트와 for 반복문

1
scores = [85, 92, 78, 95, 60]
2
total = 0
3
4
for s in scores:
5
total += s
6
7
avg = total / len(scores)
8
print(f"합계: {total}")
9
print(f"평균: {avg:.1f}")
10
print(f"최고점: {max(scores)}")
11
print(f"최저점: {min(scores)}")
설명
1~2점수 리스트와 합계 변수를 선언한다.
4~5리스트의 각 점수를 s 에 담으며 반복한다. 매 반복마다 totals 를 더한다.
7합계를 점수 개수로 나누어 평균을 계산한다.
8~11합계, 평균, 최고점, 최저점을 출력한다. max(), min() 은 리스트의 최댓값과 최솟값을 반환하는 내장 함수이다.

실행 결과

1
합계: 410
2
평균: 82.0
3
최고점: 95
4
최저점: 60

6.2. 딕셔너리(Dictionary)

6.2.1. 딕셔너리란?

딕셔너리(Dictionary)는 키(Key)값(Value) 의 쌍으로 데이터를 저장하는 자료형이다. 중괄호({})를 사용한다.

실사전에서 단어(키)를 찾으면 그 뜻(값)을 알 수 있는 것과 같은 구조이다.

리스트는 순서(번호)로 접근하지만, 딕셔너리는 이름(키) 으로 접근한다.

6.2.2. 딕셔너리 선언하기

1
char = {
2
"name": "홍길동",
3
"job": "전사",
4
"lv": 30,
5
"hp": 1200.0,
6
"is_alive": True
7
}
8
9
print(char)
설명
1중괄호 {} 로 딕셔너리를 시작한다.
2~6키: 값 형식으로 각 항목을 작성한다. 키는 주로 문자열을 사용한다.
7중괄호 } 로 딕셔너리를 닫는다.

6.2.3. 값 읽기

딕셔너리[키] 형식으로 값을 읽는다.

1
char = {"name": "홍길동", "job": "전사", "lv": 30}
2
3
print(char["name"])
4
print(char["job"])
5
print(char["lv"])
설명
3char["name"] 은 키 "name" 에 해당하는 값 "홍길동" 을 반환한다.
4"job" 에 해당하는 값 "전사" 를 반환한다.
5"lv" 에 해당하는 값 30 을 반환한다.

실행 결과

1
홍길동
2
전사
3
30

주의

존재하지 않는 키를 사용하면 KeyError 오류가 발생한다. 키가 있는지 확인할 때는 in 연산자를 사용한다. "name" in char 처럼 쓰면 키가 있으면 True, 없으면 False 를 반환한다.

6.2.4. get() 메서드로 안전하게 읽기

get() 메서드는 키가 없을 때 오류 대신 기본값(기본은 None)을 반환한다.

1
char = {"name": "홍길동", "lv": 30}
2
3
print(char.get("name"))
4
print(char.get("job"))
5
print(char.get("job", "직업 없음"))
설명
3"name" 이 있으므로 "홍길동" 을 반환한다.
4"job" 이 없으므로 None 을 반환한다. 오류가 발생하지 않는다.
5두 번째 인수로 기본값 "직업 없음" 을 지정했으므로 키가 없을 때 "직업 없음" 을 반환한다.

실행 결과

1
홍길동
2
None
3
직업 없음

6.2.5. 값 추가, 수정, 삭제

1
char = {"name": "홍길동", "lv": 30}
2
print("초기:", char)
3
4
char["lv"] = 31
5
print("수정:", char)
6
7
char["job"] = "전사"
8
print("추가:", char)
9
10
del char["name"]
11
print("삭제:", char)
설명
4이미 있는 키 "lv" 에 새 값 31 을 대입하면 기존 값이 수정된다.
7없는 키 "job" 에 값을 대입하면 새 항목이 추가된다.
10del 딕셔너리[키] 로 해당 키-값 쌍을 삭제한다.

실행 결과

1
초기: {'name': '홍길동', 'lv': 30}
2
수정: {'name': '홍길동', 'lv': 31}
3
추가: {'name': '홍길동', 'lv': 31, 'job': '전사'}
4
삭제: {'lv': 31, 'job': '전사'}

6.2.6. 딕셔너리 주요 메서드

1
char = {"name": "홍길동", "job": "전사", "lv": 30}
2
3
print(char.keys())
4
print(char.values())
5
print(char.items())
6
print("lv" in char)
7
print("hp" in char)
설명
3keys() : 딕셔너리의 모든 키를 반환한다.
4values() : 딕셔너리의 모든 값을 반환한다.
5items() : 딕셔너리의 모든 키-값 쌍을 (키, 값) 형태로 반환한다.
6"lv" in char : 키 "lv" 가 딕셔너리에 있으면 True 를 반환한다.
7"hp" in char : 키 "hp" 가 없으므로 False 를 반환한다.

실행 결과

1
dict_keys(['name', 'job', 'lv'])
2
dict_values(['홍길동', '전사', 30])
3
dict_items([('name', '홍길동'), ('job', '전사'), ('lv', 30)])
4
True
5
False

6.2.7. 딕셔너리와 for 반복문

1
char = {"name": "홍길동", "job": "전사", "lv": 30, "hp": 1200}
2
3
print("[ 키만 반복 ]")
4
for k in char.keys():
5
print(k)
6
7
print("[ 값만 반복 ]")
8
for v in char.values():
9
print(v)
10
11
print("[ 키-값 동시 반복 ]")
12
for k, v in char.items():
13
print(f"{k}: {v}")
설명
4keys() 로 키만 반복한다.
8values() 로 값만 반복한다.
12items() 로 키와 값을 동시에 반복한다. k 에 키, v 에 값이 담긴다.

실행 결과

1
[ 키만 반복 ]
2
name
3
job
4
lv
5
hp
6
[ 값만 반복 ]
7
홍길동
8
전사
9
30
10
1200
11
[ 키-값 동시 반복 ]
12
name: 홍길동
13
job: 전사
14
lv: 30
15
hp: 1200

6.3. 리스트 안에 딕셔너리 담기

6.3.1. 복합 구조란?

실제 프로그램에서는 여러 사람의 정보를 관리해야 한다. 이때 리스트 안에 딕셔너리를 넣는 복합 구조를 사용한다.

1
students = [
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. 복합 구조 접근하기

1
students = [
2
{"name": "홍길동", "score": 88},
3
{"name": "김영희", "score": 95},
4
{"name": "이철수", "score": 72},
5
]
6
7
print(students[0])
8
print(students[0]["name"])
9
print(students[1]["score"])
설명
7students[0] 은 첫 번째 딕셔너리 전체를 반환한다.
8students[0]["name"] 은 첫 번째 딕셔너리의 "name" 키 값을 반환한다.
9students[1]["score"] 는 두 번째 딕셔너리의 "score" 키 값을 반환한다.

실행 결과

1
{'name': '홍길동', 'score': 88}
2
홍길동
3
95

6.3.3. 복합 구조와 for 반복문

1
students = [
2
{"name": "홍길동", "score": 88},
3
{"name": "김영희", "score": 95},
4
{"name": "이철수", "score": 72},
5
]
6
7
for stu in students:
8
print(f"{stu['name']}: {stu['score']}점")
설명
7반복마다 stu 에 각 딕셔너리가 담긴다. 첫 번째 반복에서 stu = {"name": "홍길동", "score": 88} 이다.
8stu['name']stu['score'] 로 딕셔너리의 값에 접근한다. f-string 안에서 따옴표를 쓸 때는 작은따옴표(')를 사용한다.

실행 결과

1
홍길동: 88점
2
김영희: 95점
3
이철수: 72점

6.4. 종합 예제: 학생 성적 관리 프로그램

1
students = [
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
7
print("===== 성적표 =====")
8
9
for stu in students:
10
total = stu["kor"] + stu["math"] + stu["eng"]
11
avg = total / 3
12
print(f"{stu['name']}: 국어 {stu['kor']} / 수학 {stu['math']} / 영어 {stu['eng']} | 평균 {avg:.1f}")
13
14
print("------------------")
15
16
all_avgs = []
17
for stu in students:
18
avg = (stu["kor"] + stu["math"] + stu["eng"]) / 3
19
all_avgs.append(avg)
20
21
best_idx = all_avgs.index(max(all_avgs))
22
print(f"전체 평균 1등: {students[best_idx]['name']} ({max(all_avgs):.1f}점)")
설명
1~5학생 3명의 국어, 수학, 영어 점수를 리스트 안의 딕셔너리 형태로 저장한다.
9~12각 학생의 세 과목 합계와 평균을 계산하여 출력한다.
15~18각 학생의 평균을 all_avgs 리스트에 추가한다.
20max(all_avgs) 로 최고 평균을 구하고, index() 로 그 위치(인덱스)를 찾는다.
21가장 높은 평균을 가진 학생의 이름과 점수를 출력한다.

실행 결과

1
===== 성적표 =====
2
홍길동: 국어 80 / 수학 90 / 영어 85 | 평균 85.0
3
김영희: 국어 95 / 수학 88 / 영어 92 | 평균 91.7
4
이철수: 국어 70 / 수학 75 / 영어 68 | 평균 71.0
5
------------------
6
전체 평균 1등: 김영희 (91.7점)

6.5. 실습 과제

과제 1. 나만의 영어 단어장

단어(영어)와 뜻(한국어)을 딕셔너리에 5개 이상 저장하고, 아래처럼 목록을 출력한다.

1
===== 단어장 =====
2
apple: 사과
3
banana: 바나나
4
...
5
총 5개의 단어
1
words = {
2
"apple": "사과",
3
"banana": "바나나",
4
"cherry": "체리",
5
"grape": "포도",
6
"mango": "망고",
7
}
8
9
print("===== 단어장 =====")
10
for en, ko in words.items():
11
print(f"{en}: {ko}")
12
print(f"총 {len(words)}개의 단어")

과제 2. 쇼핑몰 장바구니 프로그램

상품 이름과 가격을 담은 딕셔너리를 리스트에 3개 이상 저장하고, 전체 목록 출력 후 가장 저렴한 상품과 가장 비싼 상품, 총 금액을 출력한다.

1
cart = [
2
{"name": "라면", "price": 800},
3
{"name": "과자", "price": 1500},
4
{"name": "음료수", "price": 2000},
5
{"name": "아이스크림", "price": 1200},
6
]
7
8
print("===== 장바구니 =====")
9
total = 0
10
for item in cart:
11
print(f"{item['name']}: {item['price']}원")
12
total += item['price']
13
14
prices = [item["price"] for item in cart]
15
cheap = cart[prices.index(min(prices))]
16
exp = cart[prices.index(max(prices))]
17
18
print("--------------------")
19
print(f"합계: {total}원")
20
print(f"최저가: {cheap['name']} ({cheap['price']}원)")
21
print(f"최고가: {exp['name']} ({exp['price']}원)")