简体   繁体   English

str.endswith()/startswith() 的开始/结束参数的目的是什么?

[英]What's the purpose of start/end parameters to str.endswith()/startswith()?

I don't seem to understand how I should use start / end parameters to str.startswith() and str.endswith() .我似乎不明白我应该如何将start / end参数用于str.startswith()str.endswith() Is there a simple rule I can follow?有我可以遵循的简单规则吗?

Also, is there any benefit to using these functions compared to using string slices?另外,与使用字符串切片相比,使用这些函数有什么好处吗?

strg = "abcdefghi"

print(strg.endswith("ghi")) # True
print(strg.endswith("def", 1, 6)) # True

the last statement is the same as最后一条语句与

print(strg[1:6].endswith("def")  # True

except that it will not create a fresh string (which the slice strg[1:6] = "bcdef" does).除了它不会创建一个新的字符串(切片strg[1:6] = "bcdef" )。

startswith/endwith have the purpose of finding some substring at the beginning or at the end of some string. startswith/endwith 的目的是在某个字符串的开头或结尾找到某个子字符串。

The start and end parameters have the purpose of 'sliding' the window where you may find the substring.开始和结束参数的目的是“滑动”可以找到子字符串的窗口。 Works as parameters so the startswith/endswith can be applied to find any substring in any specific position.用作参数,因此可以应用开始/结束与查找任何特定位置的任何子字符串。

I think that str.startswith() and str.endswith() with their mentioned parameters start and end are there to increase readability in the code and to take out complexity that you get by slicing.我认为str.startswith()str.endswith()以及它们提到的参数startend可以提高代码的可读性并消除切片带来的复杂性。

text = "afoobarstring"
part_to_check = "bar"
position = 4

# approach 1 (startswith)
text.startswith(part_to_check, position)

# approach 2 (slicing)
text[position:position + len(part_to_check)] == part_to_check

# approach 3 (startswith and slicing)
text[position:].startswith(part_to_check)

While the three approaches do roughly the same thing, the approach 1 is simply easier to read and understand as the other approaches (imho).虽然这三种方法做的事情大致相同,但方法 1 比其他方法更容易阅读和理解(恕我直言)。 In approach 2 you also have to compute the end position of the string, and in approach 3 you have a copy of the string (as in approach 2) and the same function call as in approach 1 in addition.在方法 2 中,您还必须计算字符串的结束位置,在方法 3 中,您有一个字符串的副本(如方法 2)和与方法 1 中相同的函数调用。

I suspect that this leads also to better results regarding the time measurements:我怀疑这也会导致关于时间测量的更好结果:

In [1]: import timeit                                                           

In [2]: timeit.timeit('text="afoobarstring"; part_to_check = "bar"; position = 4; text.startswith(part_to_check, position)', number=10000000)                                        
Out[2]: 1.6531553190034174

In [3]: timeit.timeit('text="afoobarstring"; part_to_check = "bar"; position = 4; text[position:position + len(part_to_check)] == part_to_check', number=10000000)                   
Out[3]: 1.8180583719986316

In [4]: timeit.timeit('text="afoobarstring"; part_to_check = "bar"; position = 4; text[position:].startswith(part_to_check)', number=10000000)
Out[4]: 2.349334787999396

And also I think that approach 1 is much cleaner, also under the hood:而且我认为方法 1 更干净,也在引擎盖下:

In [1]: import dis                                                              

In [2]: def startswith(): 
   ...:     text="afoobarstring" 
   ...:     part_to_check = "bar" 
   ...:     position = 4 
   ...:     return text.startswith(part_to_check, position) 
   ...:                                                                         

In [3]: def slicing(): 
   ...:     text="afoobarstring" 
   ...:     part_to_check = "bar" 
   ...:     position = 4 
   ...:     return text[position:position + len(part_to_check)] == part_to_check 
   ...:                                                                                                      

In [4]: def slicing_and_startswith(): 
   ...:     text="afoobarstring" 
   ...:     part_to_check = "bar" 
   ...:     position = 4 
   ...:     return text[position:].startswith(part_to_check) 
   ...:                                                                                                      

In [5]: dis.dis(startswith)                                                                                  
  2           0 LOAD_CONST               1 ('afoobarstring')
              3 STORE_FAST               0 (text)

  3           6 LOAD_CONST               2 ('bar')
              9 STORE_FAST               1 (part_to_check)

  4          12 LOAD_CONST               3 (4)
             15 STORE_FAST               2 (position)

  5          18 LOAD_FAST                0 (text)
             21 LOAD_ATTR                0 (startswith)
             24 LOAD_FAST                1 (part_to_check)
             27 LOAD_FAST                2 (position)
             30 CALL_FUNCTION            2 (2 positional, 0 keyword pair)
             33 RETURN_VALUE

In [6]: dis.dis(slicing)                                                                                     
  2           0 LOAD_CONST               1 ('afoobarstring')
              3 STORE_FAST               0 (text)

  3           6 LOAD_CONST               2 ('bar')
              9 STORE_FAST               1 (part_to_check)

  4          12 LOAD_CONST               3 (4)
             15 STORE_FAST               2 (position)

  5          18 LOAD_FAST                0 (text)
             21 LOAD_FAST                2 (position)
             24 LOAD_FAST                2 (position)
             27 LOAD_GLOBAL              0 (len)
             30 LOAD_FAST                1 (part_to_check)
             33 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             36 BINARY_ADD
             37 BUILD_SLICE              2
             40 BINARY_SUBSCR
             41 LOAD_FAST                1 (part_to_check)
             44 COMPARE_OP               2 (==)
             47 RETURN_VALUE

In [7]: dis.dis(slicing_and_startswith)                                                                      
  2           0 LOAD_CONST               1 ('afoobarstring')
              3 STORE_FAST               0 (text)

  3           6 LOAD_CONST               2 ('bar')
              9 STORE_FAST               1 (part_to_check)

  4          12 LOAD_CONST               3 (4)
             15 STORE_FAST               2 (position)

  5          18 LOAD_FAST                0 (text)
             21 LOAD_FAST                2 (position)
             24 LOAD_CONST               0 (None)
             27 BUILD_SLICE              2
             30 BINARY_SUBSCR
             31 LOAD_ATTR                0 (startswith)
             34 LOAD_FAST                1 (part_to_check)
             37 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             40 RETURN_VALUE

I think it is similar with the endswith() -method.我认为它与endswith()方法类似。 That's why I didn't show this one separately.这就是为什么我没有单独展示这个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM