이 페이지의 목차
여러 값을 한 번에 — 리스트와 배열
코드 예제: Python · C · 예상 50분
학습 목표
- 여러 값을 하나의 이름으로 묶어 다루는 방법을 설명한다.
- 리스트 또는 배열을 사용한 프로그램을 작성한다.
관련 성취기준
- 프그02-01
변수와 자료형의 개념과 특징을 이해하고, 구분하여 지정할 수 있으며, 이들을 사용한 프로그램을 작성할 수 있다.
생각 열기 — 변수 서른 개
반 학생 서른 명의 점수를 다뤄야 한다. 지금까지 배운 것으로 하면 이렇게 된다.
점수1 = 88
점수2 = 92
점수3 = 75
...
점수30 = 64
합계를 구하려면 점수1 + 점수2 + ... + 점수30 을 손으로 적어야 한다. 학생이 한 명 늘면 코드를 또 고쳐야 한다.
리스트와 배열 — 값을 줄지어 담는다
여러 값을 하나의 이름으로 묶어 순서대로 담은 것을 Python에서는 리스트(list) — 여러 값을 순서대로 담은 자료. 크기를 바꿀 수 있다, C에서는 배열(array) — 같은 자료형의 값을 정해진 개수만큼 이어서 담은 자료이라 한다.
3차시의 문자열처럼 인덱스로 꺼낸다. 0번부터 센다.
점수 = [88, 92, 75, 100, 64]
print("개수:", len(점수))
print("첫째:", 점수[0], "/ 마지막:", 점수[-1])
print("합계:", sum(점수))
print("평균:", sum(점수) / len(점수))
print("최고:", max(점수))
점수.append(70)
print("하나 넣은 뒤:", 점수)개수: 5 첫째: 88 / 마지막: 64 합계: 419 평균: 83.8 최고: 100 하나 넣은 뒤: [88, 92, 75, 100, 64, 70]
#include <stdio.h>
int main(void)
{
int scores[5] = {88, 92, 75, 100, 64};
int n = 5;
int sum = 0, high = scores[0];
for (int i = 0; i < n; i++) {
sum += scores[i];
if (scores[i] > high) high = scores[i];
}
printf("개수: %d\n", n);
printf("첫째: %d / 마지막: %d\n", scores[0], scores[n - 1]);
printf("합계: %d\n", sum);
printf("평균: %.1f\n", (double)sum / n);
printf("최고: %d\n", high);
return 0;
}개수: 5 첫째: 88 / 마지막: 64 합계: 419 평균: 83.8 최고: 100
두 코드의 길이가 다른 까닭
같은 일을 하는데 C 쪽이 길다. 언어가 대신 해 주는 일이 다르기 때문이다.
| Python 리스트 | C 배열 | |
|---|---|---|
| 크기 | 늘었다 줄었다 한다 | 만들 때 정하면 바뀌지 않는다 |
| 담는 값 | 종류가 섞여도 된다 | 같은 자료형만 |
| 개수 알기 | len(점수) | 자기 길이를 모른다 — 개수를 따로 들고 다닌다 |
| 합계·최댓값 | sum(), max() 가 있다 | 반복문으로 직접 구한다 |
| 하나 더 넣기 | append() | 자리가 남아 있어야 하고 개수도 손으로 늘린다 |
C 코드에서 int n = 5; 를 따로 들고 다니는 것을 눈여겨보자. 배열은 자기 길이를 모르므로, 개수를 잃어버리면 어디까지가 값인지 알 수 없다. 3단원 5차시에서 average(scores, 5, &avg) 처럼 개수를 함께 넘긴 것이 이 때문이다.
반복과 만나면 힘이 생긴다
리스트의 진짜 쓸모는 반복문과 만날 때 나온다. 학생이 30명이든 300명이든 코드가 그대로다.
합계 ← 0
점수 목록의 각 점수에 대하여 되풀이한다
합계 ← 합계 + 점수
평균 ← 합계 ÷ 개수
1단원 7차시에서 그린 이 의사 코드가 위 C 예제의 for 문 그대로다. 반복은 10차시에서 본격적으로 다룬다.
활동
학급 점수 목록의 평균과 최댓값 구하기
약 25분1단계 — 값을 바꿔 본다 (5분)
실행기의 [고치기]로 점수 목록을 우리 반 모둠 인원수만큼 바꿔 보자. 코드의 다른 곳을 안 고쳐도 되는지 확인한다.
- Python에서 목록만 바꾸면 되는가?
- C에서는 무엇을 함께 고쳐야 하는가?
2단계 — 표를 채운다 (10분)
| 하려는 일 | Python 코드 | C에서는 어떻게 |
|---|---|---|
| 개수 알기 | len(점수) |
|
| 세 번째 값 | ||
| 마지막 값 | ||
| 합계 | ||
| 최댓값 | ||
| 값 하나 더 넣기 |
3단계 — 최저점을 더한다 (5분)
두 코드에 최저점을 구해 출력하는 부분을 더한다.
- Python은 무엇을 쓰면 되는가?
- C에서는 최고점 구하는 부분을 어떻게 흉내 내면 되는가?
- C에서 최저점의 처음 값을
100으로 두면 어떤 경우에 틀리는가? (1단원 7차시 활동과 3단원 4차시를 떠올려 보자)
4단계 — 일부러 넘어가 본다 (5분)
점수[5] 처럼 없는 자리를 읽어 본다.
| 언어 | 무슨 일이 일어났는가 | 오류 메시지가 있었나 |
|---|---|---|
| Python | ||
| C |
어느 쪽이 더 위험한지, 왜 그런지 한 문장으로 적는다.
개념 확인 문제
보기를 누르면 바로 채점된다. 틀려도 해설을 읽으면 된다.
점수 = [88, 92, 75, 100, 64] 일 때 점수[2] 는?프그02-01
C에서 배열과 함께 개수를 따로 들고 다녀야 하는 까닭은?프그02-01
크기가 5인 C 배열에서 scores[5] 를 읽으면?프그02-01
Python 리스트와 C 배열의 차이로 알맞지 않은 것은?프그02-01
여러 값을 리스트로 묶으면 학생 수가 늘어도 코드를 거의 고치지 않아도 된다. 그 까닭으로 가장 알맞은 것은?프그02-01
더 알아보기
심화리스트를 복사한다는 것
1차시의 「더 알아보기」에서 Python 변수는 이름표에 가깝다고 했다. 그 차이가 리스트에서 실제 문제로 나타난다.
a = [1, 2, 3]
b = a
b.append(4)
print(a) # [1, 2, 3, 4]b 를 고쳤는데 a 도 바뀐다. 상자를 복사한 것이 아니라 같은 리스트에 이름표를 하나 더 붙인 것이기 때문이다. 진짜로 복사하려면 b = a[:] 처럼 잘라 내기로 새 리스트를 만들어야 한다. 이 함정은 실제로 자주 걸리므로 한 번 실행해 보는 것이 좋다.
심화값이 메모리에 이어져 있다는 뜻
배열은 값들이 메모리에 붙어서 놓인다. int 가 4바이트라면 scores[0] 다음 4바이트가 scores[1] 이다. 그래서 scores[i] 를 찾는 계산이 “시작 주소 + i × 4” 로 끝난다 — 몇 번째든 같은 시간에 찾는다. 이것이 인덱스로 꺼내는 일이 빠른 이유다. 반대로 중간에 값을 끼워 넣으려면 뒤의 값을 전부 한 칸씩 밀어야 해서 느리다. 자료를 어떤 모양으로 담을지가 무엇이 빠른지를 정한다 — 3단원 3차시에서 자료의 모양을 설계에 적어 둔 이유다.
실무표처럼 다루려면 — 2차원
학생마다 여러 과목 점수를 다루려면 어떻게 할까. 리스트 안에 리스트를 넣으면 된다.
점수 = [[88, 92, 75],
[70, 80, 90]]
점수[0][1] # 첫째 학생의 둘째 과목 → 92C에서는 int scores[2][3]; 처럼 적는다. 이렇게 두 번호로 가리키는 것을 2차원 배열이라 한다. 11차시에서 중첩 반복을 배우면 이 표를 한 칸씩 훑을 수 있게 된다.
이어지는 학습
이 차시를 이해하려면 다음을 먼저 알아야 한다.
- 3차시의 인덱스 개념 — 프로그래밍 프그02-01
교과서에서 찾기
| 교과서 | 해당 위치 | 쪽수 |
|---|---|---|
| 성림출판(Python) | 프로그래밍의 기초 › 01 변수와 자료형 | 58쪽 |
| 씨마스커뮤니케이션(Python) | 프로그래밍 기초 › 2 변수와 자료형 | 84쪽 |
| 삼양미디어(Python) | 프로그래밍의 기초 › 01 데이터 입출력 (프그02-02와 통합) | 42쪽 |
| 삼양미디어(C) | 프로그래밍의 기초 › 01 데이터 입출력 (프그02-02와 통합) | 42쪽 |
| 씨마스(C) | C 프로그래밍의 기초 › 1 변수와 자료형 | 62쪽 |
| 웅보출판사(C) | 프로그래밍의 기초 › Chapter 01 변수와 자료형 | 61쪽 |