如何在Pydantic中将多个itemN格式的输入变量合并为单个列表字段?
如何在Pydantic中将多个itemN格式的输入变量合并为单个列表字段?
我来给你分享一个简洁的解决方案,完全贴合Pydantic的设计思路,不用手动逐个定义item1、item2这类字段,就能自动把所有itemN格式的输入收集到items列表里。
核心思路:利用模型验证器预处理输入
我们可以借助Pydantic的模型验证器,在模型解析输入数据之前,自动筛选出所有符合item+数字格式的字段,按顺序收集到items列表中,再把处理后的数据交给模型解析。
下面分Pydantic版本给出具体实现:
Pydantic v2 实现(推荐,当前主流版本)
from pydantic import BaseModel, model_validator from typing import List, Dict, Any class SomeModel(BaseModel): items: List[str] @model_validator(mode='before') def collect_items(cls, values: Dict[str, Any]) -> Dict[str, Any]: # 筛选出所有以"item"开头、后面跟数字的键 item_keys = [k for k in values if k.startswith('item') and k[4:].isdigit()] # 按数字顺序排序,保证item1、item2、item3的顺序不乱 sorted_item_keys = sorted(item_keys, key=lambda x: int(x[4:])) # 收集对应的值,并从原输入中移除这些itemN字段 items = [values.pop(key) for key in sorted_item_keys] # 把收集好的列表赋值给items字段 values['items'] = items return values
Pydantic v1 实现
如果还在使用v1版本,只需要把验证器换成root_validator并设置pre=True:
from pydantic import BaseModel, root_validator from typing import List, Dict class SomeModel(BaseModel): items: List[str] @root_validator(pre=True) def collect_items(cls, values: Dict[str, Any]) -> Dict[str, Any]: item_keys = [k for k in values if k.startswith('item') and k[4:].isdigit()] sorted_item_keys = sorted(item_keys, key=lambda x: int(x[4:])) items = [values.pop(key) for key in sorted_item_keys] values['items'] = items return values
测试用法
不管是哪个版本,你都可以直接传入带itemN的字典(或者从CSV读取的行数据)来实例化模型:
# 模拟CSV读取的一行数据 input_data = {"item1": "apple", "item2": "banana", "item3": "cherry"} model = SomeModel(**input_data) print(model.items) # 输出: ['apple', 'banana', 'cherry']
额外优化:添加字段约束
如果要求必须至少有一个itemN字段,可以给items字段添加Field约束:
from pydantic import Field class SomeModel(BaseModel): items: List[str] = Field(min_length=1, description="至少需要提供一个item") # 验证器代码同上...
这样如果输入中没有任何itemN字段,模型会直接抛出验证错误,符合业务要求。
这种方法完全遵循Pydantic的设计逻辑,没有任何hack操作,还能灵活适配任意数量的itemN字段,不管是3个还是100个都能自动处理。
备注:内容来源于stack exchange,提问作者blinken_lx
相关产品推荐
相关产品推荐

