티스토리 뷰

반응형

파이썬이 최근에 정식으로 3.10 업데이트를 하면서, 새로운 제어문의 꼴이 생겼다. match문이 이번 포스팅의 주인공이다.

 

파이썬은 여러 조건 분기를 if...elif...else를 통해 처리하였지만, 3.10을 통해 구조적 패턴 매칭(Structural Pattern Matching)을 새로 도입하였다.

 

C / C++나 자바나 자바스크립트를 공부했던 사람들은 switch문, 혹은 Rust의 경우 패턴 매칭이 익숙할 것이다. 이와 유사하게, 파이썬에는 match-case문이 새로 등장하였다.

 

이번 포스팅에서 match-case문에 대하여 한번 알아보도록 하자.

thumbnail
match-case문에 대하여 알아보자.

1. match

match-case문은 match 입력에 대하여 일치하는 패턴가 있다면 해당 case문에 속한 코드를 실행한다.

 

만약 해당되는 case가 없으면 case '_'(언더바)가 실행되며, 다른 언어에서 default: 에 해당한다고 생각하면 된다.

 

만약 case '_'가 없고, 해당되는 case가 없다면, 어떠한 분기도 실행되지 않는다. (와일드카드 구문이라고도 한다.)

 

간단한 예시를 들자면 다음과 같다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# -*- coding: utf-8 -*-
def http_error(status):
    match status:
        case 400:
            print("Bad request")
        case 404:
            print("Not found")
        case 418:
            print("I'm a teapot")
        case _:
            print("Something's wrong with the internet")
http_error(400# Bad request
http_error(418# I'm a teapot
http_error(300# Something's wrong with the internet
cs

 

다른 언어와 구문이 꽤 비슷하다는 것을 확인할 수 있다.

 

한 가지 다른 언어들과 다른 점이 있다면, case간 fall-through가 없다는 점이다. 즉, 각 case에 대하여 case가 완료되었을 때 따로 return이나 break와 같이 case 코드가 끝났다는 구문을 넣지 않아도 된다. 

 

case에서 여러 개의 조건을 결합하고 싶다면 다음과 같이 '|'를 이용하여 작성할 수 있다. 특이하게 'or' 대신 '|'를 썼다는 점이 눈여겨볼만 하다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# -*- coding: utf-8 -*-
def http_error(status):
    match status:
        case 400:
            print("Bad request")
        case 401 | 402 | 403# 401 or 402 or 403
            print("Permission Denied")
        case 404:
            print("Not found")
        case 418:
            print("I'm a teapot")
        case _:
            print("Something's wrong with the internet")
http_error(400# Bad request
http_error(418# I'm a teapot
http_error(300# Something's wrong with the internet
http_error(401# Permission Denied
cs

2. match with literal

파이썬에서는 다른 언어와 다르게 match문을 활용할 때, unpacking과 비슷한 방식을 지원한다. 하나의 객체를 여러 개의 객체로 푸는 것이 가능하다는 것이다. 이때 unpacking된 데이터들은 case 내의 변수에 바인딩될 수 있다. 참 파이썬스럽다.

 

말로 써 놓으면 무슨 소리인지 모를 수 있지만, 구체적인 예시로 풀어보면 이해가 쉽게 될 것이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# -*- coding: utf-8 -*-
def print_point(point):
    match point:
        case (00):
            print("Origin")
        case (0, y):
            print(f"Y = {y}")
        case (x, 0):
            print(f"X = {x}")
        case (x, y):
            print(f"X = {x}, Y = {y}")
        case _:
            raise ValueError("Not a point")
 
print_point((00)) # Origin
print_point((40)) # X = 4
print_point([02]) # Y = 2
 
# unpacking이 가능하다면 어떤 꼴이든 상관이 없다.
print_point([2+ [4]) # X = 2, Y = 4
print_point([x for x in range(2)]) # Y = 1
print_point(("1""2")) # X = 1, Y = 2
print_point([1+2300+20]) # X = 3, Y = 320
print_point("some thing".split()) # X = some, Y = thing
 
# unpacking이 불가능하거나 어떤 case에도 걸리지 않으면 ValueError와 마주친다.
print_point([1])
print_point([103])
print_point(21# 두 개의 인자가 들어가면 안 된다!
 
cs

 

위의 case에서 case에 두 개의 상수가 들어가도 되고, 두 개의 변수가 들어가도 된다.

 

match를 할 때 마다 (x, y) = point와 같이 진행된다고 봐도 무방하다.


3. match with conditional case

만약, match를 하긴 하는데, 특정 조건 하에 실행되게 하고 싶다면 다음 syntax를 활용하면 된다.

case <match> if <match> in <iterable>

예시를 살펴보자. input에 대한 패턴 매칭을 할 때, if 의 조건이 참이라는 가정 하에 패턴 매칭이 이루어지면 실행되도록 하는 코드이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# -*- coding: utf-8 -*-
 
classA = ["Alice""Bob""Cameron"]
classB = ["Cheolsoo""Yeonghee""Minsu""Heesu"]
 
while True:
    name = input("Enter a name: ")
 
    match name:
        case n if n in classA:
            print(f"{n} is in classA")
        case n if n in classB:
            print(f"{n} is in classB")
        case _:
            print(f"{n} is unknown")
cs

 

input으로 "Alice", "Minsu", "Jeongmin"을 넣어보자.

 

1
2
3
4
5
6
7
8
Enter a name: Alice
Alice is in classA
 
Enter a name: Minsu
Minsu is in classB
 
Enter a name: Jeongmin
Jeongmin is unknown
cs

 

if의 참이라는 조건 하에 패턴 매칭이 실행되는 것을 확인할 수 있다.


도움이 되었다면 지나가는 길에 하트 하나 눌러주세요, 양질의 글을 쓰는데 하나의 동기부여가 됩니다😍

지적이나 오타 수정 댓글 환영합니다!!

 

 

반응형
댓글
Total
Today
Yesterday
공지사항
최근에 올라온 글
최근에 달린 댓글
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함