2

我正在计算非负p的Lp距离函数。对于除p = 0 和p = ∞ 之外的所有情况,内置函数都可以很好地发挥作用。在了解结构模式匹配之前,我使用过字典和异常处理:pow()

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)

有些人不希望这里有例外。因此,我将片段重写为以下片段:

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)

为什么case inf:不正确(Python v3.10.2)?

4

1 回答 1

2

case语句中,简单名称是捕获(分配)给该名称模式。相反,带点的名称是指名称的的模式。

简单来说NAME,总是会成功,而且会成功NAME = <subject>

简单来说NAME1.NAME2,只有当<subject> == NAME1.NAME2

使用 justcase inf:意味着要匹配的值无条件地分配给名称inf- 名称之前是否绑定无关紧要。
相反,您想要的是case math.inf:,这意味着与该值进行比较。

import math

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)      
        # compare against a value by using its dotted name
        case math.inf:
            return max(abs(x), abs(y))
        case _:
            return pow(pow(abs(x), p) + pow(abs(y), p), 1.0/p)
于 2022-02-12T18:26:45.650 回答