By Blankman


2010-08-09 02:52:50 8 Comments

I'm looking for a string.contains or string.indexof method in Python.

I want to do:

if not somestring.contains("blah"):
   continue

17 comments

@Brandon Bailey 2019-02-06 11:06:27

You can use a few methods :

  1. if x in y:
  2. y.count()
  3. y.find()

1 is a Boolean expression, meaning it will return either a state True of False dependent on if the condition is met or not.

E.g:

string = "Hello world"

if "Hello" in string: >>True
if "Python" in string: >>False

2 will return the integer value of the number of times a sub string appears in a string.

E.g:

string.count("bah") >> 0
string.count("Hello") >> 1

3 will return the index value of the given sub strings initial position. This will also return -1 if no sub string can be found.

E.g:

string.find("Hello")  >>0
string.find("foo")  >>-1

@ARGeo 2018-12-25 15:35:03

There are four simplest ways to find out what substring is and where substring begins.

The first one is via the Python’s in operator:

someString = "Polly is drinking Coca-Cola."

"Coca-Cola" in someString
# Result: True

"Pepsi" in someString
# Result: False

Second way is to use the string’s find() method.

Unlike the in operator which is evaluated to a boolean value, the find method returns an integer. This integer is the index of the beginning of a substring if this substring exists, otherwise -1 is returned. Here's how it works:

someString = "Polly is drinking Coca-Cola."

someString.find("is")
# Result: 6

someString.find("Pepsi")
# Result: -1

someString.find("Polly")
# Result: 0

You can also specify start and end indices to limit your search. For instance:

someString = "Polly is drinking Coca-Cola."

someString.find("is", 5, 10)
# Result: 6

someString.find("Polly", 15, 20)
# Result: -1

Third. And, of course, you can use if...is not statement (it works in Python 2.7 and 3.6):

someString = "Polly is drinking Coca-Cola."
substring = "drinking"

if someString.find(substring) is not -1:
    print("Cool! Python found the desired substring!")
else:
    print("Python didn't find the desired substring!")

# Result: "Cool! Python found the desired substring!"

Four. Use the index() method. It's almost the same as the find() method.

someString = "Polly is drinking Coca-Cola."
x = someString.index("drinking")
print(x)

# Result: 9

Hope this helps.

@Muskovets 2018-11-23 07:15:14

As previously said, you can use the in operator like this:

>>> to_search_in = "String to search in"
>>> to_search = "search"
>>> print(to_search in to_search_in)
True
>>> print(to_search_in.find(to_search))
10

Also you can use regular expressions to get the occurrences:

>>> import re
>>> print(re.findall(r'( |t)', to_search_in)) # searches for t or space
['t', ' ', 't', ' ', ' ']

@Fipsi 2018-06-16 12:02:01

I see there are already answers, but I want to add my two cents as well.

In Python there are functions to do this, but the most simple (and mostly preferred) method is to use the keyword in:

"test" in "testtext"
True

"abc" in "abcdefg"
True

"abc" in "Abc"
False

"ABC" in "abc"
False

"abc" in "def"
False

"abc" in ["abc", "def", "ghi"]
True

There are some string methods as well:

"xxabcxx".find("abc")
2 # Returns the index of the first match

"xxabcxx".find("cde")
-1 # Returns -1 if the substring 
# could not be found in the string

# And:

"xxabcxx".index("abc")
2

"xxabcxx".index("cde")
ValueError: substring not found
#raises ValueError...

About performance:

In general in is the fastest method to find a substring...

find is slightly faster than index.

@Rahul Gupta 2015-05-26 17:46:13

Basically, you want to find a substring in a string in Python. There are two ways to search for a substring in a string in Python.

Method 1: in operator

You can use the Python's in operator to check for a substring. It's quite simple and intuitive. It will return True if the substring was found in the string else False.

>>> "King" in "King's landing"
True

>>> "Jon Snow" in "King's landing"
False

Method 2: str.find() method

The second method is to use the str.find() method. Here, we call the .find() method on the string in which substring is to found. We pass the substring to the find() method and check its return value. If its value is other than -1, the substring was found in the string, otherwise not. The value returned is the index where substring was found.

