[Python] 조건문
동빈나 채널의 파이썬 문법 부수기 유튜브 강의를 참고하여 정리한 내용이다.
파이썬은 다른 언어와 다르게 동작하는 부분들이 있어서, C/C++ 배경이 있으면 살짝 헷갈리는 게 몇 가지 있다.
truthy/falsy 처리 방식이나 부등식 연결 같은 것들인데, 알고 나면 오히려 파이썬이 더 자연스럽다.
if / elif / else 기본 구조
score = 85
if score >= 90:
print("A")
elif score >= 80:
print("B")
elif score >= 70:
print("C")
elif score >= 60:
print("D")
else:
print("F")
# 출력: B
elif는 else if의 줄임이다. 조건이 위에서부터 순서대로 평가되고, 처음으로 True가 되는 블록만 실행된다.
비교 연산자
| 연산자 | 의미 | 예시 |
|---|---|---|
== |
같음 | a == b |
!= |
다름 | a != b |
> |
초과 | a > b |
< |
미만 | a < b |
>= |
이상 | a >= b |
<= |
이하 | a <= b |
a = 10
b = 20
print(a == b) # False
print(a != b) # True
print(a < b) # True
print(a >= 10) # True
논리 연산자: and, or, not
x = 15
# and - 둘 다 True일 때
if x > 10 and x < 20:
print("10 초과 20 미만") # 출력됨
# or - 하나라도 True일 때
if x < 5 or x > 10:
print("5 미만이거나 10 초과") # 출력됨
# not - 반전
if not x > 20:
print("20 이하") # 출력됨
단축 평가 (Short-circuit Evaluation)
파이썬은 결과가 확정되는 순간 나머지 조건을 평가하지 않는다.
# and: 앞이 False면 뒤는 평가 안 함
a = 0
if a != 0 and (10 / a) > 1: # a가 0이므로 뒤 조건은 실행되지 않음
print("ok")
# ZeroDivisionError가 나지 않는다
# or: 앞이 True면 뒤는 평가 안 함
b = 5
result = b or print("실행 안 됨") # b가 truthy이므로 print 호출 안 됨
# 활용: None 체크 후 속성 접근
data = None
if data is not None and data["key"] > 0:
print("값 있음")
단축 평가는 버그를 막는 데 유용하다. None 체크를 앞에 두면 뒤에서 안전하게 접근할 수 있다.
in / not in 연산자
값이 컨테이너(리스트, 문자열, 사전, 집합 등)에 있는지 확인한다.
fruits = ["apple", "banana", "cherry"]
print("apple" in fruits) # True
print("grape" in fruits) # False
print("grape" not in fruits) # True
# 문자열에서
s = "hello world"
print("hello" in s) # True
print("world" in s) # True
print("python" in s) # False
# 사전에서 - 키를 기준으로 확인
d = {"a": 1, "b": 2}
print("a" in d) # True
print(1 in d) # False (값이 아니라 키 기준)
print(1 in d.values()) # True (값 기준으로 보려면 .values())
리스트에서
in은 O(N), 집합/사전에서in은 O(1)이다. 존재 여부를 반복적으로 확인해야 한다면 집합으로 변환하는 게 낫다.
pass 키워드
아무 동작도 하지 않는다. 문법상 블록이 필요한데 아직 내용이 없을 때 쓴다.
x = 10
if x > 5:
pass # 나중에 구현할 것
else:
print("5 이하")
# 함수나 클래스 정의 시에도
def todo_function():
pass
빈 블록을 두면 IndentationError나 SyntaxError가 나는데, pass로 채워두면 일단 실행은 된다.
조건문 간소화
한 줄 if
x = 10
# 한 줄로 쓰기
if x > 5: print("5 초과")
# elif, else도 가능하지만 가독성이 떨어짐
if x > 5: print("크다")
else: print("작다")
조건부 표현식 (삼항 연산자)
x = 10
# 기본 형태: 참일 때 값 if 조건 else 거짓일 때 값
result = "양수" if x > 0 else "음수 또는 0"
print(result) # 양수
# 변수 할당에 자주 씀
a = 5
b = 10
max_val = a if a > b else b
print(max_val) # 10
# 리스트 컴프리헨션과 조합
nums = [1, -2, 3, -4, 5]
abs_nums = [n if n >= 0 else -n for n in nums]
print(abs_nums) # [1, 2, 3, 4, 5]
중첩 삼항 연산자는 가독성이 나빠져서 왠만하면 쓰지 않는 게 낫다.
# 이렇게 쓰면 읽기 힘들다
grade = "A" if score >= 90 else "B" if score >= 80 else "C"
# 차라리 if/elif/else가 낫다
파이썬 부등식 연결
파이썬은 수학에서 쓰는 연속 부등식을 그대로 쓸 수 있다.
x = 15
# 파이썬
if 0 < x < 20:
print("0 초과 20 미만") # 출력됨
# C++에서는 이렇게 써야 함
# if (x > 0 && x < 20)
# 더 다양한 형태도 된다
if 0 <= x <= 100:
print("0 이상 100 이하")
if 1 < x < 5 or 10 < x < 20:
print("범위 내")
C/C++ 배경이라면 이 문법이 낯설 수 있는데, 파이썬에서는 정상적으로 동작하고 오히려 더 읽기 좋다.
truthy / falsy
파이썬에서 조건문은 True/False뿐 아니라 모든 값에 적용된다. “비어있거나 없는 값”은 False로 취급된다.
# False로 취급되는 값들
if 0: print("출력 안 됨")
if 0.0: print("출력 안 됨")
if "": print("출력 안 됨") # 빈 문자열
if []: print("출력 안 됨") # 빈 리스트
if {}: print("출력 안 됨") # 빈 사전
if (): print("출력 안 됨") # 빈 튜플
if set(): print("출력 안 됨") # 빈 집합
if None: print("출력 안 됨")
# True로 취급되는 값들
if 1: print("출력됨")
if -1: print("출력됨") # 0이 아닌 숫자
if "hello": print("출력됨") # 비어있지 않은 문자열
if [1, 2]: print("출력됨") # 비어있지 않은 리스트
이걸 활용하면 코드가 간결해진다.
# 리스트가 비어있는지 확인
data = []
# 이렇게 써도 되지만
if len(data) == 0:
print("비었다")
# 이렇게 더 간결하게 쓸 수 있다
if not data:
print("비었다")
# 사전에서 키로 값 꺼낼 때
result = d.get("key")
if result: # None이거나 0이면 False - 주의 필요
print(result)
if not data패턴은 편하지만, 0이나 빈 문자열도 유효한 값인 상황에서는if data is None처럼 명시적으로 쓰는 게 안전하다.
is vs ==
# == : 값이 같은지
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # True (값이 같음)
print(a is b) # False (다른 객체)
# is : 같은 객체인지 (메모리 주소 비교)
c = a
print(a is c) # True (같은 객체를 참조)
# None 비교는 is를 써야 한다
x = None
if x is None: # 올바름
print("None임")
if x == None: # 동작은 하지만 관례상 is를 씀
print("None임")
작은 정수(-5 ~ 256)는 파이썬이 캐싱하기 때문에 is가 True가 되는 경우가 있다. 값 비교는 항상 ==를 쓰고, None 비교에만 is를 쓴다.
# 정수 캐싱 - 믿으면 안 되는 동작
a = 256
b = 256
print(a is b) # True (캐싱 범위 내)
a = 257
b = 257
print(a is b) # False (캐싱 범위 밖, 구현에 따라 다름)
match-case (Python 3.10+)
C의 switch-case와 유사한 문법이다. 코딩테스트 환경이 3.10 이상이면 쓸 수 있다.
command = "quit"
match command:
case "quit":
print("종료")
case "hello":
print("안녕")
case "help":
print("도움말")
case _:
print("알 수 없는 명령")
# 출력: 종료
값 비교 외에 패턴 매칭도 가능하다.
point = (1, 0)
match point:
case (0, 0):
print("원점")
case (x, 0):
print(f"x축 위의 점: {x}")
case (0, y):
print(f"y축 위의 점: {y}")
case (x, y):
print(f"임의의 점: ({x}, {y})")
# 출력: x축 위의 점: 1
에러 상황
IndentationError
파이썬에서 들여쓰기는 문법의 일부다. 탭과 스페이스를 섞으면 안 된다.
x = 10
if x > 5:
print("크다") # IndentationError: expected an indented block
if x > 5:
print("크다")
print("여기도") # IndentationError: unexpected indent
# 탭과 스페이스 혼용
if x > 5:
print("탭") # 탭으로 들여쓰기
print("스페이스") # 스페이스로 들여쓰기
# TabError: inconsistent use of tabs and spaces in indentation
에디터 설정에서 탭을 스페이스로 자동 변환하도록 설정하는 게 안전하다.
SyntaxError
# 콜론 빠뜨리기
if x > 5
print("크다") # SyntaxError: expected ':'
# elif/else를 if 없이 쓰기
else: # SyntaxError: invalid syntax
print("else 단독으로 쓸 수 없다")