Python 3.6-具有异步功能的过滤器

时间:2019-07-31 07:31:50

标签: 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())

使用过滤器功能时我该怎么办?

谢谢

1 个答案:

答案 0 :(得分:1)

在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

然后您可以使用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())    

输出:

[2, 3]
[2, 3]
True