Python中如何匹配空字典?错误方法原因及结构化匹配方案
Python结构化模式匹配中空字典匹配的问题与解决
Python 3.10及以上版本支持结构化模式匹配,但实际使用中会发现,匹配空字典的逻辑和空列表并不一致,按直觉编写的代码会出现不符合预期的结果:
错误示例1:直接用{}匹配空字典
def match_empty(m): match m: case []: print("empty list") case {}: print("empty dict") case _: print("not empty")
运行结果:
match_empty([]) # empty list match_empty([1, 2]) # not empty match_empty({}) # empty dict match_empty({'a': 1}) # empty dict # 非空字典被错误匹配
错误示例2:用构造器模式匹配
def match_empty(m): match m: case list(): print("empty list") case dict(): print("empty dict") case _: print("not empty")
运行结果:
match_empty([]) # empty list match_empty([1, 2]) # empty list # 非空列表被错误匹配 match_empty({}) # empty dict match_empty({'a': 1}) # empty dict # 非空字典被错误匹配
可行但需显式检查长度的方案
def match_empty(m): match m: case []: print("empty list") case d: if isinstance(d, dict) and len(d) == 0: print("empty dict") return print("not empty")
运行结果符合预期:
match_empty([]) # empty list match_empty([1, 2]) # not empty match_empty({}) # empty dict match_empty({'a': 1}) # not empty
问题1:为何前两种方法无法达到预期效果?
case {}的问题:
结构化模式匹配里,{}是捕获模式,它只会检查对象是否为字典类型,不会验证字典是否为空——任何字典(空或非空)都会被这个模式匹配到。而[]是序列模式,空序列模式会严格检查序列长度是否为0,因此能正确匹配空列表。case list()/case dict()的问题:
这两个属于类模式,作用是判断对象是否为对应类的实例,不关心实例的具体内容。因此所有列表(无论空或非空)都会匹配case list(),所有字典都会匹配case dict(),自然不符合只匹配空实例的需求。
问题2:是否存在无需显式检查长度,仅用结构化模式匹配即可匹配空dict的方法?
有两种纯模式匹配的实现方式:
方式1:利用**捕获+守卫条件
def match_empty(m): match m: case []: print("empty list") case {**rest} if not rest: print("empty dict") case _: print("not empty")
{**rest}会把字典中所有键值对捕获到rest变量里,if not rest作为守卫条件,只有当rest为空(即原字典没有键值对)时才会匹配成功。
方式2:类模式+守卫条件
def match_empty(m): match m: case []: print("empty list") case dict() if len(m) == 0: print("empty dict") case _: print("not empty")
先通过dict()确认对象是字典类型,再用if len(m) == 0的守卫条件判断是否为空,逻辑直观且符合模式匹配的语法规范。
内容的提问来源于stack exchange,提问作者upe
相关产品推荐
相关产品推荐

