6

How does Python checks if a given value exists in an iterable using in keyword. Does it perform a linear search? Like :

def naive(iterable, val):
    for i in range(len(l)):
        if iterable[i]==val:
            return True
    return False

? Or it has got a different way of doing that. Other than linear search?

ShuklaSannidhya
  • 8,572
  • 9
  • 32
  • 45

3 Answers3

17

Python's in operator calls the __contains__ magic function on the container. That is implemented in different ways for different containers.

For strings, lists and tuples, it's a linear search (O(N)), though since it's implemented in C it will probably be faster than the pure-python one you have in your question.

For a sets and dicts, it's a hash-table lookup, which is much faster (O(1) average case).

Other containers will have different performance characteristics. I don't think there are any in the standard library, but a balanced tree data structure would probably be O(log N).

Blckknght
  • 100,903
  • 11
  • 120
  • 169
  • 1
    +1 for mentioning the possibility of a balanced tree implementing log-time `__contains__`. It's also worth mentioning that it falls back to a linear search if there *isn't* an `__contains__` and that this uses the iterator protocol - meaning, among other things, it works for generators, too. – lvc Mar 11 '13 at 05:02
8

The in keyword depends on the implementation of the __contains__ method in the object's class you are calling. That means for anything that isn't hashable (list, string) it performs a linear search but for a hashable data structures (dict, set) it would be amortized constant time.

Jared
  • 25,627
  • 7
  • 56
  • 61
3

If it's a linear data structure yes, it's a linear search. Examples: a list, a string. If it's a set it's an O(1) operation, or if we're checking if a key is in a dict is also O(1).

Óscar López
  • 232,561
  • 37
  • 312
  • 386