거르기는 빈 리스트를 하나 두고, 값을 하나씩 꺼내 조건에 맞는 것만 그 리스트에 담는 틀입니다. 바꿔 담기는 꺼낸 값을 바꿔서 담는 같은 틀입니다.
가격 가운데 4000원 넘는 것만 고르거나, 모든 가격을 500원씩 올린 새 가격표를 만들 때가 있습니다. 원래 리스트에서 값을 지우거나 칸을 고치면 처음 리스트가 사라집니다. 거르기와 바꿔 담기는 원래 리스트를 그대로 두고, 고른 값이나 바꾼 값을 새 리스트에 담습니다. 이 레슨은 거르기와 바꿔 담기 코드를 직접 쓰는 틀 레슨입니다. 풀이 예제를 하위 목표 셋으로 나눠 읽고, 빈칸을 채우며 쓰기로 넘어갑니다.
1거르기의 세 하위 목표
가격 가운데 4000원보다 비싼 값만 고르는 풀이 예제이고, 그림의 코드입니다.
prices = [4000, 4500, 3500]
# 1. 빈 리스트
picked = []
# 2. 하나씩 꺼내 (맞으면) 담기
for price in prices:
if price > 4000:
picked.append(price)
# 3. 끝나고 쓰기
print(picked)
[4500]- 1. 빈 리스트: 3번 줄이 칸이 없는 새 리스트 ②를 만들고 이름
picked를 붙입니다. 아직 아무것도 고르지 않았습니다. - 2. 하나씩 꺼내 (맞으면) 담기: 5번 줄이 가격을 하나씩 꺼내
price를 붙이고, 6번 줄의 조건이True일 때만 7번 줄이 그 값을picked끝에 더합니다. - 3. 끝나고 쓰기: 반복이 다 끝난 뒤 담은 리스트를 한 번 찍습니다.
| 줄 | 바뀐 이름 | 값 | 출력 |
|---|---|---|---|
| 1 | prices | ① [4000, 4500, 3500] | |
| 3 | picked | ② [] | |
| 5 | price | 4000 | |
| 6 | 조건 price > 4000 | False | |
| 5 | price | 4500 | |
| 6 | 조건 price > 4000 | True | |
| 7 | picked | ② [4500] | |
| 5 | price | 3500 | |
| 6 | 조건 price > 4000 | False | |
| 5 | 꺼낼 수 없음 — 반복 끝 | ||
| 9 | [4500] |
7번 줄 append()는 이름을 다시 붙이지 않고 리스트 ②를 제자리에서 바꿉니다. 이런 줄도 바뀐 이름 칸에 그 이름을, 값 칸에 바뀐 리스트를 적습니다. 꼬리표가 ② 그대로라 새 리스트가 아니라 같은 리스트입니다.
picked처럼 고른 값을 모아 담는 이름을 담는 그릇이라고 부릅니다. 원래 리스트 ①은 처음 그대로입니다.
2바꿔 담기
모든 가격을 500원씩 올린 새 가격표를 만듭니다. 모든 값을 담으니 조건이 없고, 2번 하위 목표는 '하나씩 꺼내 담기'입니다.
prices = [4000, 4500, 3500]
# 1. 빈 리스트
raised = []
# 2. 하나씩 꺼내 담기
for price in prices:
raised.append(price + 500)
# 3. 끝나고 쓰기
print(raised)
print(prices)
[4500, 5000, 4000]
[4000, 4500, 3500]6번 줄은 price + 500을 먼저 계산한 새 값을 raised 끝에 더합니다. 바뀐 가격은 새 리스트에 담기고, 원래 prices는 그대로입니다.
3빈 리스트는 어디에 두는가
빈 리스트를 만드는 줄을 반복 안으로 옮겼습니다. 조건 price > 3000은 세 값 모두 True입니다. 무엇이 찍힐까요?
prices = [4000, 4500, 3500]
for price in prices:
picked = []
if price > 3000:
picked.append(price)
print(picked)
실행 결과 보기
[3500]예상과 다르면 그곳이 배울 곳입니다. 3번 줄은 덩어리 안에 있어 바퀴마다 실행됩니다. 바퀴마다 새 빈 리스트를 만들어 picked를 그 리스트에 다시 붙이니, 앞 바퀴에 담은 값은 아무도 가리키지 않는 리스트에 남고 마지막 바퀴의 3500만 남습니다(규칙 3·4).
1번 하위 목표 '빈 리스트'는 반복 앞에 한 번 둡니다.
예제
수를 돌리면
리스트 대신 수를 for에 넘겼습니다.
count = 3
for n in count:
print(n)
Traceback (most recent call last): File "main.py", line 2, in <module> for n in count: ^^^^^TypeError: 'int' object is not iterable맨 아래 줄은 'int(정수)는 하나씩 꺼낼 수 있는 값이 아니다'라는 뜻입니다. for는 리스트·문자열·range()처럼 값을 차례로 내주는 것만 돕니다. 수만큼 돌려면 for n in range(count):처럼 range()에 넘깁니다.
자주 틀리는 곳
틀린 생각: 리스트를 도는 중에 그 리스트에서 값을 지워도 남은 값을 다 본다.
돌면서 '커피'를 만날 때마다 지우면 '커피'가 다 사라질 것 같지만, 하나가 남습니다.
orders = ['커피', '커피', '라테']
for item in orders:
if item == '커피':
orders.remove(item)
print(orders)
['커피', '라테']for는 리스트의 칸을 0번, 1번, 2번 차례로 꺼냅니다. 0번 '커피'를 지우면 뒤 칸이 한 칸씩 앞으로 와서 둘째 '커피'가 0번 자리로 갑니다. 다음 바퀴는 1번 칸 '라테'를 꺼내므로 둘째 '커피'를 건너뜁니다.
맞는 규칙: 도는 리스트에서 값을 지우면 뒤 칸이 당겨져 다음 값을 건너뜁니다. 거를 때는 원래 리스트를 그대로 두고 남길 값을 새 리스트에 담습니다.
틀린 생각: 빈 리스트를 만드는 줄은 반복 안에 둬도 담은 값이 쌓인다.
처음에 한 번 만드는 리스트라 어디에 두든 같아 보이지만, 덩어리 안의 줄은 바퀴마다 실행됩니다.
for n in [1, 2, 3]:
picked = []
picked.append(n)
print(picked)
[3]맞는 규칙: 덩어리 안에서 picked = []를 쓰면 바퀴마다 새 빈 리스트에 다시 붙어 앞에서 담은 값이 사라집니다. 1번 하위 목표 '빈 리스트'는 반복 앞에 한 번 둡니다(규칙 4).
확인 문제
1. 1절 풀이 예제의 6번 줄을 if price > 4500:으로 바꿨습니다. 무엇이 찍힐까요?
prices = [4000, 4500, 3500]
# 1. 빈 리스트
picked = []
# 2. 하나씩 꺼내 (맞으면) 담기
for price in prices:
if price > 4500:
picked.append(price)
# 3. 끝나고 쓰기
print(picked)
힌트
바퀴마다 6번 줄 조건의 값을 추적 표에 적어 봅니다.
정답
[]세 값 모두 4500보다 크지 않아 7번 줄이 한 번도 실행되지 않습니다. 아무것도 담지 않은 빈 리스트는 []로 찍힙니다.
흔한 오답은 [4500]입니다. 같은 값도 담는다고 본 것입니다. > 연산자는 두 값이 같으면 False입니다.
2. 빈칸을 채워 코드를 완성하세요.
(가) 4000원보다 싼 값만 담아 [3500]이 찍히도록 한 줄의 빈칸을 채우세요.
prices = [4000, 4500, 3500]
# 1. 빈 리스트
cheap = []
# 2. 하나씩 꺼내 (맞으면) 담기
for price in prices:
if price < 4000:
________
# 3. 끝나고 쓰기
print(cheap)
힌트
2번 하위 목표 '하나씩 꺼내 (맞으면) 담기'에서 담는 줄입니다.
정답
cheap.append(price)입니다.
prices = [4000, 4500, 3500]
# 1. 빈 리스트
cheap = []
# 2. 하나씩 꺼내 (맞으면) 담기
for price in prices:
if price < 4000:
cheap.append(price)
# 3. 끝나고 쓰기
print(cheap)[3500]다르게 써도 되는 곳: cheap.extend([price])나 cheap = cheap + [price]도 [3500]이 찍힙니다. 빈칸에 cheap.append(3500)을 써도 같지만, 가격을 바꾸면 따라 바뀌지 않습니다.
흔한 오답은 cheap = cheap.append(price)입니다. append()가 돌려준 None에 cheap을 다시 붙여 None이 찍힙니다. append()가 늘린 리스트를 돌려준다고 본 것입니다.
(나) 주문 가운데 '커피'만 골라 담습니다. 2번 하위 목표를 통째로 채우세요. 다 채운 코드는 ['커피', '커피']를 찍어야 하고, 1번 줄을 items = ['녹차', '커피']로 바꾸면 ['커피']를 찍어야 합니다.
items = ['커피', '라테', '커피']
# 1. 빈 리스트
coffee = []
# 2. 하나씩 꺼내 (맞으면) 담기
# 3. 끝나고 쓰기
print(coffee)
힌트
1절 풀이 예제의 2번 하위 목표와 같은 세 줄입니다. 조건은 꺼낸 값이 '커피'와 같은지입니다.
정답
items = ['커피', '라테', '커피']
# 1. 빈 리스트
coffee = []
# 2. 하나씩 꺼내 (맞으면) 담기
for item in items:
if item == '커피':
coffee.append(item)
# 3. 끝나고 쓰기
print(coffee)['커피', '커피']다르게 써도 되는 곳: 꺼낸 값의 이름은 item 말고 다른 낱말로 지어도 됩니다. 7번 줄은 coffee.append('커피')로 써도 두 시험 값 모두 같습니다.
흔한 오답은 if 줄 없이 모두 담는 것입니다. 그러면 ['커피', '라테', '커피']가 찍히고, 둘째 시험 값에서도 ['녹차', '커피']가 찍힙니다. 조건 없이 담기만 해도 '커피'만 골라진다고 본 것입니다.
3. 시험 점수마다 5점씩 더하려고 쓴 코드입니다. 무엇이 찍힐까요?
scores = [70, 85, 90]
for score in scores:
score = score + 5
print(scores)
힌트
바퀴마다 3번 줄 뒤에 이름 score와 리스트 scores의 칸이 각각 무엇을 가리키는지 이름표로 그려 봅니다.
정답
[70, 85, 90]2번 줄은 칸 값을 꺼내 그 값에 이름 score를 붙입니다. 3번 줄은 score + 5로 새 값을 만들어 이름 score만 그 값에 다시 붙일 뿐, 리스트의 칸은 건드리지 않습니다.
흔한 오답은 [75, 90, 95]입니다. 이름 score가 리스트의 칸 자체라서 다시 붙이면 칸이 바뀐다고 본 것입니다(따라 옮겨 간다는 생각). 다시 붙이기는 이름만 옮깁니다(규칙 3). 5점씩 더한 점수가 필요하면 2절처럼 새 리스트에 담습니다.
아래 코드 1번 줄 리스트 끝에 5000을 한 칸 더하면 무엇이 찍히는지 봅니다.
처음 펼 때 약 6MB를 받습니다.컴퓨터에서 해 보기
파이썬 3.14. Tab을 누르면 다음 단추나 칸으로 갑니다. 들여쓰기는 빈칸 네 개입니다. Enter는 앞줄 들여쓰기를 잇고, 콜론 뒤에서는 한 단계 더 들여 씁니다. Ctrl+Enter로 실행합니다.
'실행'을 누르면 여기에 나옵니다.
여기서 쓴 코드 · 내 예상은 저장하지도 운영자에게 보내지도 않습니다. 페이지를 새로 열면 처음 코드입니다.