In synchronous python, I can check if an iterator contains a value using the in
operator:
def my_iterator():
print('A')
yield 1
print('B')
yield 2
print('C')
yield 3
print(2 in my_iterator())
# A
# B
# True
However, if I try to do this with an AsyncGenerator
, there is no real way to do this with the in
operator. I could make my own function to advance in the iterator, but I'm wondering if Python supports something like this by default:
import asyncio
async def my_iterator():
print('A')
yield 1
print('B')
yield 2
print('C')
yield 3
async def main():
print(2 in my_iterator()) # argument of type 'async_generator' is not iterable
There is no async counterpart of the in
operator.
Also please note that __contains__
mentioned in the question title does not play a role in the posted example code. The details are documente here. The short version is that leaving aside strings, sequences, etc. there are three membership test methods for user defined objects:
__contains__
method exists, it is called,A generator (i.e. a function with yield
statements) does not have a __contains__
special method (step 1 is skipped), that's why it is iterated over (step 2).
To support async iterations, the step 2 would need a change. I don't know if it is possible, but I am quite sure the existing in
won't be changed.
That leaves us with two options for async iterables:
write an async generator (a class with __aiter__
and __anext__
) with its own __contains__
. You could then use the existing in
. However, in most cases it is impossible to know the future values.
just write an own test like you've mentioned in the question:
async for v in my_async_gen():
if v == some_value:
print("found")
break
else:
print("not found")