상위 목록: 하위 목록: 작성 날짜: 읽는 데 15 분 소요

조건문(if)

조건문(if)은 제어문 중 하나로, 알고리즘의 논리적 제어를 표현하는 수단입니다.

프로그램은 기본적으로 위에서 아래로 한 줄씩 순서대로 실행됩니다. 하지만 실제 프로그램은 입력값이나 상태에 따라 다른 동작을 해야 하는 경우가 대부분입니다. 예를 들어 점수가 90점 이상이면 A를, 그렇지 않으면 다른 등급을 출력하거나, 로그인에 실패하면 오류 메시지를 보여주어야 합니다.

조건문을 통해 어떤 목적이나 상태가 만족할 때 실행되게 하거나, 특정 상태가 하나라도 만족할 때 등 알고리즘의 실행 흐름을 제어할 수 있습니다.

조건문은 조건문에 작성된 조건 판단식을 통해 실행 여부를 결정하게 됩니다.

조건 판단식이 참(True) 값일 때 조건문 내부의 알고리즘을 실행하게 됩니다. 반대로 거짓(False) 값이면 해당 블록을 건너뛰고 다음 분기나 조건문 다음 줄로 이동합니다.

Python에서는 if, elif, else 또는 Tuple, Dictionary, 조건 표현식(삼항 연산자), match-case를 이용하여 조건문을 구성할 수 있습니다.

이번 강좌에서는 조건 판단식을 만드는 관계·논리 연산자와 우선 순위, 조건이 어떤 순서로 평가되는지, if-elif-else의 분기 흐름, 값을 고르는 짧은 표현 방법, 그리고 데이터의 구조까지 비교하는 match-case를 차례대로 다룹니다.



조건 판단식

조건 판단식은 주로 관계 연산자(Relational Operator)와 논리 연산자(Logical Operator) 등을 통해 식을 구성합니다.

관계 연산자는 등식이나 부등식을 사용해 표현하며, 종류는 다음과 같습니다.


관계 연산자(Relational Operator)

연산 의미
x > y x가 y보다 큼
x >= y x가 y보다 크거나 같음
x < y x가 y보다 작음
x <= y x가 y보다 작거나 같음
x == y x와 y가 같음
x != y x와 y가 같지 않음


print(3 > 2, type(3 > 2))
print(1 < 2 < 3)
print("apple" < "banana")
print(0.1 + 0.2 == 0.3)
결과
True <class ‘bool’>
True
True
False

관계 연산자의 결과는 항상 True 또는 False인 bool 자료형입니다. 즉, 조건 판단식은 참·거짓 값을 만들어내는 식이며, if 문은 그 값을 보고 실행 여부를 결정합니다.

1 < 2 < 3처럼 비교 연산자를 연결하여 수학식과 같은 형태로 작성할 수 있습니다.

문자열끼리도 비교할 수 있으며, 이 경우 사전 순서(문자의 유니코드 코드 값 순서)로 앞에서부터 한 글자씩 비교합니다. "apple"은 첫 글자 a가 b보다 앞서므로 더 작습니다.

마지막 줄은 초보자가 자주 겪는 함정입니다. 실수는 이진수로 저장되므로 0.1 + 0.2는 정확히 0.3이 아니며, == 비교가 False가 됩니다. 실수의 같음을 비교할 때는 abs(a - b) < 1e-9처럼 오차 범위를 두거나 math.isclose()를 사용합니다.

  • Tip : =는 할당, ==는 비교입니다. 조건문에 if a = 1:처럼 작성하면 SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='? 오류가 발생합니다.


논리 연산자는 앞선 6강의 비트 연산과 동일하거나 비슷한 의미를 갖습니다.

논리곱(and), 논리합(or), 논리부정(not) 등을 통해 표현할 수 있습니다.

주로, 복합적인 조건 판단식을 구성할 때 사용합니다. 예를 들어 “나이가 20 이상이고 회원인 경우”, “주말이거나 공휴일인 경우”처럼 여러 조건을 하나로 묶을 때 사용합니다.


논리 연산자(Logical Operator)

연산 의미
x and y x와 y의 연산 결과가 모두 참 값
x or y x와 y의 연산 결과 중 하나라도 참 값
not x x의 연산 결과를 반전


