Search code examples
pythonsubstringends-with

Differences between using python endswith and substring


I've come across a situation where two solutions are proposed.

Let's say I have a string, "foo bar" as an input and I need to check that it ends in "bar".

One person's solution is this:

is_bar = lambda x: x[-3:] == "bar"

The other person's solution is this:

is_bar = lambda x: x.endswith("bar")

Can anyone provide insight into the differences between the two and which is preferred? Assume only the one suffix "bar" is ever preferred, as endswith can have tuples of suffixes and would be preferred if there were more.


Solution

  • endswith is more efficient, as it doesn't cost extra space (other than what both string comparisons use internally) and can stop at the first unequal character. And you don't need to provide the length. And it's probably clearer to people less used to slice notation. And also clearer and less error-prone than for example x[-31:] == "toolongtoimmediatelyseethelength".

    The slice takes extra space, gets fully created before even the first character is compared, and you need to provide the length. But it's better when you're playing code golf.

    In case the potential end string isn't hardcoded, the slice comparison even has a subtle bug. While x[-1:] gets you the suffix of length 1, x[-0:] does not give you the suffix of length 0 but the entire string. So x[-len(s):] == s fails when s is empty but x is not, where it becomes x[0:] == '' and results in False. The correct result is trivially True, and x.endswith(s) gets it. I also just used that in another answer where I don't need a special case for no-overlap cases but an answer comparing slices does.