比较 Python 中两种子字符串搜索方法的效率

38 浏览
0 Comments

比较 Python 中两种子字符串搜索方法的效率

在搜索 Python 中的子字符串搜索主题 (link1, link2) 后,我发现了两个明显的解决方案。

str1 = 'Hi there'
str2 = 'Good bye'
# 1
if str1.find('Hi') != -1: 
    print 'Success!'
# 2
if 'Good' in str2:
    print 'Success'

  • 这两个方案生成的代码有什么区别,还是第二个只是语法糖?
  • 哪个更有效率?
  • 还有第三个选项吗?
admin 更改状态以发布 2023年5月21日
0
0 Comments

第二个不仅仅是第一个的语法糖。 str.find 只是一个方法调用,而 a in b 调用了 a.__contains__(b)。我认为它们在速度上没有任何区别。

我建议使用第二个,因为它更符合 Python 的风格:

它更易读。
它使用了鸭子类型。字符串可以被替换为不同的可迭代对象,它仍然可以工作。

0
0 Comments

您可以检查这些条件的字节码是什么样子:

In [1]: import dis
In [2]: dis.dis(lambda: 'Hi' in x)
  1           0 LOAD_CONST               1 ('Hi') 
              3 LOAD_GLOBAL              0 (x) 
              6 COMPARE_OP               6 (in) 
              9 RETURN_VALUE         
In [3]: dis.dis(lambda: x.find('Hi') != -1)
  1           0 LOAD_GLOBAL              0 (x) 
              3 LOAD_ATTR                1 (find) 
              6 LOAD_CONST               1 ('Hi') 
              9 CALL_FUNCTION            1 (1 positional, 0 keyword pair) 
             12 LOAD_CONST               3 (-1) 
             15 COMPARE_OP               3 (!=) 
             18 RETURN_VALUE         

可以看到,find 版本执行了更多的操作,特别是进行了一个属性查找,而这在 in 运算符中是不需要的。

我必须说,in 更明确地表明您正在检查子字符串的存在而不是其位置,因此更易读。

就速度而言,在任何合理大小的字符串上,它们应该是完全相等的。只有对于最小的字符串,属性查找会产生显着影响,但在这种情况下,条件仍然被快速检查。

第三个选项是使用 index 并捕获异常:

try:
    string.index(substring)
except IndexError:
    # not found
else:
    # found

尽管这不能表示为一个简单的表达式。

0