In Python, it is known that in checks for membership in iterators (lists, dictionaries, etc) and looks for substrings in strings. My question is regarding how in is implemented to achieve all of the following: 1) test for membership, 2) test for substrings and 3) access to the next element in a for-loop. For example, when for i in myList:
or if i in myList:
is executed, does in call myList.__next__()
? If it does call it, how then does it work with strings, given that str objects are not iterators(as checked in Python 2.7) and so do not have the next() method? If a detailed discussion of in's implementation is not possible, would appreciate if a gist of it is supplied here.
The 'in' Operator in Python The in operator works with iterable types, such as lists or strings, in Python. It is used to check if an element is found in the iterable. The in operator returns True if an element is found. It returns False if not.
The operators in and not in test for membership. x in s evaluates to True if x is a member of s, and False otherwise. x not in s returns the negation of x in s . All built-in sequences and set types support this as well as dictionary, for which in tests whether the dictionary has a given key.
Technically speaking, a Python iterator object must implement two special methods, __iter__() and __next__() , collectively called the iterator protocol. An object is called iterable if we can get an iterator from it. Most built-in containers in Python like: list, tuple, string etc. are iterables.
An iterator is an object that contains a countable number of values. An iterator is an object that can be iterated upon, meaning that you can traverse through all the values. Technically, in Python, an iterator is an object which implements the iterator protocol, which consist of the methods __iter__() and __next__() .
A class can define how the in
operator works on instances of that class by defining a __contains__
method.
The Python data model documentation says:
For objects that don’t define
__contains__()
, the membership test first tries iteration via__iter__()
, then the old sequence iteration protocol via__getitem__()
, see this section in the language reference.
Section 6.10.2, "Membership test operations", of the Python language reference has this to say:
The operators
in
andnot in
test for membership.x in s
evaluates toTrue
if x is a member of s, andFalse
otherwise.x not in s
returns the negation ofx in s
. All built-in sequences and set types support this as well as dictionary, for whichin
tests whether the dictionary has a given key. For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expressionx in y
is equivalent toany(x is e or x == e for e in y)
.For the string and bytes types,
x in y
isTrue
if and only if x is a substring of y. An equivalent test isy.find(x) != -1
. Empty strings are always considered to be a substring of any other string, so"" in "abc"
will returnTrue
.For user-defined classes which define the
__contains__()
method,x in y
returnsTrue
ify.__contains__(x)
returns a true value, andFalse
otherwise.For user-defined classes which do not define
__contains__()
but do define__iter__()
,x in y
isTrue
if some valuez
withx == z
is produced while iterating overy
. If an exception is raised during the iteration, it is as ifin
raised that exception.Lastly, the old-style iteration protocol is tried: if a class defines
__getitem__()
,x in y
isTrue
if and only if there is a non-negative integer index i such thatx == y[i]
, and all lower integer indices do not raiseIndexError
exception. (If any other exception is raised, it is as ifin
raised that exception).The operator
not in
is defined to have the inverse true value ofin
.
As a comment indicates above, the expression operator in
is distinct from the keyword in
which forms a part of the for
statement. In the Python grammar, the in
is "hardcoded" as a part of the syntax of for
:
for_stmt ::= "for" target_list "in" expression_list ":" suite ["else" ":" suite]
So in the context of a for
statement, in
doesn't behave as an operator, it's simply a syntactic marker to separate the target_list
from the expression_list
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With