0

Like in this question, I am trying to match an element in a list, and handle the cases accordingly. See the example below.

direct_payments = ["creditcard", "debitcard"]
on_credits = ["gift card", "rewards program"]

def print_payment_type(payment_type):
    match payment_type:
        case in direct_payments:
            print("You paid directly!")
        case in on_credits:
             print("You paid on credits!")

print_payment_type("gift card")

I want this to print "You paid on credits". I am convinced that using structural pattern matching is the most readable option in my case. Is there any way to achieve this behaviour? I cannot use "gift card" | "rewards program", because I need to use the lists elsewhere.

Ruben
  • 103
  • 2

4 Answers4

2
  • case needs to a pattern (the feature is called structural pattern matching after all). So we cannot include a function there (e.g. case XX in direct_credits.) [Thanks to matszwecja for this clarification.]

  • The cases are generated by the match statement. So we cannot do this case in direct_payments:.

I could think of an application of case like this:

direct_payments = ["creditcard", "debitcard"]
on_credits = ["gift card", "rewards program"]

def find_val(value, arrays):
    for i, arr in enumerate(arrays):
        if value in arr:
            return i
    return -1

def print_payment_type(payment_type):
    match find_val(payment_type, [direct_payments, on_credits]):
        case 0:
            print("You paid directly!")
        case 1:
            print("You paid on credits!")

print_payment_type("gift card")

However, I do not understand why you would prefer case over if/ elif/else. You could combine your requirements easily using and/or. Anything that you want to do using match-case should be easily doable using elif` conditions.

direct_payments = ["creditcard", "debitcard"]
on_credits = ["gift card", "rewards program"]

def print_payment_type(payment_type):
    if (payment_type in direct_payments) and (payment_type not in on_credits):
        print("You paid directly!")
    elif payment_type in on_credits:
        print("You paid on credits!")

print_payment_type("gift card")

This link should be where you can get more examples of using case.

EDIT: gimix has a better answer.

kgkmeekg
  • 524
  • 2
  • 8
  • 17
  • `case` does not need to be a type - it is supposed to be a *pattern* though (the feature is called *structural pattern matching* after all). That's why if/else is a better solution here, as OP is dealing with *conditions*, not *patterns*. – matszwecja Oct 19 '22 at 11:23
  • The case operator jumps to the instruction needed, while if/else must check every condition before stopping at the condition of choice. – Noji Jun 13 '23 at 21:51
1

This works:

def print_payment_type(payment_type):
    match payment_type:
        case payment_type if payment_type in direct_payments:
            print("You paid directly!")
        case payment_type if payment_type in on_credits:
             print("You paid on credits!")
gimix
  • 3,431
  • 2
  • 5
  • 21
1

You can use a dictionary, like this:

my_dict = {'direct_payments': ["creditcard", "debitcard"],
    'on_credits': ["gift card", "rewards program"]}


def print_payment_type(payment_type):
    selected_key=next(key for key, value in my_dict.items() if payment_type in value)
    print("The selected dictionary key is", selected_key)
    match selected_key:
        case "direct_payments":
            print("You paid directly!")
        case "on_credits":
             print("You paid on credits!")

print_payment_type("gift card")
AziMez
  • 2,014
  • 1
  • 6
  • 16
0

You could use structural pattern matching like this:

def print_payment_type(payment_type):
    match payment_type:
        case "creditcard" | "debitcard":
            print("You paid directly!")
        case "gift card" | "rewards program":
            print("You paid on credits!")


print_payment_type("gift card")

However, this might not be the most elegant option because you "lose" the direct_payments and on_credits lists.