You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Python的match/case语句匹配元素全为字符串的列表?

如何用Python的match/case语句匹配元素全为字符串的列表?

我来帮你梳理这个问题的解决方案,咱们一步步拆解:

一、先解释为什么test(['This', 'should', 0, 'not', 'match'])没被警告

你提到PyCharm没给这个用例标红,这是因为默认的类型检查模式不会严格校验容器(比如列表)内部的元素类型。要让它检测到这种问题,你需要开启更严格的类型检查:

  • 在PyCharm里:打开SettingsLanguages & FrameworksPythonType Checking,把Type Checking Mode改成Strict
  • 如果用mypy这类命令行类型检查工具,需要加上--strict参数运行,它就会指出这个列表里混了非字符串元素的问题

二、如何用match/case匹配全字符串的列表

Python的match/case运行时模式匹配,而list[str]只是静态类型注解,运行时根本不存在这个“类型”——它只是给静态检查工具看的提示,不是实际的类。所以直接写case list[str]()肯定行不通。

要实现匹配元素全为字符串的列表,你可以给case加上守卫子句(guard clause),也就是用if来额外校验列表里的每个元素:

def checkArg(arg: str | list[str]) -> str:
    match arg:
        case str():
            return 'str'
        case list() if all(isinstance(item, str) for item in arg):
            return 'list(str)'
        case _:
            return "unmatched"

def test(arg: str | list[str]):
    print(f'{arg=!r}: {checkArg(arg)}')

test(0)                  # 输出: arg=0: unmatched
test('This should match')# 输出: arg='This should match': str
test(['This', 'should', 'match']) # 输出: arg=['This', 'should', 'match']: list(str)
test(['This', 'should', 0, 'not', 'match']) # 输出: arg=['This', 'should', 0, 'not', 'match']: unmatched

这里的if all(isinstance(item, str) for item in arg)就是守卫,它会在匹配到list类型后,额外检查列表里的每个元素是不是字符串,只有全满足才会进入这个分支。

补充说明

你原来的case list()只会检查传入的参数是不是list实例,完全不管里面的元素类型,所以哪怕列表里混了数字也会匹配成功。加上守卫后就能精准过滤出全字符串的列表啦。

备注:内容来源于stack exchange,提问作者xenoid

火山引擎 最新活动