如何模糊匹配dict与pydantic模型相匹配?

发布于 2025-02-12 11:21:44 字数 2098 浏览 0 评论 0原文

我希望能够模糊的字典键与我的一个模型匹配,但我不确定这是否是最好的方法。我在脚本底部提供了不同的测试用例,以显示可能传递的信息。

有人知道创建模糊匹配的更有效的方法吗?

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


class ExtendedBaseModel(BaseModel):
    @classmethod
    def get_field_names(cls, alias=False):
        return list(cls.schema(alias).get("properties").keys())


class Image(ExtendedBaseModel):
    """Represents any picture image that needs to be stored via a 64 bit encoding"""
    id: str = str(uuid.uuid4())
    width: Optional[int] = 1920
    height: Optional[int] = 1080
    base64str: str


class MouseCoord(ExtendedBaseModel):
    x: int
    y: int


def dict_to_model(input_dict: dict):
    all_models = {
        "Image": Image.get_field_names(),
        "MouseCoord": MouseCoord.get_field_names(),
    }
    best_match = {}
    for model, model_fields in all_models.items():
        input_keys = input_dict.keys()
        percent_match = len(set(model_fields) & set(input_keys)) / float(len(set(model_fields) | set(input_keys)))
        new_match = {"model": model, "percent_match": percent_match}
        if percent_match > 0:
            if not best_match:
                best_match = new_match
            elif percent_match > best_match.get("percent_match"):
                best_match = new_match
                if percent_match == 1:
                    break
                
    if not best_match:
        return None
    elif best_match.get("model") == "Image":
        try:
            return Image(**input_dict)
        except:
            return None
    elif best_match.get("model") == "MouseCoord":
        try:
            return MouseCoord(**input_dict)
        except:
            return None
    

dict_1 = {"x": 1}
dict_2 = {"x": 1, "y": 2}
dict_3 = {"id": str(uuid.uuid4()), "base64str": "sdfsefs"}
dict_4 = {"id": str(uuid.uuid4()), "width": 10, "height": 10, "base64str": "sdfsefs" }
dict_5 = {"foo": "bar"}
one = dict_to_model(dict_1)
two = dict_to_model(dict_2)
three = dict_to_model(dict_3)
four = dict_to_model(dict_4)
five = dict_to_model(dict_5)

I want to be able to fuzzy match the keys of a dictionary to one of my models but I am not sure if this is the best way to do it. I provided different test cases on the bottom of the script to show what information might be passed.

Does anyone know a more efficient way of creating this fuzzy match?

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


class ExtendedBaseModel(BaseModel):
    @classmethod
    def get_field_names(cls, alias=False):
        return list(cls.schema(alias).get("properties").keys())


class Image(ExtendedBaseModel):
    """Represents any picture image that needs to be stored via a 64 bit encoding"""
    id: str = str(uuid.uuid4())
    width: Optional[int] = 1920
    height: Optional[int] = 1080
    base64str: str


class MouseCoord(ExtendedBaseModel):
    x: int
    y: int


def dict_to_model(input_dict: dict):
    all_models = {
        "Image": Image.get_field_names(),
        "MouseCoord": MouseCoord.get_field_names(),
    }
    best_match = {}
    for model, model_fields in all_models.items():
        input_keys = input_dict.keys()
        percent_match = len(set(model_fields) & set(input_keys)) / float(len(set(model_fields) | set(input_keys)))
        new_match = {"model": model, "percent_match": percent_match}
        if percent_match > 0:
            if not best_match:
                best_match = new_match
            elif percent_match > best_match.get("percent_match"):
                best_match = new_match
                if percent_match == 1:
                    break
                
    if not best_match:
        return None
    elif best_match.get("model") == "Image":
        try:
            return Image(**input_dict)
        except:
            return None
    elif best_match.get("model") == "MouseCoord":
        try:
            return MouseCoord(**input_dict)
        except:
            return None
    

dict_1 = {"x": 1}
dict_2 = {"x": 1, "y": 2}
dict_3 = {"id": str(uuid.uuid4()), "base64str": "sdfsefs"}
dict_4 = {"id": str(uuid.uuid4()), "width": 10, "height": 10, "base64str": "sdfsefs" }
dict_5 = {"foo": "bar"}
one = dict_to_model(dict_1)
two = dict_to_model(dict_2)
three = dict_to_model(dict_3)
four = dict_to_model(dict_4)
five = dict_to_model(dict_5)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文