前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >短短几十行 Python 代码,实现分词功能搜索引擎(2.0版)

短短几十行 Python 代码,实现分词功能搜索引擎(2.0版)

作者头像
Wu_Candy
发布2022-12-06 20:47:42
8980
发布2022-12-06 20:47:42
举报
文章被收录于专栏:无量测试之道

前言

前期分享的文章 仅30行代码,实现一个搜索引擎(1.0版) 中介绍了如何使用 30行 Python 代码来实现一个简易版的搜索引擎。

仔细阅读过这篇文章的小伙伴可能会产生一些疑虑,例如:

  1. 索引函数每次需要遍历所有文件,需要占用大量的时间和空间,当需被检索的文件及内容量比较大时,每次遍历检索的时间复杂度和空间复杂度就会相当高了。
  2. 检索的文本内容只支持单个单词,如果想一次检索多个词呢,且被检索的词分布在检索文件里的不同位置。

针对以上的疑虑,该如何进行优化呢?

最容易想到的就是将文件内容进行分词,也称语料分词,它的思想是将整个文件内容,按照一定规则处理后形成一个无重复单词的 set 集合,语料分词的做法可以大大提升存储和检索效率。

具体的 Python 代码实现请往下阅读。

Python 核心代码实现
代码语言:javascript
复制
import re
from BaseEngine import SearchEngineBase, main


class BOWModelEngine(SearchEngineBase):
    def __init__(self):
        """
        1.super(BOWModelEngine, self).__init__()含义是指:对继承自父类的属性使用父类的初始化方法进行初始化。
        2.这里的__init__()括号里可以加上父类中初始化时定义的属性,因为此处父类初始化时没有定义任何属性,所以这里括号里为空。
        """
        super(BOWModelEngine, self).__init__()
        self.__file_path_to_content = {}  # 子类BOWModelEngine自定义的私有属性

    def process_search_contents(self, file_path, content):
        """
        该函数实现功能:重写了父类的process_search_contents方法,填充__file_path_to_content字典内容,
        key为文件名称,value为文件内容经过一定规则进行处理过的无重复的单词set。
        :param file_path: 完整路径下的文件名称,例如:/search_contents/1.txt
        :param content: 具体文件内容
        :return:填充__file_path_to_content字典内容
        """
        self.__file_path_to_content[file_path] = self.parse_text_to_words(content)

    def search(self, query_content):
        """
        该函数实现功能:重写了父类的search方法,返回检索文本中每个单词都出现在同一个文件的文件名称列表
        :param query_content:需要检索的文本
        :return:出现在哪些文件里的文件名称列表
        """
        query_words = self.parse_text_to_words(query_content)
        results = []
        for file_path, content in self.__file_path_to_content.items():
            if self.query_match(query_words, content):
                results.append(file_path)
        return results

    @staticmethod
    def query_match(query_words, content):
        """
        该函数实现功能:遍历parse_text_to_words函数返回的无重复的单词set,判断如果有一个单词不存在于当前文件中,则返回False,否则返回True
        :param query_words: 无重复的单词set
        :param content: 每个文件的具体内容
        :return: True&False
        """
        for query_word in query_words:
            if query_word not in content:
                return False
        return True

    @staticmethod
    def parse_text_to_words(content):
        """
        该函数实现功能:将检索文本内容进行一定规则处理后返回无重复的单词set(集合)
        :param content: 检索文本,例如:we will alive long
        :return: 无重复单词的集合,格式为:{'we','will','alive'}
        """
        content = re.sub(r'[^\w ]', ' ', content)  # 使用正则表达式去除标点符号和换行符
        content = content.lower()  # 搜索文本全部转换为小写
        word_list = content.split(' ')  # 使用空格将文本内容进行分隔,生成所有单词的列表
        word_list = filter(None, word_list)  # 生成的单词列表再去除空白单词
        return set(word_list)  # 返回单词的set(无重复的集合), 格式为: {'we','will','alive'}


search_engine = BOWModelEngine()  # 实例化子类BOWModelEngine的对象
main(search_engine)

PS:

1.核心代码块中每个函数实现的功能都有详细的解释说明,请注意仔细阅读,这将非常有助于理解搜索引擎的执行流程和代码流的流转

2.检索文件内容和被继承的基类SearchEngineBase实现代码都是和 仅30行代码,实现一个搜索引擎(1.0版) 这篇文章中所使用的内容是一模一样的,本次只优化了继承父类的子类实现代码。

实现效果预览

至此,一个功能提升的进阶版搜索引擎就实现了,后续还会继续分享功能更加强大搜索引擎实现的高阶版,敬请关注~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-11-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 无量测试之道 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
    • Python 核心代码实现
      • 实现效果预览
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档