연산자 우선 순위(Operators Precedence)

연산 의미
** 거듭 제곱
~x, +x, -x 단항 연산
*, @, /, //, % 곱셈 및 나누기 연산
+, - 덧셈 및 뺄셈 연산
«, » Bitwise Shift
& Bitwise AND
^ Bitwise XOR
| Bitwise OR
<, <=, >, >=, ==, !=, in, not in, is, is not 비교·멤버십·식별 연산자
not 논리 연산자
and 논리 연산자
or 논리 연산자
x if 조건 else y 조건 표현식
lambda 람다 표현식
:= 할당 표현식


연산자에는 우선 순위가 존재하며, 연산자 우선 순위 표의 순서대로 우선시합니다.

Python에서는 <, ==, in, is 등 모든 비교 연산자가 같은 우선 순위를 가지며, 1 < 2 == 2처럼 연결하여 작성하면 1 < 2 and 2 == 2로 해석됩니다.

  • Tip : **는 왼쪽의 단항 연산자보다 우선하므로 -2 ** 2는 -(2 ** 2)인 -4가 됩니다.

연산자 우선 순위 표에서 확인할 수 있듯이 and는 or보다 먼저 연산됩니다.

True or True and False 연산은 and가 먼저 연산되므로 True or (True and False)가 됩니다.

즉, 최종 결과는 True가 됩니다.

산술 연산자가 비교 연산자보다, 비교 연산자가 논리 연산자보다 우선하므로 a + 1 > 10 and b < 5는 ((a + 1) > 10) and (b < 5)로 해석됩니다. 대부분의 조건식은 이 덕분에 소괄호 없이도 자연스럽게 읽힙니다.

연산자 우선 순위를 모두 외우고 사용하는 것은 불가능하며, 코드 구성에 있어서 효율적이지도 않습니다.

그러므로, 소괄호를 사용해 먼저 연산될 수식을 설정합니다.



if

if 문은 가장 기본적인 조건문입니다. if 조건: 아래에 들여쓴 코드는 조건이 참일 때만 실행되며, elif와 else를 이어 붙여 여러 갈래 중 하나만 실행하는 구조를 만들 수 있습니다.

a = 100
if a > 100:
    print("크다")
elif a == 100:
    print("같다")
else:
    print("작다")
결과
같다

콜론(:)과 들여쓰기(Indentation)를 이용하여 해당 조건문에 대한 내용을 구성할 수 있습니다.

들여쓰기는 공백 4칸을 사용하는 것이 표준(PEP 8)이며, 같은 블록 안에서는 들여쓰기 깊이가 반드시 같아야 합니다. 공백과 탭을 섞어 사용하면 TabError가 발생할 수 있습니다.

조건문은 첫 분기(if)에 부합하지 않으면 다음 분기(elif)로 넘어가며, 어떤 분기에도 포함되지 않는 경우 최종 분기(else)로 넘어갑니다.

만약, 최종 분기(else)를 작성하지 않으면, 어떠한 분기도 포함되지 않아, 분기를 무시하고 넘어갑니다.

예제의 실행 흐름을 한 단계씩 따라가면 다음과 같습니다.

  1. a > 100을 평가합니다. 100 > 100은 False이므로 print("크다")를 건너뜁니다.
  2. 다음 분기인 a == 100을 평가합니다. 100 == 100은 True이므로 print("같다")를 실행합니다.
  3. 참인 분기를 하나 실행했으므로 else는 평가하지 않고 조건문 전체를 빠져나갑니다.

즉, if-elif-else는 위에서부터 차례대로 조건을 검사하다가 처음으로 참이 되는 분기 하나만 실행합니다. 이후의 elif 조건은 참이든 거짓이든 아예 계산되지 않습니다.

  • Tip : elif는 else if의 줄임말이며, 필요한 만큼 여러 번 작성할 수 있습니다. else는 마지막에 한 번만 작성할 수 있고 조건을 적지 않습니다.


score = 95

if score >= 60:
    print("D 이상")
elif score >= 90:
    print("A")
else:
    print("F")
결과
D 이상

분기는 위에서부터 검사하기 때문에 조건의 순서가 결과를 바꿉니다.

