Python3快速查找集合中是否有任何元素是字符串的子串

标签 python algorithm python-3.x big-o string-algorithm

如果我有一个字符串集合,是否有数据结构或函数可以提高检查集合中的任何元素是否是我的子字符串的速度主弦?

现在我正在遍历我的字符串数组并使用 in 运算符。有没有更快的方法?

import timing

## string match in first do_not_scan
## 0:00:00.029332

## string not in do_not_scan
## 0:00:00.035179
def check_if_substring():
    for x in do_not_scan:
        if x in string:
            return True
    return False

## string match in first do_not_scan
## 0:00:00.046530

## string not in do_not_scan
## 0:00:00.067439
def index_of():
    for x in do_not_scan:
        try:
            string.index(x)
            return True
        except:
            return False

## string match in first do_not_scan
## 0:00:00.047654

## string not in do_not_scan
## 0:00:00.070596
def find_def():
    for x in do_not_scan:
        if string.find(x) != -1:
            return True
    return False

string = '/usr/documents/apps/components/login'
do_not_scan = ['node_modules','bower_components']

for x in range(100000):
    find_def()
    index_of()
    check_if_substring()

最佳答案

不,没有更快的内置方法。

如果您要测试大量字符串,那么最好使用第三方 Aho-Corasick包,作为J.F. Sebastian's answer显示。


使用内置方法,最坏的情况是:没有匹配项,这意味着您已经测试了列表中的每个项目以及几乎每个项目中的每个偏移量。

幸运的是,in 运算符非常快(至少在 CPython 中),在我的测试中快了将近三倍:

0.3364804992452264  # substring()
0.867534976452589   # any_substring()
0.8401796016842127  # find_def()
0.9342398950830102  # index_of()
2.7920695478096604  # re implementation

这是我用来测试的脚本:

from timeit import timeit
import re

def substring():
    for x in do_not_scan:
        if x in string:
            return True
    return False

def any_substring():
    return any(x in string for x in do_not_scan)

def find_def():
    for x in do_not_scan:
        if string.find(x) != -1:
            return True
    return False

def index_of():
    for x in do_not_scan:
        try:
            string.index(x)
            return True
        except:
            return False

def re_match():
    for x in do_not_scan:
        if re.search(string, x):
            return True
    return False

string = 'a'
do_not_scan = ['node_modules','bower_components']

print(timeit('substring()', setup='from __main__ import substring'))
print(timeit('any_substring()', setup='from __main__ import any_substring'))
print(timeit('find_def()', setup='from __main__ import find_def'))
print(timeit('index_of()', setup='from __main__ import index_of'))
print(timeit('re_match()', setup='from __main__ import re_match'))

关于Python3快速查找集合中是否有任何元素是字符串的子串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35803016/

相关文章:

python - 如何不计算用户输入的重复项?

Python 安装工具 : package directory does not exist

python - isinstance 文件 python 2.7 和 3.5

python - Keras 模型中的权重和变量有什​​么区别?

python - 在渲染模板中将变量从 python (flask) 传递到 HTML?

algorithm - 如何比较两条路径

python-3.x - 将 avro 文件的目录从 HDFS 读取到 python 中的类似数据框的对象中

Python Scrapy 函数调用

基于多个可能的匹配匹配人的算法

c++ - 对 std::multiset 中的相等范围进行排序