Reputation: 1804
This is pretty basic question but couldn't find a good information on it.
How can I use the built in filter function when the function I want to use to filter the elements is async?
Example:
import asyncio
async def not_one(item):
if item == 1:
await asyncio.sleep(1) # Just to give an asyc feel..
return False
return True
async def main():
org_list = [1, 2, 3]
# IMPLEMENTATION #1 - WITHOUT USING FILTER
without_one_list = []
for item in org_list:
is_one = await not_one(item)
if is_one:
without_one_list.append(item)
print(without_one_list) # [2, 3]
# NOT WORKING #1 - not_one was never awaited
without_one_list = list(filter(not_one, org_list))
# NOT WORKING #2 - not a valid syntax
without_one_list = list(filter(await not_one, org_list))
# NOT WORKING #3 - not a valid syntax
without_one_list = list(await filter(not_one, org_list))
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
How can I do what I want while using the filter function?
Thanks
Upvotes: 3
Views: 2993
Reputation: 13393
in Python 3.6 you can use Asynchronous Generators
You should be able to define a simple async_filter
on your own, like this:
async def async_filter(async_pred, iterable):
for item in iterable:
should_yield = await async_pred(item)
if should_yield:
yield item
then you can obtain a list by using Asynchronous Comprehensions
:
import asyncio
async def not_one(item):
if item == 1:
await asyncio.sleep(1) # Just to give an asyc feel..
return False
return True
async def async_filter(async_pred, iterable):
for item in iterable:
should_yield = await async_pred(item)
if should_yield:
yield item
async def main():
org_list = [1, 2, 3]
# IMPLEMENTATION #1 - WITHOUT USING FILTER
without_one_list = []
for item in org_list:
is_one = await not_one(item)
if is_one:
without_one_list.append(item)
print(without_one_list) # [2, 3]
without_one_list_async = [i async for i in async_filter(not_one, org_list)]
print(without_one_list_async)
print(without_one_list_async == without_one_list)
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Output:
[2, 3]
[2, 3]
True
Upvotes: 5