代码之家  ›  专栏  ›  技术社区  ›  Norrius

构成异步迭代器的map、filter和itertools

  •  6
  • Norrius  · 技术社区  · 7 年前

    python是否支持异步迭代器上的函数式操作?我知道我可以用 map , filter itertools 要懒洋洋地转换和使用来自正常生成器的数据,请执行以下操作:

    from itertools import accumulate, takewhile
    
    def generator():
        a, b = 1, 1
        while True:
            yield a
            a, b = b, a + b
    
    # create another iterator, no computation is started yet:
    another_iterator = takewhile(lambda x: x < 100, accumulate(generator()))
    # start consuming data:
    print(list(another_iterator))
    # [1, 2, 4, 7, 12, 20, 33, 54, 88]
    

    现在,Python3.6的异步生成器/迭代器不支持相同的功能,因为它们当然不实现普通的迭代器协议:

    async def agenerator():
        a, b = 1, 1
        while True:
            yield a
            a, b = b, a + b
    
    accumulate(agenerator())
    

    typeerror:“异步生成器”对象不可iterable

    在python 3.6/3.7中,是否有某种异步映射或异步itertools来实现类似的惰性行为?

    1 回复  |  直到 7 年前
        1
  •  5
  •   Mikhail Gerasimov    7 年前

    我看到的最完整的异步itertools版本是 aiostream 模块。你的例子是:

    import asyncio
    from aiostream.stream import takewhile, accumulate, list as alist
    
    
    async def agenerator():
        a, b = 1, 1
        while True:
            yield a
            a, b = b, a + b
    
    
    async def main():
        another_iterator = takewhile(
            accumulate(agenerator()),
            lambda x: x < 100, 
        )
    
        res = await alist(another_iterator)
    
        print(res)
    
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()