乐趣区

关于python:pyhon简单实现json对值进行模糊搜索

我常常应用 json 进行存储配置,于是经常遇到这样的问题:如果想要对某个数组里的值进行含糊搜寻,同时输入相干的其余数组雷同地位的的值该如何实现呢?

思路

代入理论案例来思考一下我的解法

数据

{
    "name": [
        "电饭煲版广式腊肠煲饭",
        "电饭煲烧鸡",
        "电饭煲焖面"],
    "ingredients": [
        "腊肠、米",
        "鸡肉、洋葱、菌菇",
        "猪肉、面食"],
    "url": [
        "https://www.***.com/video/BV1NE411Q7Jj",
        "https://www.***.com/video/BV1T54y1U7Cu",
        "https://www.***.com/video/BV14b411q7rM"
        "https://www.***.com/video/BV1K441157rz"],
    "difficulty": [
        "简略",
        "简略",
        "简略"],
    "tag": [
        "广式",
        "好吃",
        "衰弱餐"],
    "practice": [
        "炒",
        "烧",
        "蒸"
        ""],"tool": [" 电饭煲 "," 电饭煲 "," 电饭煲 """]
}

这是一个菜谱 json。
如果我当初被隔离在家了,手头上只有零星的食材,我想依据手头上的食材来看看我都能做出什么菜。
那么这该如何实现呢?

解法一

如果已知我手上的食物有牛肉、洋葱。那么我能够这样实现

  1. 遍历 json,而后别离创立数组变量存储 name、ingredients、url、difficulty 等 json 数组内容
  2. 遍历 ingredients 数组,含糊匹配是否与我手头上的食物统一
  3. 如果统一,将数据退出新的数组中,同时把雷同地位的 name、url、difficulty 等 json 数组内容也别离退出新的数组中
  4. 同时输入各个数组的内容
    不言而喻,这种解法太呆了,于是我想还有哪里能够优化呢?

解法二

于是我又想到了另一种写法

  1. 只遍历一次 json 并存储,而后再存储一组须要含糊匹配的内容数组
    (这个内容数组能够是你想匹配的任何值所在的对应数组,例如想含糊匹配菜名,就只须要存储 name 数组,想含糊匹配食材,就只须要存储 ingredients 数组)
  2. 含糊匹配是否与我手头上的食物统一并记录下地位
  3. 通过地位取其余相干的其余数组雷同地位的的值

这个解法的关键在于,因为各个数组的长度雷同,所以获取一次地位即可同时晓得其余对应数值所在的对应数组中的地位
说的有点绕,间接上代码。

代码实现

首先取菜谱数据

# 取菜谱 json
def get_record():
    url = "./menu.json"
    if not os.path.isfile(url):
        return "菜谱获取失败"
    fo = open(url, "r", encoding='utf-8')
    ele_json = loads(fo.read())
    return ele_json

含糊搜寻实现

# 含糊搜寻
def fuzzyfinder(user_input, collection_key_list):
    suggestions = []
    pattern = '.*?'.join(user_input)  # Converts 'djm' to 'd.*?j.*?m'
    regex = compile(pattern)  # Compiles a regex.
    a = 0
    for item in collection_key_list:
        match = regex.search(item)  # Checks if the current item matches the regex.
        if match:
            suggestions.append(a)
        a = a + 1
    return suggestions

user_inputcollection_key_list 别离示意 关键字 欲含糊匹配的数组
suggestions 数组 存储了含糊匹配上了的数值的地位

最初依据理论状况进行数据取出应用即可。
在本例子里,就是取出菜谱

