Python应用专题 | 2: 全面评测子串匹配

本文涉及的产品
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: 记录评测子串匹配的各个方案,以供后续参考。

背景

在实际项目中经常遇到子串查找或者匹配的问题。即查找子串test_sub在原始文本test_str中的索引位置。进行直接给出各方案的评测对比。

各方案对比

各种常见的子串匹配方案如下:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2023/6/18 16:23
# @Author  : JasonLiu
# @File    : test_match_index.py


import pdb
from functools import reduce
from timeit import timeit
import re
import time


def find_index_startswith(test_str, test_sub):
    # using list comprehension + startswith()
    # All occurrences of substring in string
    res = [i for i in range(len(test_str)) if test_str.startswith(test_sub, i)]
    return res


def find_index_finditer(test_str, test_sub):
    res = [i.start() for i in re.finditer(test_sub, test_str)]
    return res


def find_index_replace(test_str, test_sub):
    res = []
    while (test_str.find(test_sub) != -1):
        res.append(test_str.find(test_sub))
        test_str = test_str.replace(test_sub, "*" * len(test_sub), 1)
    return res


# 最快
def find_substring_indices(string, substring):
    # Initialize an empty list to store the start indices of the substrings
    indices = []
    # Start searching for the substring from the beginning of the string
    start_index = 0
    # Continue searching until the substring is not found in the remaining part of the string
    while True:
        # Find the next occurrence of the substring starting from the current start_index
        index = string.find(substring, start_index)
        if index == -1:
            # If the substring is not found, break out of the loop
            break
        else:
            # If the substring is found, add its start index to the list of indices
            indices.append(index)
            # Update the start index to start searching for the next occurrence of the substring
            start_index = index + 1
    # Return the list of indices
    return indices


res = find_substring_indices("我是卖核弹的小男孩", "核弹")
# pdb.set_trace()


def find_all_substrings(string, substring):
    # Initialize an empty list to store the indices of all occurrences of the substring.
    indices = []
    # Set the starting index i to 0.
    i = 0
    # Use a while loop to keep searching for the substring in the string.
    while i < len(string):
        # Use the find() method to find the first occurrence of the substring in the string, starting from the current index i.
        j = string.find(substring, i)
        # If find() returns -1, it means that there are no more occurrences of the substring in the string, so break out of the loop.
        if j == -1:
            break
        # If find() returns a non-negative value, append the index of the first character of the substring to the list,
        # and update the starting index i to the next character after the end of the substring.
        indices.append(j)
        i = j + len(substring)
    # Return the list of indices.
    return indices


def find_index_finditer_reduce(test_str, test_sub):
    # using re.finditer() to find all occurrences of substring in string
    occurrences = re.finditer(test_sub, test_str)
    # using reduce() to get start indices of all occurrences
    res = reduce(lambda x, y: x + [y.start()], occurrences, [])
    return res


def find(raw_string, short_text):
    if raw_string.find(short_text) > -1:
        pass


def re_find(raw_string, short_text):
    if re.match(short_text, raw_string):
        pass


# 最快
def best_find(raw_string, short_text):
    if short_text in raw_string:
        pass


# number: stmt执行的次数,默认是1000000,100万
# print(timeit("find(string, text)", "from __main__ import find; string='lookforme'; text='look'"))
# print(timeit("re_find(string, text)", "from __main__ import re_find; string='lookforme'; text='look'"))
# print(timeit("best_find(string, text)", "from __main__ import best_find; string='lookforme'; text='look'"))

print(timeit("find_index_startswith(string, text)",
             "from __main__ import find_index_startswith; string='我是卖核弹的小男孩'; text='小男孩'"))
print(timeit("find_index_finditer(string, text)",
             "from __main__ import find_index_finditer; string='我是卖核弹的小男孩'; text='小男孩'"))
print(timeit("find_index_replace(string, text)",
             "from __main__ import find_index_replace; string='我是卖核弹的小男孩'; text='小男孩'"))
print(timeit("find_substring_indices(string, text)",
             "from __main__ import find_substring_indices; string='我是卖核弹的小男孩'; text='小男孩'"))
print(timeit("find_all_substrings(string, text)",
             "from __main__ import find_all_substrings; string='我是卖核弹的小男孩'; text='小男孩'"))
