如何用Python match/case匹配列表重复元素?解决重复绑定报错
Python match/case 匹配三个重复元素的解决办法
问题情况
你原本想靠Python的match/case语法检测短列表里的重复元素——比如匹配[n, n, n]这种三个元素都相同的列表,还能拿n做运算(比如骰子游戏算分),但写的代码报错,说后两个n已经被绑定:
def score_3(dice: list[int]) -> tuple[str, int]: dice.sort() match dice: case [1, 1, 1]: return "3 MOOSE", 300 case [n, n, n]: return f"3 {n}S", n*100 case _: return different_scoring_function(dice)
试了换成[n] * 3也没用,虽然你已经有个靠字典计数的可行方案,但还是想知道有没有基于模式匹配的解决办法。
为啥报错
Python的模式匹配里,[n, n, n]这种写法是先把第一个位置的元素绑定给n,后面的n会被当成已经绑定好的变量去做值匹配,而不是让三个位置都绑定同一个变量。所以要么元素不相等时匹配失败,相等时也会因为重复绑定变量报错。
可行的模式匹配方案
给你三种靠谱的写法:
写法1:用守卫(Guard)判断
捕获第一个元素为n,然后加个if条件确保后两个元素都等于n:
def score_3(dice: list[int]) -> tuple[str, int]: dice.sort() match dice: case [1, 1, 1]: return "3 MOOSE", 300 case [n, a, b] if a == n and b == n: return f"3 {n}S", n * 100 case _: return different_scoring_function(dice)
写法2:用海象运算符+守卫
不想写多个变量的话,用海象运算符先抓第一个元素,再判断所有元素都等于它:
def score_3(dice: list[int]) -> tuple[str, int]: dice.sort() match dice: case [1, 1, 1]: return "3 MOOSE", 300 case lst if (n := lst[0]) == lst[1] == lst[2]: return f"3 {n}S", n * 100 case _: return different_scoring_function(dice)
写法3:结合可变长度模式+条件
用*匹配剩余元素,再判断所有剩余元素和第一个元素相等:
def score_3(dice: list[int]) -> tuple[str, int]: dice.sort() match dice: case [1, 1, 1]: return "3 MOOSE", 300 case [n, *rest] if all(x == n for x in rest): return f"3 {n}S", n * 100 case _: return different_scoring_function(dice)
你已实现的字典计数方案
def score_3(counts: dict[int, int]) -> tuple[str, int]: for i in counts: if counts[i] == 3: if i == 1: return "3 MOOSE", 300 else: return f"3 {i}S", i * 100
内容的提问来源于stack exchange,提问作者whatf0xx
相关产品推荐
相关产品推荐