score가 95이므로 A가 출력될 것 같지만, 첫 번째 조건 score >= 60이 먼저 참이 되어 D 이상이 출력되고 조건문이 종료됩니다. score >= 90은 검사조차 되지 않습니다.

범위를 나누는 조건문에서는 더 좁은(엄격한) 조건을 먼저 작성해야 합니다. 위 예제는 score >= 90을 첫 번째 분기로 옮겨야 의도대로 동작합니다.


score = 95

if score >= 90:
    print("A")
if score >= 60:
    print("D 이상")
결과
A
D 이상

elif 대신 if를 여러 번 작성하면 서로 독립된 조건문 여러 개가 됩니다.

첫 번째 if가 참이어서 A를 출력한 뒤에도, 두 번째 if는 별개의 조건문이므로 다시 검사되어 D 이상도 출력됩니다.

하나만 골라야 하는 경우에는 if-elif를, 각 조건을 모두 따로 검사해야 하는 경우에는 if를 여러 번 사용합니다.


a = 100
if a > 10:
    if a % 2 == 0:
        print("10보다 큰 짝수")
    else:
        print("10보다 큰 홀수")
결과
10보다 큰 짝수

조건문 안에 다시 조건문을 작성하는 것을 중첩 조건문이라 합니다.

바깥 if의 조건 a > 10이 참일 때만 안쪽 조건문에 진입하며, 안쪽의 else는 들여쓰기 깊이가 같은 안쪽 if와 짝을 이룹니다. 들여쓰기가 곧 블록의 범위이므로 들여쓰기를 잘못하면 else가 다른 if와 짝지어질 수 있습니다.

  • Tip : 중첩이 깊어지면 읽기 어려워집니다. if a > 10 and a % 2 == 0:처럼 and로 합칠 수 있는 조건은 합쳐서 중첩을 줄입니다.


a = 100
b = 40

if (100 <= a < 130) and not (50 < a < 100):
    print("if-1 : 모두 조건에 만족")

if a < 50 or (b - 40) == 0:
    print("if-2 : 하나라도 만족")

if b > 0 or b > 0 and a < 50:
    print("if-3 : 조건 우선식")
결과
if-1 : 모두 조건에 만족
if-2 : 하나라도 만족
if-3 : 조건 우선식

조건문을 사용할 때 주의점은 조건식 내부에도 우선 순위가 있다는 점입니다.

if-1은 100 <= a < 130이 True, 50 < a < 100이 False이므로 not에 의해 True가 되어 True and True로 참이 됩니다.

if-2는 a < 50이 False이지만 (b - 40) == 0이 True이므로 False or True로 참이 됩니다.

if-1과 if-2 조건에는 명시적으로 소괄호(())를 사용해 연산이 우선되어야 할 정보를 입력했습니다.

하지만, if-3을 확인해본다면, True or True and False가 되어, 코드만 보고는 어떤 연산이 우선되는지 한눈에 알기 어렵습니다.

(True or True) and False로 소괄호가 앞에 연결되었다면, True and False가 되어 최종적으로 False가 됩니다.

True or (True and False)로 소괄호가 뒤에 연결되었다면, True or False가 되어 최종적으로 True가 됩니다.

Python은 and를 or보다 먼저 연산하므로 실제로는 True or (True and False)로 해석되어, if-3이 출력되었습니다.

즉, 조건식 내부에도 우선 순위가 있으므로, 의도를 명확히 하기 위해 소괄호를 사용하는 것이 좋습니다.

  • Tip : and와 or는 결과가 정해지면 나머지 식을 계산하지 않습니다. 이를 단락 평가(Short-circuit Evaluation)라 하며, or는 앞의 값이 참이면, and는 앞의 값이 거짓이면 뒤의 식을 실행하지 않습니다.


def check(name, value):
    print(name, "평가")
    return value

if check("A", False) and check("B", True):
    print("and 참")

if check("C", True) or check("D", True):
    print("or 참")
결과
A 평가
C 평가
or 참

check() 함수는 호출될 때마다 이름을 출력하므로, 조건식의 어느 부분이 실제로 평가되었는지 확인할 수 있습니다.

첫 번째 조건문은 check("A", False)가 거짓이므로, 뒤가 무엇이든 and의 결과는 거짓입니다. 따라서 B는 평가되지 않고 and 참도 출력되지 않습니다.