>>> some_string = "valar morghulis"

>>> some_string.find("morghulis")
6

>>> some_string.find("dohaeris")
-1

I would recommend you to use the first method as it is more Pythonic and intuitive.

@Ashish Anand 2019-04-14 14:39:51

lol...hats off to example. John Snow in king's landing.

@Jamie Bull 2018-01-13 15:32:36

If you're looking for case-insensitive search for whole words, rather than a substring contained within another word:

import string

s = 'This is my text example'
if 'is' not in (word.lower() 
    for split_char in string.punctuation + string.whitespace 
    for word in s.split(split_char)):
    # do something

@thomie 2018-04-14 16:33:05

split takes a single separator, rather than a list of separators.

@wowserx 2018-11-13 01:36:21

Case-insensitive string comparison should use .casefold(), not .lower().

@Kundor 2018-11-14 04:31:20

This doesn't actually work; change s to 'This is,my test example'. It's not splitting on all the split_chars at once—just on one at a time (so when it gets to the comma, it considers the two words 'This is' and 'my test example'.) Elsewhere you suggested using translate to turn them all to spaces, which should work.

@ytpillai 2015-05-25 22:50:59

Here is your answer:

if "insert_char_or_string_here" in "insert_string_to_search_here":
    #DOSTUFF

For checking if it is false:

if not "insert_char_or_string_here" in "insert_string_to_search_here":
    #DOSTUFF

OR:

if "insert_char_or_string_here" not in "insert_string_to_search_here":
    #DOSTUFF

@Jeffrey04 2018-03-28 09:59:15

If you are happy with "blah" in somestring but want it to be a function call, you can probably do this

import operator

if not operator.contains(somestring, "blah"):
    continue

All operators in Python can be more or less found in the operator module including in.

@Aaron Hall 2014-11-25 22:33:48

Does Python have a string contains substring method?

Yes, but Python has a comparison operator that you should use instead, because the language intends its usage, and other programmers will expect you to use it. That keyword is in, which is used as a comparison operator:

>>> 'foo' in '**foo**'
True

The opposite (complement), which the original question asks for, is not in:

>>> 'foo' not in '**foo**' # returns False
False

This is semantically the same as not 'foo' in '**foo**' but it's much more readable and explicitly provided for in the language as a readability improvement.

Avoid using __contains__, find, and index

As promised, here's the contains method:

str.__contains__('**foo**', 'foo')

returns True. You could also call this function from the instance of the superstring:

'**foo**'.__contains__('foo')

But don't. Methods that start with underscores are considered semantically private. The only reason to use this is when extending the in and not in functionality (e.g. if subclassing str):

class NoisyString(str):
    def __contains__(self, other):
        print('testing if "{0}" in "{1}"'.format(other, self))
        return super(NoisyString, self).__contains__(other)

ns = NoisyString('a string with a substring inside')

and now:

>>> 'substring' in ns
testing if "substring" in "a string with a substring inside"
True

Also, avoid the following string methods:

>>> '**foo**'.index('foo')
2
>>> '**foo**'.find('foo')
2

>>> '**oo**'.find('foo')
-1
>>> '**oo**'.index('foo')

Traceback (most recent call last):
  File "<pyshell#40>", line 1, in <module>
    '**oo**'.index('foo')
ValueError: substring not found

Other languages may have no methods to directly test for substrings, and so you would have to use these types of methods, but with Python, it is much more efficient to use the in comparison operator.

Performance comparisons

We can compare various ways of accomplishing the same goal.

import timeit

def in_(s, other):
    return other in s

def contains(s, other):
    return s.__contains__(other)

def find(s, other):
    return s.find(other) != -1

def index(s, other):
    try:
        s.index(other)
    except ValueError:
        return False
    else:
        return True



