Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please refer to our video player troubleshooting guide for assistance.

Avoid Using .find() to Check for Substrings

00:00 In the previous lesson, I showed you that you can use text_lower.index() to get the index position of the first occurrence of the substring.

00:10 This is where it starts. And there is a second string method called .find() that does basically the same. So if you use .find() and then pass it "secret", you will get the same result, 59.

00:25 This is where the first occurrence of the substring starts. But this has a name that is sometimes a little misleading for Python programmers because .find() seems like a good way to find a string in Python, right? And I would argue that it is quite descriptively named.

00:42 You want to find where is the string, and if you think of it like that, then .find() also makes sense. It gives you the index position, right?

00:50 I prefer to use .index() because I have the feeling it’s a little more descriptive of what do both of these methods actually return because they return the index positions. Now there’s a difference between them, which is how they handle if they do not find the substring.

01:06 So if I say text_lower.index() and pass it a substring that’s not in there—let’s say "treasure"

01:15 then .index() gives a ValueError and just tells me that the substring isn’t found. So, in my opinion, it’s quite descriptive and understandable. If I do the same with .find(),

01:29 it does not throw an error but instead it returns the value—no, well that was the wrong string.

01:38 Instead it returns the value -1, and this -1 in the context of .find(), it means the substring is not in the string, but it’s not really very descriptive in my opinion.

01:52 I’d rather have a ValueError thrown that tells me this is not in there than have -1. And the reason for that is that you’ll see people finding the .find() string method and using it for finding a substring in a string, and then they start writing code, a conditional where they say if text_lower.find(), let’s say "treasure",

02:18 != -1: then print("found it"), right, and else maybe print something like

02:31 "substring not in string". Of course, your conditions would probably do something else in here. That’s where you write your code logic. But what I want to show you here is that if you opt for using .find() in order to check for the substring in the string, then you come up with some kind of hard-to-read code constructs because in order to correctly interpret this if you’re reading code, you need to know that .find() returns -1 if it doesn’t find a substring, and that’s not entirely intuitive.

03:04 It works because we know that .find() returns -1 if it’s not found, we know "treasure" is not in that string, so this whole expression is going to evaluate to False, and because of that, you’re going to print out that the substring is not in the string.

03:20 But if you think back to how we did that initially, which is saying "treasure" in text_lower, this is much shorter and more concise, and also the output makes a lot of sense.

03:35 So in this case you’re just saying is it in there, and Python returns False, which means you can write your conditional statement like so. You can say iflet me just copy that—if "treasure" in text_lower: print("found it")

03:53 and else

03:56 I want to print("substring not in string") just to remake the same structure as before. So in this case, the first line of this code is a lot easier to interpret if you use the in operator than if you use .find() and then compare to the -1 return value. Okay, so this is just a little aside as to why you shouldn’t use .find() or, for that matter, .index() or .count() or any of these other string methods that you could massage in order to still basically perform a substrings check.

04:29 Well, you shouldn’t be using that, and instead just stick with using the in operator, which is the most readable way of checking for a substring in a string.

04:42 That said, all of these string methods still have their use cases. If you want to know how often is the substring in the string, you can use str.count(). If you want to know where is the substring located, then you can use str.index(), and you could also use str.find() for that same purpose, and that just depends on whether you want to handle an error or whether you want to deal with the return value of -1. And which of those two you wanted to use might really depend on your use case.

05:12 All of these string methods are useful if you want to learn more about the substring, and that’s what you should use them for.

Become a Member to join the conversation.