두 번째 조건문은 check("C", True)가 참이므로, or의 결과는 이미 참으로 정해집니다. 따라서 D는 평가되지 않고 바로 or 참이 출력됩니다.

조건식은 항상 왼쪽에서 오른쪽으로 평가되며, 결과가 확정되는 순간 멈춥니다. 이 성질을 이용하면 if L and L[0] > 0:처럼 앞의 조건이 뒤의 조건을 보호하도록 작성할 수 있습니다. L이 빈 목록이면 L[0]을 계산하지 않으므로 IndexError가 발생하지 않습니다.

  • Tip : 함수 호출처럼 시간이 오래 걸리는 조건은 뒤에, 빠르게 걸러낼 수 있는 조건은 앞에 두면 불필요한 계산을 줄일 수 있습니다.


for value in [0, "", [], None, 3, "a", [0]]:
    if value:
        print(repr(value), "참")
    else:
        print(repr(value), "거짓")
결과
0 거짓
‘’ 거짓
[] 거짓
None 거짓
3 참
‘a’ 참
[0] 참

조건 판단식에는 True, False뿐만 아니라 모든 값을 사용할 수 있습니다.

if 값:을 만나면 Python은 내부적으로 bool(값)을 계산해 참·거짓을 판단합니다. 이렇게 참으로 취급되는 값을 Truthy, 거짓으로 취급되는 값을 Falsy라고 부르기도 합니다.

0, 0.0, 빈 문자열(""), 빈 목록([]), 빈 튜플(()), 빈 사전({}), None 등은 거짓으로 판단하며, 그 외의 값은 참으로 판단합니다.

[0]은 원소가 0이지만 비어있지 않은 목록이므로 참이 됩니다.

이 성질 덕분에 목록이 비어 있는지 검사할 때 if len(L) > 0: 대신 if L:처럼 간결하게 작성할 수 있습니다.

  • Tip : 반복문(for)은 15강에서 자세히 다룹니다.

  • Tip : 값이 None인지 검사할 때는 if value == None:이 아닌 if value is None:을 사용합니다. is는 같은 객체인지를 비교하며, None은 프로그램 안에 하나만 존재하는 객체이기 때문입니다. 또한 if not value:는 0이나 빈 문자열도 거짓으로 처리하므로, None만 골라내야 할 때는 is None을 사용합니다.



Tuple

if 문은 문장(statement)이므로 값으로 사용할 수 없습니다. 조건에 따라 두 값 중 하나를 골라 변수에 할당하는 짧은 코드가 필요할 때, 튜플의 인덱싱을 이용하는 방법이 있습니다.

a = 5
if a > 5:
    a = a*2
    print(a)
else:
    a = a-4
    print(a)


a = 5
b = (a-4, a*2) [a>5]  
print(b)
결과
1
1

튜플을 이용하여 if문처럼 사용할 수 있습니다.

튜플을 생성하여 (거짓, 참) [조건]으로 사용할 수 있습니다.

True는 정수 1, False는 정수 0으로 취급되므로, 조건의 결과가 튜플의 index로 사용되는 원리입니다.

예제에서는 먼저 튜플 (a-4, a*2)가 (1, 10)으로 두 값 모두 계산되고, 다음으로 a > 5가 False, 즉 0이 되어 (1, 10)[0]인 1이 선택됩니다.

참 값이 두 번째 자리에 오기 때문에 일반적인 읽기 순서와 반대여서 헷갈리기 쉽습니다.

  • Tip : 이 방식은 조건과 관계없이 튜플 안의 모든 값을 미리 계산하므로, 한쪽 값에서 오류가 발생할 수 있는 경우에는 사용하지 않습니다. 일반적으로는 아래의 조건 표현식을 사용합니다.


x = 0
b = (10 / x, 0)[x == 0]
결과
ZeroDivisionError: division by zero

x가 0이면 0을 고르려는 의도였지만, 인덱싱하기 전에 튜플을 만들면서 10 / x를 먼저 계산하므로 ZeroDivisionError가 발생합니다.

같은 코드를 b = 0 if x == 0 else 10 / x처럼 조건 표현식으로 작성하면, 선택된 쪽만 계산하므로 오류 없이 0이 할당됩니다.



