Source code for stouputils.collections.iterable


# Imports
from collections.abc import Callable, Iterable
from typing import Literal


# Functions
[docs] def unique_list[T](list_to_clean: Iterable[T], method: Literal["id", "hash", "str"] = "str") -> list[T]: """ Remove duplicates from the list while keeping the order using ids, hash, or str Args: list_to_clean (Iterable[T]): The list to clean method (Literal["id", "hash", "str"]): The method to use to identify duplicates Returns: list[T]: The cleaned list Examples: >>> unique_list([1, 2, 3, 2, 1], method="id") [1, 2, 3] >>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s3 = {1, 2, 3} >>> unique_list([s1, s2, s1, s1, s3, s2, s3], method="id") [{1, 2, 3}, {2, 3, 4}, {1, 2, 3}] >>> s1 = {1, 2, 3} >>> s2 = {2, 3, 4} >>> s3 = {1, 2, 3} >>> unique_list([s1, s2, s1, s1, s3, s2, s3], method="str") [{1, 2, 3}, {2, 3, 4}] """ # Initialize the seen ids set and the result list seen: set[int | str] = set() result: list[T] = [] # Iterate over each item in the list for item in list_to_clean: if method == "id": item_identifier = id(item) elif method == "hash": item_identifier = hash(item) elif method == "str": item_identifier = str(item) else: raise ValueError(f"Invalid method: {method}") # If the item id is not in the seen ids set, add it to the seen ids set and append the item to the result list if item_identifier not in seen: seen.add(item_identifier) result.append(item) # Return the cleaned list return result
[docs] def at_least_n[T](iterable: Iterable[T], predicate: Callable[[T], bool], n: int) -> bool: """ Return True if at least n elements in iterable satisfy predicate. It's like the built-in any() but for at least n matches. Stops iterating as soon as n matches are found (short-circuit evaluation). Args: iterable (Iterable[T]): The iterable to check. predicate (Callable[[T], bool]): The predicate to apply to items. n (int): Minimum number of matches required. Returns: bool: True if at least n elements satisfy predicate, otherwise False. Examples: >>> at_least_n([1, 2, 3, 4, *[i for i in range(5, int(1e5))]], lambda x: x % 2 == 0, 2) True >>> at_least_n([1, 3, 5, 7], lambda x: x % 2 == 0, 1) False """ if n <= 0: return True count: int = 0 for item in iterable: if predicate(item): count += 1 if count >= n: return True return False