Matching in Python as a Switch in other languages

Python version 3.10.5 brings the use of switch statement in python using match keyword. Read the blog to learn more about match functionality

Matching in Python as a Switch in other languages

Switch in Python as a Match

Have you ever tried the switch statement in Python? If you have been programming in other languages such as C++, C#, Java, etc, you will have used the switch statement, but when you shifted to Python, you noticed there is no switch statement in Python.

But here's some good news. Python's new release, i.e., Python 3.10.5, provides switch statements to Python users. A switch statement has been added to Python in the form of match statements and case statements of patterns with corresponding actions. Pattern matching allows programs to extract information from complex data types, branch based on data structures, and perform specified actions based on various data types.

Before proceeding to Syntax & Examples, make sure you have upgraded to the latest version of Python, i.e., Python 3.10.5, by downloading it from Python's Official Website

python 3.10.5 download pic.PNG

Match General Syntax

The syntax is pretty much the same as other programming languages use. Instead of the "switch" keyword, we use the "match" keyword in Python.

The generic syntax of pattern matching is:

match subject:
    case 1:
        # code here
    case 2:
        # code here
    case 3:
        # code here
    case _:
        # _ is used for default. if in case the value is not matched with any case default will execute 
        # code here
  • First, a variable of various types will be passed to match the operator.
  • Then, the match statement will evaluate the value of the variable.
  • After that, the variable value will be compared with each case from top to bottom until matched with a suitable case.
  • Then the code inside the matched case will be executed.
  • If there is no case-matched, then a wildcard "_". If a wildcard is provided and provided cases do not match, then the wildcard will be used as a matched case. (Such as the default case in various programming languages).

Match Example

Let us check a simple example of pattern matching: A value, the subject, is matched to several literals, the patterns. The subject of the match statement in the example below is status. Each of the case statements is a pattern, with literals representing request status codes. After a match, the case's corresponding action is carried out:

num1, num2 = 5, 6
op = input("Enter Operator")
result = 0
match op:
     case "+":
          result = num1+num2
     case "-":
          result = num1-num2
     case "/":
          result = num1/num2
     case "*":
          result = num1*num2
     case _:
          print("Operator Not Found")

If op is selected "+", the sum operation will be performed. If op is selected "%", the case statement with will match as a wildcard, and “Operator Not Found” will be printed. Note the last block: the variable name, , acts as a wildcard and insures the op will always match. The use of _ is optional.

You can combine several literals into a single pattern using | ("or"):

case "+" | "sum" | "add":
    result = num1 + num2

Match Without the wildcard, how would it behave?

If we remove the last case block from the above example, it becomes:

num1, num2 = 5, 6
op = input("Enter Operator")
result = 0
match op:
     case "+":
          result = num1+num2
     case "-":
          result = num1-num2
     case "/":
          result = num1/num2
     case "*":
          result = num1*num2

A match may not exist without the use of _ a case statement. If there is no match, then the behavior is a no-op. For example, if op is set to "%", a no-op occurs.

Matching with literals and variables

Patterns can resemble unpacking assignments, and they can also be used to bind variables. A data point in this example can be unpacked to its x- and y-coordinates:

x, y = 1, 2

point = (1, 0)

match point:
     case (0, 0):
          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 _:
          print("not a point")

The first pattern has two literals, (0, 0), and is an extension of the literal pattern mentioned above. The next two patterns combine a literal and a variable, with the variable binding a subject value (point). The fourth pattern catches two variables, it is essentially identical to the unpacking assignment (x, y) = point.

Matching with Class or Class Object

If you use classes to structure your data, you can use the class name followed by an argument list similar to a constructor as a pattern. This pattern can grab class characteristics and store them in variables:

class Point:
    x: int
    y:int

x, y = 1, 1

point = (0, y)

match point:
    case Point(x=0, y=0):
        print("Origin is the point's location.")
    case Point(x=0, y=y):
        print(f"Y={y} and the point is on the y-axis.")
    case Point(x=x, y=0):
        print(f"X={x} and the point is on the x-axis.")
    case Point():
        print("The point is located somewhere else on the plane.")
    case _:
        print("Not a point")

Or you can simply match using class object also

class Point:
    def __init__(self, x, y):
        self.x, self.y = x, y

x, y = 1, 1

point = Point(0, y)

match point:
    case Point(x=0, y=0):
        print("Origin is the point's location.")
    case Point(x=0, y=y):
        print(f"Y={y} and the point is on the y-axis.")
    case Point(x=x, y=0):
        print(f"X={x} and the point is on the x-axis.")
    case Point():
        print("The point is located somewhere else on the plane.")
    case _:
        print("Not a point")

An if clause, known as a "guard," can be added to a pattern. If the guard is false, the match proceeds to the next case block. It's worth noting that value capture occurs before the guard is evaluated:

match point:
    case Point(x, y) if x == y:
        print(f"The point is on the diagonal Y=X at {x}.")
    case Point(x, y):
        print(f"Point is not on the diagonal.")

Matching with Complex pattern

You have seen in the above examples we have used wildcard alone. but we can also use it in a more complex manner:

match response:
    case ('success', code, 200):
        print("Response received.")
    case ('error', code, _):
        print(f"An error {code} occurred while responding.")

Stay tuned and follow for new updates