Module grscheller.datastructures.core.iterlib
Module grscheller.datastructures.core.iterlib
Library of iterator related functions.
Expand source code
# Copyright 2023 Geoffrey R. Scheller
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Module grscheller.datastructures.core.iterlib
Library of iterator related functions.
"""
from __future__ import annotations
from typing import Any, Callable, Iterator
__all__ = ['mapIter', 'concat', 'exhaust', 'merge']
__author__ = "Geoffrey R. Scheller"
__copyright__ = "Copyright (c) 2023 Geoffrey R. Scheller"
__license__ = "Appache License 2.0"
def mapIter(iterator: Iterator[Any], f: Callable[[Any], Any]) -> Iterator[Any]:
"""Lazily map a function over an iterator stream.
See also the map Python builtin function.
"""
return (f(x) for x in iterator)
def concat(*iterators: Iterator[Any]) -> Iterator[Any]:
"""Sequentually concatenate multiple iterators into one.
See also the chain function from the itertools module.
"""
for iterator in iterators:
while True:
try:
value = next(iterator)
yield value
except StopIteration:
break
def merge(*iterators: Iterator[Any], yieldPartial = False) -> Iterator[Any]:
"""Merge multiple iterator streams until one is exhausted."""
iterList = list(iterators)
if (numIters := len(iterList)) > 0:
values = []
# Break when first iterator is exhausted
while True:
try:
for ii in range(numIters):
values.append(next(iterList[ii]))
for value in values:
yield value
values.clear()
except StopIteration:
break
# Yield any remaining values
if yieldPartial:
for value in values:
yield value
def exhaust(*iterators: Iterator[Any], yieldPartial = True) -> Iterator[Any]:
"""Merge multiple iterator streams until all are exhausted."""
iterList = list(iterators)
if (numIters := len(iterList)) > 0:
ii = 0
values = []
# Break when last iterator is exhausted
while True:
try:
while ii < numIters:
values.append(next(iterList[ii]))
ii += 1
for value in values:
yield value
ii = 0
values.clear()
except StopIteration:
numIters -= 1
if numIters < 1:
break
del iterList[ii]
# Yield any remaining values
if yieldPartial:
for value in values:
yield value
Functions
def concat(*iterators: Iterator[Any]) ‑> Iterator[Any]
-
Sequentually concatenate multiple iterators into one.
See also the chain function from the itertools module.
Expand source code
def concat(*iterators: Iterator[Any]) -> Iterator[Any]: """Sequentually concatenate multiple iterators into one. See also the chain function from the itertools module. """ for iterator in iterators: while True: try: value = next(iterator) yield value except StopIteration: break
def exhaust(*iterators: Iterator[Any], yieldPartial=True) ‑> Iterator[Any]
-
Merge multiple iterator streams until all are exhausted.
Expand source code
def exhaust(*iterators: Iterator[Any], yieldPartial = True) -> Iterator[Any]: """Merge multiple iterator streams until all are exhausted.""" iterList = list(iterators) if (numIters := len(iterList)) > 0: ii = 0 values = [] # Break when last iterator is exhausted while True: try: while ii < numIters: values.append(next(iterList[ii])) ii += 1 for value in values: yield value ii = 0 values.clear() except StopIteration: numIters -= 1 if numIters < 1: break del iterList[ii] # Yield any remaining values if yieldPartial: for value in values: yield value
def mapIter(iterator: Iterator[Any], f: Callable[[Any], Any]) ‑> Iterator[Any]
-
Lazily map a function over an iterator stream.
See also the map Python builtin function.
Expand source code
def mapIter(iterator: Iterator[Any], f: Callable[[Any], Any]) -> Iterator[Any]: """Lazily map a function over an iterator stream. See also the map Python builtin function. """ return (f(x) for x in iterator)
def merge(*iterators: Iterator[Any], yieldPartial=False) ‑> Iterator[Any]
-
Merge multiple iterator streams until one is exhausted.
Expand source code
def merge(*iterators: Iterator[Any], yieldPartial = False) -> Iterator[Any]: """Merge multiple iterator streams until one is exhausted.""" iterList = list(iterators) if (numIters := len(iterList)) > 0: values = [] # Break when first iterator is exhausted while True: try: for ii in range(numIters): values.append(next(iterList[ii])) for value in values: yield value values.clear() except StopIteration: break # Yield any remaining values if yieldPartial: for value in values: yield value