Dictionary

if-elif로 하나의 값이 여러 후보 중 무엇과 같은지 비교하는 코드는 분기가 늘어날수록 길어집니다. 이렇게 “값 → 결과”의 대응 관계가 명확한 경우에는 사전으로 대응표를 만들어 조건문을 대신할 수 있습니다.

a = 5
if a == 1:
    print("일")
elif a == 2:
    print("이")
elif a == 3:
    print("삼")
else:
    print("알 수 없음")

data = {1 : "일", 2 : "이", 3 : "삼"}
b = data.get(a, "알 수 없음")

print(b)
결과
알 수 없음
알 수 없음

사전을 이용하여 if문처럼 사용할 수 있습니다.

사전을 생성하여 key와 value 값을 할당합니다.

사전.get(key, 예외)을 이용하여 key를 호출하여 value를 불러옵니다. 값이 없는 경우 예외 구문을 출력합니다.

if-elif는 조건을 위에서부터 하나씩 비교하지만, 사전은 key의 해시(hash)를 이용해 값을 바로 찾습니다. 그러므로 분기가 수십 개로 늘어나도 코드 길이가 늘지 않고, 대응표를 데이터처럼 따로 관리하거나 수정하기 쉽습니다.

예제의 a는 5이며 사전에 5라는 key가 없으므로, get()의 두 번째 인수인 "알 수 없음"이 반환됩니다. 이는 if 문의 else 역할을 합니다.

  • Tip : data[a]처럼 대괄호로 조회하면 key가 없을 때 KeyError: 5가 발생합니다. 조건문 대용으로 사용할 때는 기본값을 지정할 수 있는 get()을 사용합니다.


def add(a, b): return a + b
def sub(a, b): return a - b

ops = {"+": add, "-": sub}
op = "-"

print(ops[op](7, 3))
print(ops.get("*", add)(7, 3))
결과
4
10

사전의 value에는 문자열뿐만 아니라 함수도 저장할 수 있습니다.

ops[op]는 "-"에 대응하는 sub 함수를 꺼내고, 뒤의 (7, 3)으로 그 함수를 호출하므로 4가 출력됩니다. "*"는 사전에 없으므로 기본값으로 지정한 add가 호출되어 10이 출력됩니다.

이처럼 입력값에 따라 다른 동작을 실행해야 할 때, 사전과 함수를 함께 사용하면 긴 if-elif를 대신할 수 있습니다.

  • Tip : 사전은 ==로 같은 값을 찾는 경우에만 대신할 수 있습니다. score >= 90처럼 범위를 비교하는 조건은 if-elif를 사용합니다.



조건 표현식(삼항 연산자)

조건에 따라 두 값 중 하나를 고르는 작업은 매우 자주 등장합니다. 앞의 튜플 방식은 두 값을 모두 계산하는 문제가 있으므로, Python은 이를 위한 전용 문법인 조건 표현식을 제공합니다.

a = 5
if a > 5:
    a = a * 2
    print(a)
else:
    a = a - 4
    print(a)


a = 5
b = a * 2 if a > 5 else a - 4

print(b)
결과
1
1

조건 표현식(Conditional Expression)을 사용하여 코드를 간략화 할 수 있습니다. 피연산자가 세 개이므로 흔히 삼항 연산자라고도 부릅니다.

참 값 if 조건 else 거짓 값으로 구성할 수 있습니다.

조건에 부합할 경우 참 값을 실행하게 되며 부합하지 않을 경우 거짓 값을 실행합니다.

작성 순서와 실행 순서가 다르다는 점에 주의합니다. 가운데의 조건이 가장 먼저 평가되고, 그 결과에 따라 왼쪽이나 오른쪽 중 한쪽만 계산됩니다. 예제에서는 a > 5가 False이므로 a * 2는 계산되지 않고 a - 4인 1이 b에 할당됩니다.

조건 표현식은 값을 만들어내는 식이므로, 변수에 할당하거나 함수의 인수로 바로 사용할 수 있습니다. 단, else를 생략할 수 없습니다.


x = 1 + 2 if False else 0
print(x)

y = 1 + (2 if False else 0)
print(y)
결과
0
1

조건 표현식은 우선 순위가 매우 낮아서, 주변의 연산을 모두 포함한 채로 하나의 값처럼 동작합니다.

