Python 3.6 - 使用异步函数进行过滤

Noa*_*oam 2 python python-3.x python-3.6

这是非常基本的问题,但找不到相关的好信息。

当我想用来过滤元素的函数是异步的时,如何使用内置的过滤函数?

例子:

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())
Run Code Online (Sandbox Code Playgroud)

如何在使用过滤功能的同时做我想做的事?

谢谢

Ada*_*Er8 5

在Python 3.6中你可以使用Asynchronous Generators

您应该能够async_filter自己定义一个简单的,如下所示:

async def async_filter(async_pred, iterable):
    for item in iterable:
        should_yield = await async_pred(item)
        if should_yield:
            yield item
Run Code Online (Sandbox Code Playgroud)

那么您可以使用以下方法获取列表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())    
Run Code Online (Sandbox Code Playgroud)

输出:

[2, 3]
[2, 3]
True

Run Code Online (Sandbox Code Playgroud)