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

如何将CSV时间戳字符串转为Pydantic模型的TimeStamp列表?

解决CSV转Pydantic对象时时间戳字符串转模型列表的问题

问题场景

现有包含YouTube链接和时间戳的CSV文件,格式如下:

https://www.youtube.com/watch?v=dsnLcaNhXd6o,0:13-0:20;0:25-0:31;0:36-0:40
https://www.youtube.com/watch?v=d8InLcaNhXd6o,0:43-0:52;0:56-1:07
https://www.youtube.com/watch?v=Inji8LcaNhXd6o,0:13-0:20;0:25-0:31;0:36-0:40;0:43-0:52;0:56-1:07;1:15-1:25;1:28-1:40

通过csv.reader读取并结合enumerate得到带行索引的元组列表后,无法直接将时间戳字符串映射到定义好的TimeStamp模型列表字段,添加验证器时因类型不匹配报错。

已定义的Pydantic模型:

class TimeStamp(BaseModel):
    start_min: int
    start_sec: int
    end_min: int
    end_sec: int

class VideoDetail(BaseModel):
    row_index: int
    url: str
    timestamps: List[TimeStamp]

class VideoList(BaseModel):
    entry: List[VideoDetail]

解决方案

核心思路是在Pydantic字段验证流程中,提前将时间戳字符串转换为符合TimeStamp模型结构的字典列表,再由Pydantic自动解析为模型对象。以下分Pydantic v2和v1两种版本给出实现:

版本1:Pydantic v2(推荐)

使用Annotated结合BeforeValidator,在字段验证前完成字符串解析:

from pydantic import BaseModel, BeforeValidator, ValidationError
from typing import List, Annotated

class TimeStamp(BaseModel):
    start_min: int
    start_sec: int
    end_min: int
    end_sec: int

# 自定义时间戳字符串解析函数
def parse_timestamp_str(timestamp_str: str) -> List[dict]:
    timestamps = []
    # 拆分多个时间戳片段
    for ts_part in timestamp_str.split(';'):
        # 拆分开始/结束时间
        start_str, end_str = ts_part.split('-')
        # 拆分分/秒并转为整数
        start_min, start_sec = map(int, start_str.split(':'))
        end_min, end_sec = map(int, end_str.split(':'))
        timestamps.append({
            'start_min': start_min,
            'start_sec': start_sec,
            'end_min': end_min,
            'end_sec': end_sec
        })
    return timestamps

class VideoDetail(BaseModel):
    row_index: int
    url: str
    # 用Annotated标记字段,指定前置验证器
    timestamps: Annotated[List[TimeStamp], BeforeValidator(parse_timestamp_str)]

class VideoList(BaseModel):
    entry: List[VideoDetail]

版本2:Pydantic v1

使用@validator装饰器并设置pre=True,开启前置验证:

from pydantic import BaseModel, validator, ValidationError
from typing import List

class TimeStamp(BaseModel):
    start_min: int
    start_sec: int
    end_min: int
    end_sec: int

class VideoDetail(BaseModel):
    row_index: int
    url: str
    timestamps: List[TimeStamp]

    @validator('timestamps', pre=True)
    def parse_timestamps(cls, value):
        # 仅当输入为字符串时进行解析
        if isinstance(value, str):
            timestamps = []
            for ts_part in value.split(';'):
                start_str, end_str = ts_part.split('-')
                start_min, start_sec = map(int, start_str.split(':'))
                end_min, end_sec = map(int, end_str.split(':'))
                timestamps.append({
                    'start_min': start_min,
                    'start_sec': start_sec,
                    'end_min': end_min,
                    'end_sec': end_sec
                })
            return timestamps
        # 非字符串输入直接返回,交给后续验证
        return value

class VideoList(BaseModel):
    entry: List[VideoDetail]

CSV数据转换与验证

将读取的CSV元组列表转换为符合VideoDetail结构的字典列表,再传入VideoList完成验证:

import csv

csv_file = 'your_youtube_data.csv'

with open(csv_file, mode='r') as file:
    csv_reader = csv.reader(file)
    video_data = []
    for row_idx, row in enumerate(csv_reader):
        # 跳过无效行(确保每行有2个元素:链接+时间戳)
        if len(row) != 2:
            print(f"警告:第{row_idx}行格式无效,已跳过")
            continue
        url, timestamp_str = row
        video_data.append({
            'row_index': row_idx,
            'url': url,
            'timestamps': timestamp_str
        })

# 验证并生成模型对象
try:
    video_list = VideoList(entry=video_data)
    # 输出验证后的JSON格式数据
    print(video_list.model_dump_json(indent=2))
except ValidationError as e:
    print(f"验证错误:{e}")

关键说明

  • 前置验证器(BeforeValidator或pre=True的@validator)会在Pydantic进行类型检查前执行,将字符串转换为List[dict],此时Pydantic可以自动将字典解析为TimeStamp模型对象。
  • 解析函数中加入了基础的格式拆分逻辑,若需要更严格的时间格式验证(比如秒数不超过59),可以在TimeStamp模型中添加额外的字段验证器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 07:15:43