Iterators membership testing
Pierre Quentel
pierre.quentel at gmail.com
Sun Aug 9 05:06:50 EDT 2015
The documentation at https://docs.python.org/3.5/reference/expressions.html#not-in says :
"For user-defined classes which do not define __contains__() but do define
__iter__(), x in y is true if some value z with x == z is produced while
iterating over y. If an exception is raised during the iteration, it is as if
in raised that exception."
However, if I define a class with
class A:
def __init__(self, x):
self.x = x
self.counter = -1
def __iter__(self):
return self
def __next__(self):
self.counter += 1
if self.counter >= self.x:
raise StopIteration
return self.counter
and test for membership with
iterator = A(10)
for i in iterator:
assert i in iterator, '%s not found' %i
I get an assertion error. Setting a trace on __next__ suggests that for
membership testing, the interpreter consumes the iterator until the searched
value is found (or until exhaustion), then it resumes iteration at this point.
For instance :
>>> iterator = A(10)
>>> for i in iterator:
... print(i)
... assert i+1 in iterator
...
0
2
4
6
8
>>>
If this is correct, should the documentation mention it ?
More information about the Python-list
mailing list