[ Web Proxy ]
URL:
Viewing: https://python-course.eu/python-tutorial/structural-pattern-matching.php [Back]  [Original]

17. Structural Pattern Matching | Python Tutorial | python-course.eu
python-course.eu
Search site:

Live Python classes by highly experienced instructors:

instructor-led training course [instructor-led training course]
Instructor-led training courses by Bernd Klein

  1. Intro to Python Tutorial
  2. History and Philosophy of Python
  3. The Interpreter, an Interactive Shell
  4. Execute a Script
  5. Structuring with Indentation
  6. Assignment Expressions
  7. Data Types and Variables
  8. Type Annotations
  9. Operators
  10. Sequential Data Types
  11. List Manipulation
  12. Shallow and Deep Copy
  13. Dictionaries
  14. Sets and Frozen Sets
  15. Sets Examples
  16. Keyboard Input
  17. Conditional Statements
  18. Structural Pattern Matching
  19. Adventure Game with Structural Pattern Matching
  20. While Loops
  21. For Loops
  22. Output with Print
  23. Formatted Output
  24. Working with Dictionaries and while Loops
  25. Functions
  26. Passing Arguments
  27. Parameters And Arguments
  28. Namespaces
  29. Global vs. Local Variables and Namespaces
  30. File Management
  31. Modular Programming and Modules
  32. Packages
  33. Errors and Exception Handling

This website contains a free and extensive online tutorial by Bernd Klein, using material from his classroom Python training courses.

If you are interested in an instructor-led classroom training course, have a look at these Python classes:

instructor-led training course [instructor-led training course]
Instructor-led training course by Bernd Klein at Bodenseo

Image kabliczech - Fotolia.com

This page was written by Bernd Klein.

Bernd is an experienced computer scientist with a history of working in the education management industry and is skilled in Python, Perl, Computer Science, and C++. He has a Dipl.-Informatiker / Master Degree focused in Computer Science from Saarland University.

PDF versions of this site [PDF versions of this site]

PDF logo [PDF logo] PDF version of this site

This website is free of annoying ads. We want to keep it like this. You can help with your donation:

[Go]

The need for donations

17. Structural Pattern Matching

By Bernd Klein. Last modified: 29 Mar 2023.

Introduction

Structural pattern matching is a programming technique that allows complex data structures to be applied in a concise and readable way in comparisons. Structural pattern matching is used in various programming languages, including Python.

With structural pattern matching, a data structure (such as a list or a tuple) is analyzed and searched for a specific pattern that one has previously defined. One can then perform different actions based on the patterns found. This can often be written in a concise and easy-to-understand way, which increases the readability of the code.

Patterns [Patterns]

In general, structural pattern recognition can reduce error-proneness and increase development productivity by shortening syntax and improving readability.

'Structural Pattern Matching' was newly introduced in Python 3.10. The syntax for this new feature was proposed in PEP 622 in June 2020. The pattern matching statement of Python was inspired by similar syntax found in Scala, Erlang, and other languages. In its simplest form it behaves like the switch statement of C, C++, or Java. Yet, there are more improved use cases for this feature, as you will learn in this tutorial. We will learn that it is possible in Python to unpack a pattern into its basic component.

Before you go on with this chapter, you have to make sure that Python version 3.10 or higher is running on your system. The easiest way to find out is to use version from sys:

import sys
sys.version

OUTPUT:

'3.10.10 (main, Mar 21 2023, 18:45:11) [GCC 11.2.0]'

In Python, structural pattern matching is introduced by the match statement.

The match statement works by comparing an evaluated expression (also known as an "expression under test") with one or more patterns. A pattern is a special expression that corresponds to a particular data type or contains a complex data structure such as a list or a tuple.

Let's look at a simple example of structural pattern matching. We write a function that responds to a chosen language, so 'chosen_language' is the expression to check:

Let us look at a simple structural pattern matching example. We write a function which reacts to a chosen language:

def greeting(language):
    chosen_language = language.capitalize()
    match chosen_language:
        case 'English':
            print('Hello')
        case 'German':
            print('Hallo!')
            
greeting('english')

OUTPUT:

Hello

In Python's structural pattern matching, the underscore character (_) is used as a placeholder to match any value. This means for the following code that the case with the '_' always applies if 'English' or 'German' is not entered:

def greeting(language):
    chosen_language = language.capitalize()
    match chosen_language:
        case 'English':
            print('Hello')
        case 'German':
            print('Hallo!')
        case _:
            print(f"Hello, I don't know {chosen_language}!")
            