def get_cook(key):
    # 进一步解析资源 json
    al_dict = get_record()
    collection_key = []  # 用来含糊匹配的 key
    for b in al_dict['ingredients']:
        collection_key.append(b)
    fuzzyfinder_i_list = fuzzyfinder(key, collection_key)  # 含糊搜寻资源
    fuzzyfinder_i_len = len(fuzzyfinder_i_list)
    if fuzzyfinder_i_len > 0:
        if collection_key[fuzzyfinder_i_list[0]].replace("、", "") == key.replace("、",""):
            return "".join([al_dict['name'][fuzzyfinder_i_list[0]]," 丨 ", al_dict['ingredients'][fuzzyfinder_i_list[0]],"\nB 站教程 BV 号:", al_dict['url'][fuzzyfinder_i_list[0]],"\n 难度:",
                            al_dict['difficulty'][fuzzyfinder_i_list[0]], "丨标签:", al_dict['tag'][fuzzyfinder_i_list[0]],
                            "\n 办法:", al_dict['practice'][fuzzyfinder_i_list[0]], "丨工具:",
                            al_dict['tool'][fuzzyfinder_i_list[0]]])
        elif collection_key[fuzzyfinder_i_list[fuzzyfinder_i_len - 1]].replace("、", "") == key.replace("、",""):
            return "".join([al_dict['name'][fuzzyfinder_i_list[fuzzyfinder_i_len - 1]]," 丨 ",
                            al_dict['ingredients'][fuzzyfinder_i_list[fuzzyfinder_i_len - 1]],
                            "\nB 站教程 BV 号:", al_dict['url'][fuzzyfinder_i_list[fuzzyfinder_i_len - 1]], "\n 难度:",
                            al_dict['difficulty'][fuzzyfinder_i_list[fuzzyfinder_i_len - 1]], "丨标签:",
                            al_dict['tag'][fuzzyfinder_i_list[fuzzyfinder_i_len - 1]],
                            "\n 办法:", al_dict['practice'][fuzzyfinder_i_list[fuzzyfinder_i_len - 1]], "丨工具:",
                            al_dict['tool'][fuzzyfinder_i_list[fuzzyfinder_i_len - 1]]])
        else:
            re_text = "未找到精准关键词,含糊搜寻到以下内容:\n"
            for c in fuzzyfinder_i_list:
                re_text = "".join([re_text, al_dict['name'], "丨", al_dict['ingredients'], "\nB 站教程 BV 号:",
                     al_dict['url'], "\n 难度:", al_dict['difficulty'],
                     "丨标签:", al_dict['tag'], "\n 办法:", al_dict['practice'],
                     "丨工具:", al_dict['tool'], "\n"])

            return re_text
    else:
        content = "".join([" 未找到 "+ key +" 相干菜谱 "])
        return content

这个写法能够同时解决精准匹配和含糊匹配问题,精准匹配后果个别是数组第一个或最初一个,所以只须要判断一下首尾是否与关键字雷同即可

后果

来看一下成果

精准匹配

if __name__ == "__main__":
    print(get_cook("胡萝卜、牛肉、洋葱"))
>>> 胡萝卜炖牛肉丨胡萝卜、牛肉、洋葱
>>>B 站教程 BV 号:https://www.***.com/video/BV1UR4y1V7nV
>>> 难度:艰难丨标签:法式
>>> 办法:炖丨工具:一口大锅

含糊匹配

if __name__ == "__main__":
    print(get_cook("牛肉、洋葱"))
>>> 未找到精准关键词,含糊搜寻到以下内容:>>> 电饭煲罗宋汤丨牛肉、番茄、洋葱、芹菜、胡萝卜、土豆、卷心菜
>>>B 站教程 BV 号:https://www.***.com/video/BV16Q4y1m7nU
>>> 难度:简略丨标签:杂烩
>>> 办法:丨工具:电饭煲
>>> 胡萝卜炖牛肉丨胡萝卜、牛肉、洋葱
>>>B 站教程 BV 号:https://www.***.com/video/BV1UR4y1V7nV
>>> 难度:艰难丨标签:法式
>>>...

问题解决

源码与数据

欢送 Star 欢送━(`∀´)ノ亻!
github

参考

YunYouJun/cook: 🍲 好的,明天咱们来做菜!
隔离食用手册大全

退出移动版