1 + 2 if False else 0은 (1 + 2) if False else 0으로 해석되어 0이 됩니다. 2와 0 중 하나를 골라 1에 더하려는 의도였다면 1 + (2 if False else 0)처럼 소괄호로 범위를 지정해야 합니다.


score = 85

grade = "A" if score >= 90 else "B" if score >= 80 else "C"

print(grade)
결과
B

조건 표현식은 else 뒤에 다시 조건 표현식을 연결해 여러 분기를 표현할 수 있습니다.

이 식은 "A" if score >= 90 else ("B" if score >= 80 else "C")로 해석됩니다. score >= 90이 거짓이므로 else 뒤의 식으로 넘어가고, score >= 80이 참이므로 "B"가 선택됩니다. if-elif-else와 같은 순서로 평가됩니다.

  • Tip : 조건 표현식을 여러 번 중첩하면 가독성이 떨어지므로, 분기가 많아지면 if-elif-else 문을 사용하는 것이 좋습니다.



match-case

if-elif는 임의의 조건을 검사할 수 있지만, 하나의 값을 여러 형태와 비교하는 코드에서는 같은 변수 이름을 반복해서 작성해야 합니다. match-case는 비교할 대상을 한 번만 적고, 그 값의 모양(패턴)에 따라 분기하는 문법입니다.

a = 3

match a:
    case 1:
        print("일")
    case 2 | 3:
        print("이 또는 삼")
    case _:
        print("알 수 없음")
결과
이 또는 삼

Python 3.10 이상에서는 match-case 문을 이용한 구조적 패턴 매칭(Structural Pattern Matching)을 사용할 수 있습니다. (PEP 634)

match 대상: 아래에 case 패턴:을 나열하면, 위에서부터 차례대로 비교하여 처음으로 일치하는 case 하나만 실행합니다.

예제에서는 a가 3이므로 case 1:은 일치하지 않고, case 2 | 3:에서 3과 일치하여 이 또는 삼이 출력됩니다. 일치하는 case를 찾았으므로 case _:는 검사하지 않습니다.

|를 사용하면 여러 패턴 중 하나라도 일치하는 경우를 표현할 수 있습니다.

case _:는 어떤 값과도 일치하므로, if 문의 else처럼 나머지 경우를 처리합니다.

  • Tip : 다른 언어의 switch 문과 달리 일치한 case를 실행한 뒤 다음 case로 넘어가지 않으므로 break가 필요하지 않습니다.

  • Tip : 일치하는 case가 없으면 아무것도 실행하지 않고 넘어갑니다.


point = (3, 0)

match point:
    case (0, 0):
        print("원점")
    case (x, 0):
        print("x축 위의 점 :", x)
    case (0, y):
        print("y축 위의 점 :", y)
    case (x, y) if x == y:
        print("대각선 위의 점 :", x)
    case (x, y):
        print("좌표 :", x, y)
    case _:
        print("좌표가 아님")
결과
x축 위의 점 : 3

match-case는 단순한 값 비교뿐만 아니라 데이터의 구조를 비교할 수 있습니다.

(x, 0)처럼 패턴에 변수 이름을 작성하면, 구조가 일치할 때 해당 위치의 값이 변수에 할당됩니다. 예제에서는 x에 3이 할당됩니다.

예제의 비교 과정은 다음과 같습니다.

  1. case (0, 0): : point는 요소가 두 개인 튜플이므로 모양은 같지만, 첫 번째 값 3이 0과 다르므로 실패합니다.
  2. case (x, 0): : 첫 번째 자리의 x는 어떤 값이든 받아들이고, 두 번째 값 0도 일치하므로 성공합니다. 이때 x에 3이 할당됩니다.
  3. 일치하는 case를 찾았으므로 아래의 case들은 검사하지 않습니다.

case 패턴 if 조건:처럼 패턴 뒤에 if를 붙인 것을 가드(Guard)라 하며, 패턴이 일치하고 조건도 참일 때만 실행합니다.

point의 값을 (0, 0), (0, -2), (4, 4), (1, 2) 등으로 바꿔 실행하면 각각 다른 case가 실행됩니다.

  • Tip : 문자열은 시퀀스이지만 시퀀스 패턴과는 일치하지 않습니다. 따라서 point = "abc"는 case _:로 넘어갑니다.