greeting('english')
greeting('french')

OUTPUT:

Hello
Hello, I don't know French!

As you most probably know, German is not only spoken in Germany, but in Austria and parts of Switzerland as well. We should not forget that German is also spoken in Liechtenstein and Luxembourg, in addition to French. This example shows now a usecase in which the structural pattern matching makes things easier:

def greeting(language):
    chosen_language = language.split()
    match chosen_language:
        case ['English']:
            print('Hello')
        case ['German']:
            print('Hallo!')
        case ['German', 'AT']:
            print(f'Servus!')
        case ['German', 'CH']:
            print(f'Grezi!')
        case ['German', 'DE']:
            print(f'Hallo')
        case ['German', 'LU']:
            print(f'Gudden Dag')
        case ['German', 'LI']:
            print(f'Grezi')

for lang in ['English', 'German LU', 'German CH']:
    greeting(lang)

OUTPUT:

Hello
Gudden Dag
Grezi!

Without match the Python code would be similar to the following code:

def greeting(language):
    chosen_language = language.split()
    if len(chosen_language) == 1:
        if chosen_language == ['English']:
            print('Hello')
        elif chosen_language == ['German']:
            print('Hallo!')
    elif len(chosen_language) == 2:
        if chosen_language == ['German', 'AT']:
            print(f'Servus!')
        elif chosen_language == ['German', 'CH']:
            print(f'Grezi!')
        elif chosen_language == ['German', 'DE']:
            print(f'Hallo')
        elif chosen_language == ['German', 'LU']:
            print(f'Gudden Dag')
        elif chosen_language == ['German', 'LI']:
            print(f'Grezi')

for lang in ['English', 'German LU', 'German CH']:
    greeting(lang)

OUTPUT:

Hello
Gudden Dag
Grezi!

We could improve the previous code a tiny little bit, but it should be clear that the match is superior in its clarity in this case. We can further improve our example: What if somebody choses an unknown language or an unknown language plus a region ? It is very easy. Instead of using a string literal in our pattern, we use variable names:

def greeting(language):
    chosen_language = language.split()
    match chosen_language:
        case ['English']:
            print('Hello')
        case ['German']:
            print('Hallo!')
        case [unknown_language]:
            print(f"So far, we don't know how to greet in {unknown_language}!")
        case ['German', 'AT']:
            print(f'Servus!')
        case ['German', 'CH']:
            print(f'Grezi!')
        case ['German', 'DE']:
            print(f'Hallo')
        case ['German', 'LU']:
            print(f'Gudden Dag')
        case ['German', 'LI']:
            print(f'Grezi')
        case [lang, region]:
            print(f"Sorry, we don't know {lang} in your region {region}!")

for lang in ['English', 'German LU', 'French', 'German CH', 'English CA']:
    greeting(lang)

OUTPUT:

Hello
Gudden Dag
So far, we don't know how to greet in French!
Grezi!
Sorry, we don't know English in your region CA!

We present an interesting use case in the form of an imaginary adventure game. Gamers could write actions as strings in the various formats, like

commands = ['go north','go west', 'drop potion', 'drop all weapons', 'drop shield']
weapons = ['axe','sword','dagger']
shield = True
inventory = ['apple','wood','potion'] + weapons + ['shield']
for command in commands: 
    match command.split():
        case ["help"]:
            print("""You can use the following commands:
            """)
        case ["go", direction]: 
            print('going', direction)
        case ["drop", "all", "weapons"]: 
            for weapon in weapons:
                inventory.remove(weapon)
        case ["drop", item]:
            print('dropping', item)
            inventory.remove(item)
        case ["drop shield"]:
            shield = False 
        case _:
            print(f"Sorry, I couldn't understand {command!r}")

OUTPUT:

going north
going west
dropping potion
dropping shield
['apple', 'wood']

In the following example, we define the factorial function using match:

def factorial(n):
    match n:
        case 0 | 1:
            return 1
        case _:
            return n * factorial(n - 1)

for i in range(6):
    print(i, factorial(i))

OUTPUT:

0 1
1 1
2 2
3 6
4 24
5 120

Live Python training

instructor-led training course [instructor-led training course]

Enjoying this page? We offer live Python training courses covering the content of this site.

Upcoming online Courses

See our Python training courses

See our Machine Learning with Python training courses

top


Web Proxy Viewer  |  New URL  |  Original Page