You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为List[List[int]]构建Pydantic模型及解决验证报错

Pydantic验证List[List[int]]类型数据的问题

问题描述

我是Pydantic新手,想要验证List[List[int]]类型的数据,编写了如下测试代码:

from pydantic import BaseModel, field_validator
from typing import List, Optional

class Scenes(BaseModel):
    scenes_start_duration_ms: List[List[int]]

class Video(BaseModel):
    video_id: str
    scenes_start_duration_ms: Optional[Scenes] = None
   
if __name__ == "__main__":
    response = {
        "scenes_start_duration_ms": [
            [0, 1234],
            [1568, 2769],
            [4671, 734],
            [5405, 1268],
        ],
        "video_id": "kl",
    }

    m = Scenes.model_validate(response)
    print(m)

    m = Video.model_validate(response)
    print(m)

运行后输出:

scenes_start_duration_ms=[[0, 1234], [1568, 2769], [4671, 734], [5405, 1268]]
Traceback (most recent call last):
  File "/media/hdd/P/UW/clipmaker/test-list.py", line 30, in <module>
    m = Video.model_validate(response)
  File "/media/hdd/P/UW/clipmaker/venv/lib/python3.10/site-packages/pydantic/main.py", line 509, in model_validate
    return cls.__pydantic_validator__.validate_python(
pydantic_core._pydantic_core.ValidationError: 1 validation error for Video
scenes_start_duration_ms
  Input should be a valid dictionary or instance of Scenes [type=model_type, input_value=[[0, 1234], [1568, 2769],...671, 734], [5405, 1268]], input_type=list]

我无法理解问题所在,后来将Video类中的代码修改为:

scenes_start_duration_ms: Optional[List[List[int]]] = None

后可以正常运行,但希望得到最优解决方案。


问题原因

Video类中scenes_start_duration_ms字段定义的类型是Optional[Scenes],但传入的response里该字段的值是List[List[int]]类型的二维列表,而非符合Scenes模型结构的字典(即{"scenes_start_duration_ms": [[...]]})。Pydantic验证时会期望该字段是Scenes实例或其对应的字典结构,因此抛出验证错误。

最优解决方案

根据需求场景,有两种合理的最优方案:

方案1:复用Scenes模型(适合需要分层封装的场景)

如果需要保留Scenes模型来封装场景数据的后续验证逻辑,可选择以下两种方式:

方式一:调整输入数据结构(推荐,若数据格式可修改)

将response中的scenes_start_duration_ms改为嵌套字典,匹配Scenes模型的结构:

response = {
    "scenes_start_duration_ms": {
        "scenes_start_duration_ms": [
            [0, 1234],
            [1568, 2769],
            [4671, 734],
            [5405, 1268],
        ]
    },
    "video_id": "kl",
}

修改后Video.model_validate(response)即可正常运行。

方式二:添加字段解析逻辑(若无法修改输入数据)

使用field_validator在验证前将二维列表转换为Scenes模型所需的结构:

from pydantic import BaseModel, field_validator
from typing import List, Optional, Any

class Scenes(BaseModel):
    scenes_start_duration_ms: List[List[int]]

class Video(BaseModel):
    video_id: str
    scenes_start_duration_ms: Optional[Scenes] = None

    @field_validator("scenes_start_duration_ms", mode="before")
    def parse_scenes(cls, v: Any) -> Any:
        if isinstance(v, list):
            return {"scenes_start_duration_ms": v}
        return v

这样即使传入的是二维列表,验证器会先将其转换为符合Scenes模型的字典,再完成验证。

方案2:直接使用List[List[int]](简洁高效)

如果不需要单独的Scenes模型做额外封装,直接将Video类的字段类型定义为Optional[List[List[int]]]就是最优解,即你更新后的代码:

class Video(BaseModel):
    video_id: str
    scenes_start_duration_ms: Optional[List[List[int]]] = None

该方案无需多余模型嵌套,代码简洁,适合不需要对场景数据做额外验证逻辑的场景。


内容的提问来源于stack exchange,提问作者Andrey Dmitriev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:08:10