command = "pick apple sword"

match command.split():
    case ["go", direction]:
        print("이동 :", direction)
    case ["pick", *items]:
        print("줍기 :", items)
    case ["quit" | "exit"]:
        print("종료")
    case _:
        print("알 수 없는 명령")

data = {"type": "user", "name": "윤대희", "age": 30}

match data:
    case {"type": "admin"}:
        print("관리자")
    case {"type": "user", "name": str(name)}:
        print("사용자 :", name)
    case _:
        print("기타")
결과
줍기 : [‘apple’, ‘sword’]
사용자 : 윤대희

목록 패턴에서 *변수를 사용하면 나머지 요소들을 목록으로 모아서 할당합니다.

command.split()의 결과는 ['pick', 'apple', 'sword']입니다. ["go", direction]은 요소 개수가 두 개여야 하므로 실패하고, ["pick", *items]는 첫 요소가 "pick"이고 나머지 개수는 상관없으므로 성공하여 items에 ['apple', 'sword']가 할당됩니다.

사전 패턴 {"key": 패턴}은 지정한 key가 존재하고 값이 패턴과 일치하면 매칭되며, 패턴에 적지 않은 나머지 key(예제의 "age")는 무시합니다.

str(name)처럼 자료형(변수) 형태로 작성하면, 값이 해당 자료형일 때만 일치하며 그 값을 변수에 할당합니다.

이처럼 match-case는 명령어 해석, JSON 같은 중첩 데이터 처리처럼 데이터의 모양에 따라 분기해야 할 때 if-elif보다 훨씬 간결합니다. 반대로 score >= 90 같은 단순한 범위 비교에는 if-elif가 더 적합합니다.

  • Tip : 패턴 안의 단순한 이름(x, name 등)은 비교 대상이 아니라 값을 할당받는 변수입니다. 변수에 저장된 값과 비교하려면 조건 가드(if)를 사용하거나 모듈.상수처럼 점(.)이 포함된 이름을 사용해야 합니다.


RED = "red"
color = "blue"

match color:
    case RED:
        print("빨강")

print(RED)
결과
빨강
blue

위 Tip의 함정을 보여주는 예제입니다. case RED:는 “RED 변수의 값과 비교”가 아니라 “어떤 값이든 받아서 RED라는 이름에 할당”하는 패턴입니다.

따라서 color가 "blue"인데도 빨강이 출력되고, 그 과정에서 RED 변수의 값이 "blue"로 덮어쓰여 버립니다.

이런 패턴 뒤에 다른 case를 더 작성하면 그 case는 절대 실행될 수 없으므로 SyntaxError: name capture 'RED' makes remaining patterns unreachable 오류가 발생합니다.

상수와 비교하려면 클래스나 모듈 안에 상수를 두고 case Color.RED:처럼 점이 포함된 이름으로 작성합니다.



정리

이름 설명 반환값/특징
if-elif-else 위에서부터 조건을 검사하여 처음 참인 분기 하나만 실행 문장(값이 아님), 범위 비교 등 모든 조건에 사용
and, or, not 조건을 조합 왼쪽부터 평가하며 결과가 정해지면 멈춤(단락 평가)
참·거짓 판단 0, 빈 컨테이너, None 등은 거짓 if L:처럼 간결하게 검사 가능
(거짓, 참)[조건] 튜플 인덱싱으로 값 선택 두 값을 모두 미리 계산하므로 주의
사전.get(key, 기본값) 값 대응표로 분기 대체 같은 값 비교에만 사용, 함수도 저장 가능
참 값 if 조건 else 거짓 값 조건 표현식(삼항 연산자) 값을 반환, 선택된 쪽만 계산
match-case 값의 구조(패턴)에 따라 분기 Python 3.10 이상, 첫 일치 case 하나만 실행

조건문을 작성할 때는 조건이 위에서 아래로, 왼쪽에서 오른쪽으로 평가된다는 점을 기억해야 합니다. 분기의 순서와 조건식 안의 순서가 모두 결과에 영향을 주며, 헷갈리는 부분은 소괄호로 의도를 드러내는 것이 가장 안전합니다.

댓글 남기기