61

I am trying to use multiple cases in a function similar to the one shown below so that I can be able to execute multiple cases using match cases in python 3.10

def sayHi(name):
    match name:
        case ['Egide', 'Eric']:
            return f"Hi Mr {name}"
        case 'Egidia':
            return f"Hi Ms {name}"
print(sayHi('Egide'))

This is just returning None instead of the message, even if I remove square brackets.

Egidius
  • 971
  • 1
  • 10
  • 22
  • 1
    https://www.python.org/dev/peps/pep-0635/#or-patterns, https://www.python.org/dev/peps/pep-0636/#or-patterns, https://docs.python.org/3/whatsnew/3.10.html#pep-634-structural-pattern-matching – jonrsharpe Oct 20 '21 at 08:46

2 Answers2

101

According to What’s New In Python 3.10, PEP 636, and the docs, you use a | between patterns:

case 'Egide' | 'Eric':
Jacktose
  • 709
  • 7
  • 21
khelwood
  • 55,782
  • 14
  • 81
  • 108
  • 1
    What if you already have the list (and need to use it in more places)? Can you somehow create that `'Egide' | 'Eric'` pattern from a list? Or is it better to use an if statement in that case? – Ruben Oct 18 '22 at 10:38
  • 1
    @Ruben That sounds like a better situation for an if-statement. – khelwood Oct 18 '22 at 11:09
  • 1
    @Ruben You can do that with a [guard](https://peps.python.org/pep-0636/#adding-conditions-to-patterns): `case name if name in male_names:`. There's more in [Blake's answer](https://stackoverflow.com/a/74187281/). – Jacktose Oct 25 '22 at 23:45
19

You can use | (or) to replace ['Egide', 'Eric'] with 'Egide' | 'Eric', but you can also match elements belonging to iterables or containers with a guard, as follows:

CONSTANTS = ['a','b', ...] # a (possibly large) iterable

def demo(item):
    match item:
        case item if item in CONSTANTS:
            return f"{item} matched"
        case _:
            return f"No match for {item}"
Blake
  • 986
  • 9
  • 24
  • 5
    shouldn't `case other` be `case _`? – odigity Nov 08 '22 at 22:23
  • 6
    Hi @odigity -- It's simply an unused variable name, so you can call it anything you'd like – Blake Nov 08 '22 at 23:17
  • 4
    @blake, agreed, but the (un)official convention seems to be _ for the default case. – Tom Pohl Mar 09 '23 at 09:04
  • 1
    @TomPohl @Black there is a difference between `case other` and `case _` and it is explained in PEP 634 as well as here: https://earthly.dev/blog/structural-pattern-matching-python. The former is a capture match and binds the match to a new variable `other` while the latter is a wildcard match. If nothing else is given, both always succeed. – interDist Jun 08 '23 at 10:03
  • 1
    @interDist, agreed, but since `other` is not used in the case body, I would still recommend _. – Tom Pohl Jun 13 '23 at 14:55