코드는 요리 순서표와 비슷하다. 재료에 이름을 붙이고, 상황에 따라 다른 순서로 가고, 같은 일을 여러 번 하고, 자주 하는 일은 묶어서 이름을 붙인다. 코딩테스트에서는 이 순서표를 함수 하나로 쓰고, 마지막에 답을 돌려주면 끝난다. 화면에 찍거나 입력을 읽을 필요는 없다. 파이썬은 짧게 쓸 수 있는 대신 C 같은 언어보다 수십 배 느리다. 그래서 몇 번 반복하는지를 늘 신경 써야 한다.
예시로 보기
숫자가 짝수면 "Even", 홀수면 "Odd"를 돌려주는 답안이다. 프로그래머스 답안은 늘 이 모양이다.
def solution(num): # 1. solution이라는 함수를 만든다. num이 들어오는 값이다
if num % 2 == 0: # 2. 2로 나눈 나머지가 0이면
return "Even" # 3. "Even"을 답으로 돌려주고 끝낸다
else: # 4. 아니면
return "Odd" # 5. "Odd"를 돌려준다
채점하는 쪽은 solution(3), solution(4)처럼 함수를 불러서, 돌려받은 값이 정답과 같은지 본다. 그래서 답은 print로 찍는 게 아니라 return으로 돌려준다. 함수 이름과 괄호 안 이름은 문제에 적힌 그대로 둔다.
: 다음 줄을 안으로 들여 쓰는 것(보통 빈칸 4개)은 “이 줄은 위 줄에 딸린 줄”이라는 표시다. 들여쓰기가 어긋나면 코드가 돌아가지 않는다.
값과 변수
값에는 종류가 있다. 이 종류를 자료형(type)이라 부른다. 코딩테스트에서는 아래 다섯 가지면 거의 된다.
| 종류 | 예 | 알아 둘 점 |
|---|---|---|
int 정수 |
3, -7, 10**20 |
아무리 커도 된다. 넘쳐서 깨지는 일이 없다 |
float 실수 |
2.5, 1e9 |
소수 계산에 아주 작은 오차가 생길 수 있다 |
str 문자열 |
"abc", '가' |
글자를 줄 세운 것. 리스트와 문자열에서 자세히 다룬다 |
bool 참·거짓 |
True, False |
비교한 결과 |
None |
None |
“값이 없다” |
변수는 값에 붙이는 이름표다. x = 5는 “5에 x라는 이름표를 붙인다”는 뜻이다. 수학의 “같다”가 아니다. 그래서 x = x + 1은 “지금 x에 1을 더한 값에 x라는 이름표를 다시 붙인다”가 된다. 줄여서 x += 1로 쓴다.
종류를 바꿀 때는 종류 이름을 함수처럼 쓴다. int("123")은 숫자 123, str(45)는 글자 "45"가 된다.
계산 기호
| 기호 | 뜻 | 예 | 결과 |
|---|---|---|---|
+ - * |
더하기, 빼기, 곱하기 | 7 * 2 |
14 |
/ |
나누기. 답은 늘 실수 | 7 / 2 |
3.5 |
// |
몫 | 7 // 2 |
3 |
% |
나머지 | 7 % 2 |
1 |
** |
거듭제곱 | 2 ** 10 |
1024 |
== != |
같다, 다르다 | 3 == 3 |
True |
< <= > >= |
크다, 작다 | 1 <= 2 < 3 |
True |
and or not |
그리고, 또는, 아니다 | True and False |
False |
몫과 나머지는 늘 짝이 맞는다. 몫에 나눈 수를 곱하고 나머지를 더하면 원래 수가 나온다. 식으로 쓰면 \(a = (a \,/\!/\, b) \cdot b + (a \,\%\, b)\)다1.
파이썬의 몫은 소수점을 그냥 떼는 게 아니라 더 작은 쪽으로 내린다. 그래서 -7 // 2는 -3이 아니라 -4다. 짝을 맞추려고 -7 % 2는 1이 된다. 양수로 나누면 나머지는 늘 0 이상이다. 그래서 음수도 num % 2 == 0으로 짝수인지 알 수 있다.
1 <= x < 5처럼 비교를 이어 쓸 수 있다. 1 <= x and x < 5와 같은 뜻이다.
조건문
if score >= 90:
grade = "A"
elif score >= 80: # 위 조건이 틀렸을 때만 본다
grade = "B"
else: # 위가 다 틀렸으면
grade = "C"
위에서부터 처음 맞는 한 곳만 실행한다. score = 95이면 "A"에서 멈추고 아래는 보지 않는다.
flowchart TD
S["score를 받는다"] --> Q1{"score >= 90?"}
Q1 -->|"예"| A["grade = A"]
Q1 -->|"아니오"| Q2{"score >= 80?"}
Q2 -->|"예"| B["grade = B"]
Q2 -->|"아니오"| C["grade = C"]
A --> E["if 문 다음 줄로"]
B --> E
C --> E
“예”로 빠지는 순간 나머지 질문은 건너뛰고 끝으로 간다. 그래서 elif의 질문은 앞 질문이 “아니오”일 때만 받는다2.
반복문
for는 “모음 안의 것을 하나씩 꺼내서 한 번씩”이다. 숫자 모음은 range로 만든다.
| 코드 | 나오는 값 |
|---|---|
range(5) |
0, 1, 2, 3, 4 (5는 안 나온다) |
range(1, 5) |
1, 2, 3, 4 |
range(0, 10, 3) |
0, 3, 6, 9 |
range(4, 0, -1) |
4, 3, 2, 1 |
total = 0
for x in [3, 1, 4]: # 리스트에서 하나씩 꺼내 x에 담는다
total += x # total: 3 → 4 → 8
for i, x in enumerate("ab"): # 번호도 같이 받는다: (0,'a'), (1,'b')
print(i, x)
for a, b in zip([1, 2], [10, 20]): # 두 모음을 나란히 꺼낸다: (1,10), (2,20)
print(a + b)
while 조건:은 조건이 맞는 동안 계속 돈다. 몇 번 돌지 미리 모를 때 쓴다. break는 반복을 바로 멈추고, continue는 이번 바퀴만 건너뛴다.
n, steps = 27, 0
while n != 1: # n이 1이 될 때까지
n = n // 2 if n % 2 == 0 else 3 * n + 1 # 한 줄로 쓴 조건: A if 조건 else B
steps += 1
함수
def area(w, h=1): # h를 안 주면 1로 친다(기본값)
return w * h # return을 만나면 값을 돌려주고 바로 끝난다
area(3, 4) # 12
area(3) # 3
return을 만나면 함수는 그 자리에서 끝난다. 반복문 안에서 return하면 남은 바퀴는 돌지 않는다. return이 없으면 None을 돌려준다.
함수 안에서 만든 변수는 함수 밖에서 보이지 않는다. 답안에 쓸 작은 함수는 solution 위나 안에 만들면 된다.
range가 내는 값, 예시 코드의 결과(total 8, 27이 1이 될 때까지 111번)도 확인했다 — 01_python-basics_verify.py활용
- 모든 풀이 문서의 코드는 이 문법에서 시작한다. 처음 나오는 문법은 그 풀이 문서의 5단계에서 줄마다 설명한다.
- 자주 하는 실수:
print로 답을 내면 채점하는 쪽은None을 받는다. 답은return으로 돌려준다.range(1, n)에는 n이 안 들어 있다. 1부터 n까지는range(1, n + 1)이다.7 / 2는3.5다. 몫이 필요하면//를 쓴다. 답이 정수여야 하는데/를 쓰면2.0같은 실수가 나가서 틀린다.=는 이름표 붙이기,==는 같은지 비교다.
연결
- 다음 개념: 리스트와 문자열, 시간 복잡도로 방법 고르기
- 연습: 짝수와 홀수
- 양수로 나눌 때
//와%가 주는 값은 나눗셈과 합동에 나오는 나눗셈 정리의 몫과 나머지다. 이 정리는 나머지가 0 이상이고 나누는 수보다 작은 (몫, 나머지) 짝이 딱 한 쌍뿐임을 보인다. 음수를 나눌 때 C·Java와 답이 다른 까닭도 거기서 다룬다. for i in range(1, n + 1): total += i를 합의 기호로 쓰면 \(\sum_{i=1}^{n} i\)(\(\sum\)은 차례로 모두 더한다는 기호)이다.range(a, b)는 a ≤ b일 때 a부터 b − 1까지 b − a개를 낸다. 합의 기호와 항 개수 세는 법은 수열과 합의 기호에 있다.float가 빠짐없이 정확히 담는 정수는 \(2^{53}\)까지다. 그래서 큰 정수를/로 나누면 끝자리가 틀릴 수 있다. 정수 몫은//로 구한다. 까닭은 거듭제곱과 지수법칙의 부동소수점 항목에 있다.- 참·거짓 값끼리 쓰면
and,or,not은 수학의 그리고(∧), 또는(∨), 아니다(¬)와 같다. 여러 조건을 묶은if가 언제 참인지는 명제와 논리 연산의 진리표로 따진다.and의 앞 조건이 거짓이면 뒤를 보지 않는 단락 평가도 거기 있다.
확인 문제
C1 다음 코드가 끝나면 s는 얼마일까?
s = 0
for i in range(1, 10, 2):
if i % 3 == 0:
continue
s += i
답: 13. i는 1, 3, 5, 7, 9다. 3과 9는 continue로 건너뛰니 1 + 5 + 7 = 13이다.
흔한 오답: 25(1~9의 홀수를 다 더함). continue가 그 바퀴의 남은 줄을 건너뛴다는 걸 놓친 것이다.
C2 -7 // 2가 -3이 아니라 -4인 까닭을 나머지 %와 묶어서 설명하라.
답: 파이썬은 “몫 × 나눈 수 + 나머지 = 원래 수”가 늘 맞게 하고, 양수로 나누면 나머지가 0 이상이 되게 정한다. -7 = (-4) × 2 + 1이니 몫은 −4, 나머지는 1이다. 몫을 −3으로 하면 나머지가 −1이 되어 이 약속이 깨진다.
C3 “1부터 n까지 더하려면 for i in range(n): total += i“라는 코드가 틀리는 가장 작은 n은?
답: n = 1. range(1)은 0 하나만 내서 합이 0인데, 답은 1이다. range(n)은 0부터 n − 1까지 돈다. 맞게 쓰면 range(1, n + 1)이다.
-
Python 3 언어 레퍼런스 6.7 “Binary arithmetic operations”: 정수 나눗셈
//는 결과를 내림(floor)하고,x == (x//y)*y + (x%y)가 맞으며,%의 결과는 나누는 수와 부호가 같다. 문법 전반은 Python 3 공식 튜토리얼 3장 “An Informal Introduction to Python”, 4장 “More Control Flow Tools”. ↩ -
이 문서 ‘조건문’ 절의 score 예시 코드와 “위에서부터 처음 맞는 한 곳만 실행한다”는 설명을 순서도로 옮겼다(Python 3 공식 튜토리얼 4.1 if Statements). ↩