perf_dict = {
'in:True': min(timeit.repeat(lambda: in_('superstring', 'str'))),
'in:False': min(timeit.repeat(lambda: in_('superstring', 'not'))),
'__contains__:True': min(timeit.repeat(lambda: contains('superstring', 'str'))),
'__contains__:False': min(timeit.repeat(lambda: contains('superstring', 'not'))),
'find:True': min(timeit.repeat(lambda: find('superstring', 'str'))),
'find:False': min(timeit.repeat(lambda: find('superstring', 'not'))),
'index:True': min(timeit.repeat(lambda: index('superstring', 'str'))),
'index:False': min(timeit.repeat(lambda: index('superstring', 'not'))),
}

And now we see that using in is much faster than the others. Less time to do an equivalent operation is better:

>>> perf_dict
{'in:True': 0.16450627865128808,
 'in:False': 0.1609668098178645,
 '__contains__:True': 0.24355481654697542,
 '__contains__:False': 0.24382793854783813,
 'find:True': 0.3067379407923454,
 'find:False': 0.29860888058124146,
 'index:True': 0.29647137792585454,
 'index:False': 0.5502287584545229}

@coderforlife 2015-06-10 03:35:42

Why should one avoid str.index and str.find? How else would you suggest someone find the index of a substring instead of just whether it exists or not? (or did you mean avoid using them in place of contains - so don't use s.find(ss) != -1 instead of ss in s?)

@Aaron Hall 2015-06-10 03:39:03

Precisely so, although the intent behind the use of those methods may be better addressed by elegant use of the re module. I have not yet found a use for str.index or str.find myself in any code I have written yet.

@Yishai E 2019-04-08 18:39:01

Kudos for the performance measurements, I was looking for that.

@firelynx 2017-04-28 18:52:16

in Python strings and lists

Here are a few useful examples that speak for themselves concerning the in method:

"foo" in "foobar"
True

"foo" in "Foobar"
False

"foo" in "Foobar".lower()
True

"foo".capitalize() in "Foobar"
True

"foo" in ["bar", "foo", "foobar"]
True

"foo" in ["fo", "o", "foobar"]
False

Caveat. Lists are iterables, and the in method acts on iterables, not just strings.

@CaffeinatedCoder 2017-06-09 18:41:24

Could the list iterable be switched around to look for any of the list in a single string? Ex: ["bar", "foo", "foobar"] in "foof"?

@firelynx 2017-06-09 19:36:09

@CaffeinatedCoder, no, this requires nested iteration. Best done by joining the list with pipes "|".join(["bar","foo", "foobar"]) and compiling a regex out of it, then matching on "foof"

@CaffeinatedCoder 2017-06-09 21:25:04

I figured out early that it could also be done with a generator, which allowed me to avoid regex. Thanks for an alternative though!

@Izaak Weiss 2017-08-28 22:00:22

any([x in "foof" for x in ["bar", "foo", "foobar"]])

@firelynx 2017-08-30 11:29:52

@IzaakWeiss Your one liner works, but it's not very readable, and it does nested iteration. I would advice against doing this

@Piyush S. Wanare 2017-10-13 16:54:22

Can you compare complexity of using regex with in operator?

@firelynx 2017-10-13 17:49:03

@PiyushS.Wanare what do you mean by complexity? The "WTF/min" is a lot higher with regex.

@Piyush S. Wanare 2017-10-13 17:51:35

@firelynx,was asking for the same can you please explain why complexity of regex is higher than in.

@firelynx 2017-10-13 17:57:46

@PiyushS.Wanare The regex syntax is unclear, so it produces more WTF/min. Even if you know it, it is not as clean as using in. Your code should be readable to others, not just to you. Also, using regex may mean you have to sanitise your inputs, which would be an extra step. There's a lot of good reasons not to use regex.

@cs95 2017-11-10 13:01:06

This has been answered in stackoverflow.com/a/3437070/4909087. Why did you repeat the answer?

@firelynx 2017-11-10 14:11:19

@cᴏʟᴅsᴘᴇᴇᴅ I'm adding to it by explaining more of the functionality of the in operator.

@cs95 2017-11-10 14:31:16

Aaron Hall’s answer did that pretty well I thought.

@firelynx 2017-11-10 14:54:18

@cᴏʟᴅsᴘᴇᴇᴅ For me it appears as a wall of text. Perhaps very explicit but not as practical as just providing more simple examples.

@Bohdan 2013-09-30 18:59:46

No, there isn't any string.contains(str) method, but there is the in operator:

if substring in someString:
    print "It's there!!!"

Here is a more complex working example:

# Print all files with dot in home directory
import commands
(st, output) = commands.getstatusoutput('ls -a ~')
print [f for f in output.split('\n') if '.' in f ]

@Joshua Detwiler 2018-06-19 15:51:25

Not a fan of parsing ls, but I get why you gave this example. Still...would've rather seen os.walk.

@Harish Reddy 2011-07-28 12:32:04

Another way to find whether a string contains a few characters or not with the Boolean return value (i.e. True or `False):

str1 = "This be a string"
find_this = "tr"
if find_this in str1:
    print find_this, " is been found in ", str1
else:
    print find_this, " is not found in ", str1

@Xavier Arias Botargues 2013-09-13 16:35:58

print already adds spaces between strings, but good example anyway.

@yeliabsalohcin 2017-10-17 09:22:28

To search against two strings, say find_that = "ng" why does this not work: if (find_this or find_that) in str1: print "I found find_this or find_that"

@K Richardson 2018-12-27 20:15:41

@yeliabsalohcin your code snippet will not produce the result you want, due to order of operations. (find_this or find_that) evaluates to find_this which is then tested by in str1

@eldarerathis 2010-08-09 02:55:04

If it's just a substring search you can use string.find("substring").

You do have to be a little careful with find, index, and in though, as they are substring searches. In other words, this:

s = "This be a string"
if s.find("is") == -1:
    print "No 'is' here!"
else:
    print "Found 'is' in the string."

It would print Found 'is' in the string. Similarly, if "is" in s: would evaluate to True. This may or may not be what you want.

@aaronasterling 2010-08-09 03:22:50

+1 for highlighting the gotchas involved in substring searches. the obvious solution is if ' is ' in s: which will return False as is (probably) expected.

@Bob 2012-11-08 00:07:37

@aaronasterling Obvious it may be, but not entirely correct. What if you have punctuation or it's at the start or end? What about capitalisation? Better would be a case insensitive regex search for \bis\b (word boundaries).

@Jamie Bull 2018-01-13 15:26:40

@bob Or if 'is' in (w.lower() for w in s.split())

@Bob 2018-01-13 15:46:41

@JamieBull Once again, you must consider if you want to include punctuation as a delimiter for a word. Splitting would have largely the same effect as the naive solution of checking for ' is ', notably, it won't catch This is, a comma' or 'It is.'.

@Jamie Bull 2018-01-13 15:50:14

Good point. It starts to get a bit unwieldy now, but 'is' not in (w.lower() for w in s.split(string.punctuation + string.whitespace)) is better

@ShadowRanger 2018-02-01 01:39:31

@JamieBull: I highly doubt any real input split with s.split(string.punctuation + string.whitespace) would split even once; split isn't like the strip/rstrip/lstrip family of functions, it only splits when it sees all of the delimiter characters, contiguously, in that exact order. If you want to split on character classes, you're back to regular expressions (at which point, searching for r'\bis\b' without splitting is the simpler, faster way to go).

@Jamie Bull 2018-02-01 11:52:02

'is' not in (w.lower() for w in s.translate(string.maketrans(' ' * len(string.punctuation + string.whitespace), string.punctuation + string.whitespace)).split() - ok, point taken. This is now ridiculous...

@Jamie Bull 2018-08-01 20:45:51

Although if anyone needs it, there's a working version here... stackoverflow.com/a/48241340/1706564

@Inconnu 2016-11-20 18:58:56

In Python there are two simple ways you can achieve this:

The Pythonic way: Using Python's 'in' Keyword-

in takes two "arguments", one on the left(substring) and one on the right, and returns True if the left argument is contained within the rightside argument and if not,it returns False.

example_string = "This is an example string"
substring = "example"
print(substring in example_string)

Output:

True

The non-Pythonic way: Using Python's str.find:

The find method returns the position of the string within the string or -1 if it's not found. But simply check if the position is not -1.

if example_string.find(substring) != -1:
    print('Substring found!')
else:
    print('Substring not found!')

Output:

Substring found!

@Corey Goldberg 2017-03-08 22:08:26

this just repeats previous answers

@Ufos 2015-07-17 13:19:36

So apparently there is nothing similar for vector-wise comparison. An obvious Python way to do so would be:

names = ['bob', 'john', 'mike']
any(st in 'bob and john' for st in names) 
>> True

any(st in 'mary and jane' for st in names) 
>> False

@Niriel 2015-08-10 09:50:07

That's because there is a bajillion ways of creating a Product from atomic variables. You can stuff them in a tuple, a list (which are forms of Cartesian Products and come with an implied order), or they can be named properties of a class (no a priori order) or dictionary values, or they can be files in a directory, or whatever. Whenever you can uniquely identify (iter or getitem) something in a 'container' or 'context', you can see that 'container' as a sort of vector and define binary ops on it. en.wikipedia.org/wiki/…

@mgc 2016-01-17 10:21:42

@Ufos i guess the more obvious python way to do this is to use any() or all(). Like : any([st in 'bob and john' for st in names]) >>> True

@Eamonn M.R. 2016-04-04 15:58:12

You don't need the inner square brackets in the any - python.org/dev/peps/pep-0289

@Michael Mrozek 2010-08-09 02:56:21

You can use the in operator:

if "blah" not in somestring: 
    continue

@BallpointBen 2018-08-17 07:02:56

Under the hood, Python will use __contains__(self, item), __iter__(self), and __getitem__(self, key) in that order to determine whether an item lies in a given contains. Implement at least one of those methods to make in available to your custom type.

@Nan Zhong 2018-10-10 22:44:36

Just make sure that somestring won't be None. Otherwise you get a TypeError: argument of type 'NoneType' is not iterable

@Trenton 2018-11-13 21:41:47

FWIW, this is the idiomatic way to accomplish said goal.

@Sam Chats 2018-12-18 20:23:24

For strings, does the Python in operator use the Rabin-Carp algorithm?

@Kaz 2019-02-12 20:24:22

This is inconsistent and ugly in code like ".so." in filename or filename.endswith(".blah").

@Kaz 2019-02-14 17:54:07

^ I meant filename.endswith(".so").

@Christoph Burschka 2019-02-28 15:34:20

@SamChats see stackoverflow.com/questions/18139660/… for the implementation details (in CPython; afaik the language specification does not mandate any particular algorithm here).

@Alex Martelli 2010-08-09 03:19:09

if needle in haystack: is the normal use, as @Michael says -- it relies on the in operator, more readable and faster than a method call.

If you truly need a method instead of an operator (e.g. to do some weird key= for a very peculiar sort...?), that would be 'haystack'.__contains__. But since your example is for use in an if, I guess you don't really mean what you say;-). It's not good form (nor readable, nor efficient) to use special methods directly -- they're meant to be used, instead, through the operators and builtins that delegate to them.

Related Questions

Sponsored Content

42 Answered Questions

[SOLVED] What does the "yield" keyword do?

13 Answered Questions

[SOLVED] How to substring a string in Python?

  • 2009-03-19 17:29:41
  • Joan Venge
  • 2444089 View
  • 1821 Score
  • 13 Answer
  • Tags:   python string

36 Answered Questions

[SOLVED] How do I check if a string contains a specific word?

3 Answered Questions

28 Answered Questions

44 Answered Questions

[SOLVED] How to merge two dictionaries in a single expression?

11 Answered Questions

[SOLVED] Static methods in Python?

24 Answered Questions

[SOLVED] Case insensitive 'Contains(string)'

22 Answered Questions

[SOLVED] How to check if a string contains a substring in Bash

  • 2008-10-23 12:37:31
  • davidsheldon
  • 1659504 View
  • 2050 Score
  • 22 Answer
  • Tags:   string bash substring

7 Answered Questions

[SOLVED] Understanding Python super() with __init__() methods

Sponsored Content