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'][c], "丨", al_dict['ingredients'][c], "\nB站教程BV号:",
                     al_dict['url'][c], "\n难度:", al_dict['difficulty'][c],
                     "丨标签:", al_dict['tag'][c], "\n方法:", al_dict['practice'][c],
                     "丨工具:", al_dict['tool'][c], "\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: 🍲 好的,今天我们来做菜!
隔离食用手册大全

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容