I am computing the Lp distance functions for non-negative p's. For all but p = 0 and p = ∞ a built-in pow()
function serves well.
Before I learned about a structural pattern matching, I had used a dictionary and exception handling:
from math import sqrt, inf
distance_function = { 0.0: lambda x, y: int(x != 0.0) + int(y != 0.0),
1.0: lambda x, y: abs(x) + abs(y), # Likely a tad faster than 'pow()'
inf: lambda x, y: max(abs(x), abs(y))}
def lp_distance(x, y, p):
try: return distance_function[p](x, y)
except KeyError: return pow(pow(abs(x), p) + pow(abs(y), p), 1.0/p)
Some people didn't want exceptions here. So I rewrote the snippet into the following one:
def lp_distance(x, y, p):
match p:
case 0.0: return int(x != 0.0) + int(y != 0.0)
case 1.0: return abs(x) + abs(y)
# The line below triggers "SyntaxError: name capture 'inf' makes remaining patterns unreachable"
case inf: return max(abs(x), abs(y))
# But the following works:
case p if p == inf: return max(abs(x), abs(y))
case _: return pow(pow(abs(x), p) + pow(abs(y), p), 1.0/p)
Why case inf:
is not correct (Python v3.10.2)?