Skip to content
Permalink
main
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
# Copyright 2022 Amethyst Reese
# Licensed under the MIT license
import asyncio
from typing import AsyncIterable, List, Tuple, TypeVar
from aioitertools.helpers import maybe_await
from .builtins import iter
from .itertools import islice
from .types import AnyIterable, Predicate
T = TypeVar("T")
async def take(n: int, iterable: AnyIterable[T]) -> List[T]:
"""
Return the first n items of iterable as a list.
If there are too few items in iterable, all of them are returned.
n needs to be at least 0. If it is 0, an empty list is returned.
Example::
first_two = await take(2, [1, 2, 3, 4, 5])
"""
if n < 0:
raise ValueError("take's first parameter can't be negative")
return [item async for item in islice(iterable, n)]
async def chunked(iterable: AnyIterable[T], n: int) -> AsyncIterable[List[T]]:
"""
Break iterable into chunks of length n.
The last chunk will be shorter if the total number of items is not
divisible by n.
Example::
async for chunk in chunked([1, 2, 3, 4, 5], n=2):
... # first iteration: chunk == [1, 2]; last one: chunk == [5]
"""
it = iter(iterable)
chunk = await take(n, it)
while chunk != []:
yield chunk
chunk = await take(n, it)
async def before_and_after(
predicate: Predicate[T], iterable: AnyIterable[T]
) -> Tuple[AsyncIterable[T], AsyncIterable[T]]:
"""
A variant of :func:`aioitertools.takewhile` that allows complete access to the
remainder of the iterator.
>>> it = iter('ABCdEfGhI')
>>> all_upper, remainder = await before_and_after(str.isupper, it)
>>> ''.join([char async for char in all_upper])
'ABC'
>>> ''.join([char async for char in remainder])
'dEfGhI'
Note that the first iterator must be fully consumed before the second
iterator can generate valid results.
"""
it = iter(iterable)
transition = asyncio.get_event_loop().create_future()
async def true_iterator():
async for elem in it:
if await maybe_await(predicate(elem)):
yield elem
else:
transition.set_result(elem)
return
transition.set_exception(StopAsyncIteration)
async def remainder_iterator():
try:
yield (await transition)
except StopAsyncIteration:
return
async for elm in it:
yield elm
return true_iterator(), remainder_iterator()