print(timeit("find_index_finditer_reduce(string, text)",
             "from __main__ import find_index_finditer_reduce; string='我是卖核弹的小男孩'; text='小男孩'"))

start_time = time.time()
find_substring_indices("我是卖核弹的小男孩", "小男孩")
end_time = time.time()
print("find_substring_indices cost=", end_time - start_time)

start_time = time.time()
res = find_all_substrings("我是卖核弹的小男孩", "小男孩")
print("res=", res)
end_time = time.time()
print("find_all_substrings cost=", end_time - start_time)

运行结果如下:

1.2356753833591938
0.8407432101666927
0.5224904119968414
0.29449306428432465
0.2958533354103565
1.0457346253097057
find_substring_indices cost= 2.86102294921875e-06
res= [6]
find_all_substrings cost= 6.9141387939453125e-06

可以看出find_substring_indicesfind_all_substrings这两种方式查找最快。

相关文章
|
8月前
|
监控 数据可视化 数据挖掘
Python Rich库使用指南:打造更美观的命令行应用
Rich库是Python的终端美化利器,支持彩色文本、智能表格、动态进度条和语法高亮,大幅提升命令行应用的可视化效果与用户体验。
714 0
|
11月前
|
机器学习/深度学习 数据采集 算法
Python AutoML框架选型攻略:7个工具性能对比与应用指南
本文系统介绍了主流Python AutoML库的技术特点与适用场景,涵盖AutoGluon、PyCaret、TPOT、Auto-sklearn、H2O AutoML及AutoKeras等工具,帮助开发者根据项目需求高效选择自动化机器学习方案。
1240 1
|
9月前
|
数据采集 监控 Java
Python 函数式编程的执行效率:实际应用中的权衡
Python 函数式编程的执行效率:实际应用中的权衡
380 102
|
10月前
|
存储 数据可视化 BI
Python可视化应用——学生成绩分布柱状图展示
本程序使用Python读取Excel中的学生成绩数据,统计各分数段人数,并通过Matplotlib库绘制柱状图展示成绩分布。同时计算最高分、最低分及平均分,实现成绩可视化分析。
745 0
|
机器学习/深度学习 数据可视化 算法
Python数值方法在工程和科学问题解决中的应用
本文探讨了Python数值方法在工程和科学领域的广泛应用。首先介绍了数值计算的基本概念及Python的优势,如易学易用、丰富的库支持和跨平台性。接着分析了Python在有限元分析、信号处理、优化问题求解和控制系统设计等工程问题中的应用,以及在数据分析、机器学习、模拟建模和深度学习等科学问题中的实践。通过具体案例,展示了Python解决实际问题的能力,最后总结展望了Python在未来工程和科学研究中的发展潜力。
374 0
|
8月前
|
机器学习/深度学习 算法 安全
【强化学习应用(八)】基于Q-learning的无人机物流路径规划研究(Python代码实现)
【强化学习应用(八)】基于Q-learning的无人机物流路径规划研究(Python代码实现)
594 6
|
8月前
|
设计模式 缓存 运维
Python装饰器实战场景解析:从原理到应用的10个经典案例
Python装饰器是函数式编程的精华,通过10个实战场景,从日志记录、权限验证到插件系统,全面解析其应用。掌握装饰器,让代码更优雅、灵活,提升开发效率。
562 0
|
9月前
|
数据采集 存储 数据可视化
Python网络爬虫在环境保护中的应用:污染源监测数据抓取与分析
在环保领域,数据是决策基础,但分散在多个平台,获取困难。Python网络爬虫技术灵活高效,可自动化抓取空气质量、水质、污染源等数据,实现多平台整合、实时更新、结构化存储与异常预警。本文详解爬虫实战应用,涵盖技术选型、代码实现、反爬策略与数据分析,助力环保数据高效利用。
462 0
|
10月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
601 1
|
9月前
|
存储 程序员 数据处理
Python列表基础操作全解析:从创建到灵活应用
本文深入浅出地讲解了Python列表的各类操作,从创建、增删改查到遍历与性能优化,内容详实且贴近实战,适合初学者快速掌握这一核心数据结构。
685 0

推荐镜像

更多