Python
string manipulation
in operator
algorithm
time complexity

Python string 'in' operator implementation algorithm and time complexity

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

The Python `in` operator is a powerful and expressive tool primarily used to determine membership. When applied to strings, it checks if a substring is present within another string. Intuitively, the syntactic simplicity of `in` hides a complex mechanism under the hood that efficiently performs this task. This article delves into the implementation, algorithmic nuances, and time complexity considerations of the `in` operator for strings.

Implementation Algorithm

Underneath the surface, Python strings are immutable sequences of characters. The `in` operator leverages the fact that a string is a sequence to perform a series of comparisons. The core of this operation can be thought of as a simplified search problem, where the aim is to locate an instance of a substring within a larger string.

The Algorithm

The essence of the `in` operation on strings is akin to the string-matching algorithms:

  1. Naive Approach: The simplest way is to use a nested loop mechanism where the outer loop iterates through each character of the given string while the inner loop checks if the substring starting at that character matches the search string. Although straightforward, this results in a time complexity of O(nm)O(n \cdot m), where nn is the length of the source string and mm is the length of the substring.
  2. Efficient Search Algorithms: In practice, Python's `in` operator takes a more sophisticated approach, leveraging algorithms like the Boyer-Moore-Horspool algorithm, which optimizes search performance by skipping sections of the text. The algorithm preprocesses the needle (substring) to create a table of shifts for mismatches. This method often provides a practical time complexity closer to O(n+m)O(n + m).

Example

To illustrate the `in` operator in use:

  • Best Case: O(m)O(m), when the substring is found immediately at the beginning.
  • Average Case: O(n+m)O(n + m), using Boyd-Moore-Horspool or similar optimizations.
  • Worst Case: Still O(nm)O(n \cdot m), but rare due to the nature of optimized searching operations.
  • Empty Substring: Python will always return `True` when checking for an empty substring as every string contains the empty substring.
  • String Lengths: Performance may vary with very short or very long strings due to caching behavior and lower-level optimizations.
  • Boyer-Moore-Horspool Algorithm: Link

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.