Python pattern match on an operator

60 Views Asked by At

I'm trying to build a function that would match on a operator , like - :

def testM(x):
    match x:
        case (operator.sub,a,b):
            return operator.sub(a,b)
        case ('-',a, b):
            return a-b
        case ("+",a,b):
            return a+b
        case ("other strange op",a,b,c):
            return (a+b-c)
        .......
        case _ : 
            return 0

The function will be used in jupyter, so user will type it quite frequently. I would like to make it minimal keystroke possible

testM('-',5,1)  ## 3 key strokes
# it works and return 4 

testM((operator.sub,4,1))   ## 12 key strokes
# it works and return 3

The goal is , user can call it like, but it doesn't work.

testM(-,5,1)  ## only 1 key strokes
# it return 4 

Is there a way to escape evaluation of - in the parameter ? then python won't raise error ?

1

There are 1 best solutions below

2
Tranbi On BEST ANSWER

I'm not sure pattern matching is the way to go here. You could just check the type of your operator and return the desired operation. An example checking for callable and string:

from simpleeval import simple_eval
from functools import reduce

def testM(*x):
    if callable(x[0]):
        return reduce(x[0], x[1:])
    elif isinstance(x[0], str):
        return simple_eval(x[0].join(map(str, x[1:])))
    #else: handle further situations if needed

Output:

print(testM('-', 5, 2))                #3
print(testM('+', 5, 2, 4))             #11
print(testM(operator.add, 5, 2, 4))    #11

Edit: using match...case, it would look like this:

def testM(*args):
    match args:
        case [x, *p] if callable(x):
            return reduce(x, p)
        case [x, *p] if isinstance(x, str):
            return simple_eval(x.join(map(str, p)))
        #handle further cases if needed