MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Tupluri în pattern matching

În construcția pattern matching din Python, tuplurile pot fi folosite ca șabloane. De exemplu:

def print_data(user):
   match user:
       case ("Tom", 37):
           print("default user")
       case ("Tom", age):
           print(f"Age: {age}")
       case (name, 22):
           print(f"Name: {name}")
       case (name, age):
           print(f"Name: {name}  Age: {age}")

print_data(("Tom", 37))     # default user
print_data(("Tom", 28))     # Age: 28
print_data(("Sam", 22))     # Name: Sam
print_data(("Bob", 41))     # Name: Bob  Age: 41
print_data(("Tom", 33, "Google"))    # nu corespunde nici unui șablon

În acest caz, funcția primește parametrul user, care, se presupune, este un tuplu cu două elemente. Construcția match compară acest tuplu cu o serie de șabloane. Primul șablon presupune că tuplul user corespunde exact setului de valori:

case ("Tom", 37):
   print("default user")

Adică, dacă primul element al tuplului este "Tom", iar al doilea - 37, se va afișa pe consolă mesajul "default user".

Al doilea șablon corespunde oricărui tuplu de două elemente, unde primul element este egal cu șirul "Tom":

case ("Tom", age):
   print(f"Age: {age}")

Pentru al doilea element se definește variabila age. În consecință, dacă primul element al tuplului este egal cu "Tom", iar al doilea nu este egal cu 37, un astfel de tuplu va corespunde celui de-al doilea șablon. Al doilea element va fi atribuit variabilei age.

Al treilea șablon este similar, dar de această dată al doilea element al tuplului este strict definit - trebuie să fie 22, iar primul element este atribuit variabilei name:

case (name, 22):
   print(f"Name: {name}")

Dacă tuplul de două elemente nu corespunde primului, al doilea și al treilea șablon, acesta va corespunde celui de-al patrulea șablon, pentru care valorile exacte nu sunt importante - pentru ele sunt definite variabilele name și age:

case (name, age):
   print(f"Name: {name}  Age: {age}")

Valori alternative

Dacă este necesar ca un element al tuplului să corespundă unui set de valori, aceste valori pot fi enumerate folosind o bară verticală:

def print_data(user):
   match user:
       case ("Tom" | "Tomas" | "Tommy", 37):
           print("default user")
       case ("Tom", age):
           print(f"Age: {age}")
       case (name, 22):
           print(f"Name: {name}")
       case (name, age):
           print(f"Name: {name}  Age: {age}")

print_data(("Tom", 37))     # default user
print_data(("Tomas", 37))   # default user
print_data(("Tom", 28))     # Age: 28
print_data(("Sam", 37))     # Name: Sam  Age: 37

În acest caz, primul șablon corespunde unui tuplu de două elemente, unde primul element este fie "Tom", fie "Tomas", fie "Tommy".

De asemenea, pot fi definite valori alternative pentru elemente individuale, dar și tupluri alternative:

def print_data(user):
   match user:
       case ("Tom", 37) | ("Sam", 22):
           print("default user")
       case (name, age):
           print(f"Name: {name}  Age: {age}")

print_data(("Tom", 37))     # default user
print_data(("Sam", 22))     # default user
print_data(("Mike", 28))    # Name: Mike  Age: 28

În acest caz, primul șablon va corespunde la două tupluri: ("Tom", 37) și ("Sam", 22).

Omiterea elementelor

Dacă nu este important un element al tuplului, atunci în șablon, în loc de o valoare concretă sau o variabilă, se poate folosi simbolul _:

def print_data(user):
   match user:
       case ("Tom", 37):
           print("default user")
       case (name, _):     # al doilea element nu contează
           print(f"Name: {name}")

print_data(("Tom", 37))     # default user
print_data(("Sam", 25))     # Name: Sam
print_data(("Bob", 41))     # Name: Bob

Se pot folosi simboluri _ pentru toate elementele tuplului; în acest caz, valorile tuturor acestor elemente nu vor conta:

def print_data(user):
   match user:
       case ("Tom", 37):
           print("default user")
       case ("Sam", _):
           print("Name: Sam")
       case (_, _):
           print("Undefined user")

print_data(("Tom", 37))     # default user
print_data(("Sam", 25))     # Name: Sam
print_data(("Bob", 41))     # Undefined user

În ultimul caz, șablonul (_, _) corespunde în continuare doar unui tuplu cu două elemente.

În exemplul de mai sus, șabloanele folosite corespundeau doar unui tuplu cu două elemente. Cu toate acestea, pot fi folosite și șabloane de tupluri cu un număr diferit de elemente:

def print_data(user):
   match user:
       case (name, age):
           print(f"Name: {name}  Age: {age}")
       case (name, age, company):
           print(f"Name: {name}  Age: {age}  Company: {company}")
       case (name, age, company, lang):
           print(f"Name: {name}  Age: {age}  Company: {company} Language: {lang}")

print_data(("Tom", 37))                     # Name: Tom  Age: 37
print_data(("Sam", 22, "Microsoft"))        # Name: Sam  Age: 22  Company: Microsoft
print_data(("Bob", 41, "Google", "english"))    
# Name: Bob  Age: 41  Company: Google Language: english

Tuplu cu un număr nedefinit de elemente

Dacă este necesar să se compare expresia cu un tuplu de lungime nedefinită, restul elementelor tuplului pot fi definite folosind simbolul * (stea):

def print_data(user):
   match user:
       case ("Tom", 37, *rest):
           print(f"Rest: {rest}")
       case (name, age, *rest):
           print(f"{name} ({age}): {rest}")

print_data(("Tom", 37))               # Rest: []
print_data(("Tom", 37, "Google"))     # Rest: ["Google"]
print_data(("Bob", 41, "Microsoft", "english"))     # Bob (41): ["Microsoft", "english"]

În exemplul de mai sus, se folosește parametrul *rest, care corespunde tuturor celorlalte elemente. Astfel, în exemplul de mai sus, șabloanele ("Tom", 37, *rest) și (name, age, *rest) corespund oricărui tuplu cu două elemente sau mai multe. Toate elementele începând cu al treilea vor fi plasate în parametrul rest, care reprezintă o listă de valori.

Dacă acest parametru (rest) nu este important, dar totuși dorim ca șablonul să corespundă unui tuplu cu un număr nedefinit de elemente, putem folosi sub-șablonul *_:

def print_data(user):
   match user:
       case ("Tom", 37, *_):
           print("Default user")
       case (name, age, *_):
           print(f"{name} ({age})")

print_data(("Tom", 37))               # Default user
print_data(("Tom", 37, "Google"))     # Default user
print_data(("Bob", 41, "Microsoft", "english"))     # Bob (41)
← Lecția anterioară Lecția următoare →