pyiter.sequence

   1from __future__ import annotations
   2
   3if __name__ == "__main__":
   4    from pathlib import Path
   5
   6    __package__ = Path(__file__).parent.name
   7
   8from typing import (
   9    overload,
  10    Any,
  11    List,
  12    Set,
  13    Dict,
  14    Generic,
  15    Iterable,
  16    Iterator,
  17    Union,
  18    Optional,
  19    Tuple,
  20    Type,
  21    Callable,
  22    Literal,
  23    NamedTuple,
  24    Awaitable,
  25    TYPE_CHECKING,
  26)
  27
  28if TYPE_CHECKING:
  29    from _typeshed import SupportsRichComparisonT
  30    from random import Random
  31    from .parallel_mapping import ParallelMappingTransform
  32    from .grouping import Grouping
  33    from .list_like import ListLike
  34
  35# from typing_extensions import deprecated
  36from functools import cached_property
  37import sys
  38
  39
  40if sys.version_info < (3, 11):
  41    # Generic NamedTuple
  42    origin__namedtuple_mro_entries = NamedTuple.__mro_entries__  # type: ignore
  43    NamedTuple.__mro_entries__ = lambda bases: origin__namedtuple_mro_entries(bases[:1])  # type: ignore
  44
  45from .transform import Transform, NonTransform, new_transform, T, U, K, O as V
  46from .error import LazyEvaluationException
  47
  48
  49class Sequence(Generic[T], Iterable[T]):
  50    """
  51    Given an [iterator] function constructs a [Sequence] that returns values through the [Iterator]
  52    provided by that function.
  53
  54    The values are evaluated lazily, and the sequence is potentially infinite.
  55    """
  56
  57    __transform__: Transform[Any, T]
  58
  59    def __init__(self, iterable: Union[Iterable[T], Transform[Any, T]]) -> None:
  60        super().__init__()
  61
  62        self.__transform__ = new_transform(iterable)
  63
  64    @cached_property
  65    def transforms(self):
  66        return [*self.__transform__.transforms()]
  67
  68    @property
  69    def data(self) -> List[T]:
  70        if self.__transform__.cache is not None:
  71            return self.__transform__.cache.copy()
  72        if is_debugging():
  73            raise LazyEvaluationException("The sequence has not been evaluated yet.")
  74        return self.to_list()
  75
  76    def dedup(self) -> Sequence[T]:
  77        """
  78        Removes consecutive repeated elements in the sequence.
  79
  80        If the sequence is sorted, this removes all duplicates.
  81
  82        Example 1:
  83        >>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
  84        >>> it(lst).dedup().to_list()
  85        ['a1', 'b2', 'a2', 'a1']
  86
  87        Example 1:
  88        >>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
  89        >>> it(lst).sorted().dedup().to_list()
  90        ['a1', 'a2', 'b2']
  91        """
  92        return self.dedup_by(lambda x: x)
  93
  94    @overload
  95    def dedup_by(self, key_selector: Callable[[T], Any]) -> Sequence[T]: ...
  96    @overload
  97    def dedup_by(self, key_selector: Callable[[T, int], Any]) -> Sequence[T]: ...
  98    @overload
  99    def dedup_by(self, key_selector: Callable[[T, int, Sequence[T]], Any]) -> Sequence[T]: ...
 100    def dedup_by(self, key_selector: Callable[..., Any]) -> Sequence[T]:
 101        """
 102        Removes all but the first of consecutive elements in the sequence that resolve to the same key.
 103        """
 104        return self.dedup_into_group_by(key_selector).map(lambda x: x[0])
 105
 106    @overload
 107    def dedup_with_count_by(self, key_selector: Callable[[T], Any]) -> Sequence[Tuple[T, int]]: ...
 108    @overload
 109    def dedup_with_count_by(
 110        self, key_selector: Callable[[T, int], Any]
 111    ) -> Sequence[Tuple[T, int]]: ...
 112    @overload
 113    def dedup_with_count_by(
 114        self, key_selector: Callable[[T, int, Sequence[T]], Any]
 115    ) -> Sequence[Tuple[T, int]]: ...
 116    def dedup_with_count_by(self, key_selector: Callable[..., Any]) -> Sequence[Tuple[T, int]]:
 117        """
 118        Removes all but the first of consecutive elements and its count that resolve to the same key.
 119
 120        Example 1:
 121        >>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
 122        >>> it(lst).dedup_with_count_by(lambda x: x).to_list()
 123        [('a1', 2), ('b2', 1), ('a2', 1), ('a1', 1)]
 124
 125        Example 1:
 126        >>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
 127        >>> it(lst).sorted().dedup_with_count_by(lambda x: x).to_list()
 128        [('a1', 3), ('a2', 1), ('b2', 1)]
 129        """
 130        return self.dedup_into_group_by(key_selector).map(lambda x: (x[0], len(x)))
 131
 132    @overload
 133    def dedup_into_group_by(self, key_selector: Callable[[T], Any]) -> Sequence[List[T]]: ...
 134    @overload
 135    def dedup_into_group_by(self, key_selector: Callable[[T, int], Any]) -> Sequence[List[T]]: ...
 136    @overload
 137    def dedup_into_group_by(
 138        self, key_selector: Callable[[T, int, Sequence[T]], Any]
 139    ) -> Sequence[List[T]]: ...
 140    def dedup_into_group_by(self, key_selector: Callable[..., Any]) -> Sequence[List[T]]:
 141        from .dedup import DedupTransform
 142
 143        return it(DedupTransform(self, key_selector))
 144
 145    @overload
 146    def filter(self, predicate: Callable[[T], bool]) -> Sequence[T]: ...
 147    @overload
 148    def filter(self, predicate: Callable[[T, int], bool]) -> Sequence[T]: ...
 149    @overload
 150    def filter(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Sequence[T]: ...
 151    def filter(self, predicate: Callable[..., bool]) -> Sequence[T]:
 152        """
 153        Returns a Sequence containing only elements matching the given [predicate].
 154
 155        Example 1:
 156        >>> lst = [ 'a1', 'b1', 'b2', 'a2']
 157        >>> it(lst).filter(lambda x: x.startswith('a')).to_list()
 158        ['a1', 'a2']
 159
 160        Example 2:
 161        >>> lst = [ 'a1', 'b1', 'b2', 'a2']
 162        >>> it(lst).filter(lambda x, i: x.startswith('a') or i % 2 == 0 ).to_list()
 163        ['a1', 'b2', 'a2']
 164        """
 165        from .filtering import FilteringTransform
 166
 167        return it(FilteringTransform(self, self.__callback_overload_warpper__(predicate)))
 168
 169    def filter_is_instance(self, typ: Type[U]) -> Sequence[U]:
 170        """
 171        Returns a Sequence containing all elements that are instances of specified type parameter typ.
 172
 173        Example 1:
 174        >>> lst = [ 'a1', 1, 'b2', 3]
 175        >>> it(lst).filter_is_instance(int).to_list()
 176        [1, 3]
 177
 178        """
 179        return self.filter(lambda x: isinstance(x, typ))  # type: ignore
 180
 181    @overload
 182    def filter_not(self, predicate: Callable[[T], bool]) -> Sequence[T]: ...
 183    @overload
 184    def filter_not(self, predicate: Callable[[T, int], bool]) -> Sequence[T]: ...
 185    @overload
 186    def filter_not(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Sequence[T]: ...
 187    def filter_not(self, predicate: Callable[..., bool]) -> Sequence[T]:
 188        """
 189        Returns a Sequence containing all elements not matching the given [predicate].
 190
 191        Example 1:
 192        >>> lst = [ 'a1', 'b1', 'b2', 'a2']
 193        >>> it(lst).filter_not(lambda x: x.startswith('a')).to_list()
 194        ['b1', 'b2']
 195
 196        Example 2:
 197        >>> lst = [ 'a1', 'a2', 'b1', 'b2']
 198        >>> it(lst).filter_not(lambda x, i: x.startswith('a') and i % 2 == 0 ).to_list()
 199        ['a2', 'b1', 'b2']
 200        """
 201        predicate = self.__callback_overload_warpper__(predicate)
 202        return self.filter(lambda x: not predicate(x))
 203
 204    @overload
 205    def filter_not_none(self: Sequence[Optional[U]]) -> Sequence[U]: ...
 206    @overload
 207    def filter_not_none(self: Sequence[T]) -> Sequence[T]: ...
 208    def filter_not_none(self: Sequence[Optional[U]]) -> Sequence[U]:
 209        """
 210        Returns a Sequence containing all elements that are not `None`.
 211
 212        Example 1:
 213        >>> lst = [ 'a', None, 'b']
 214        >>> it(lst).filter_not_none().to_list()
 215        ['a', 'b']
 216        """
 217        return self.filter(lambda x: x is not None)  # type: ignore
 218
 219    @overload
 220    def map(self, transform: Callable[[T], U]) -> Sequence[U]: ...
 221    @overload
 222    def map(self, transform: Callable[[T, int], U]) -> Sequence[U]: ...
 223    @overload
 224    def map(self, transform: Callable[[T, int, Sequence[T]], U]) -> Sequence[U]: ...
 225    def map(self, transform: Callable[..., U]) -> Sequence[U]:
 226        """
 227        Returns a Sequence containing the results of applying the given [transform] function
 228        to each element in the original Sequence.
 229
 230        Example 1:
 231        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
 232        >>> it(lst).map(lambda x: x['age']).to_list()
 233        [12, 13]
 234
 235        Example 2:
 236        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
 237        >>> it(lst).map(lambda x, i: x['name'] + str(i)).to_list()
 238        ['A0', 'B1']
 239
 240        Example 3:
 241        >>> lst = ['hi', 'abc']
 242        >>> it(lst).map(len).to_list()
 243        [2, 3]
 244        """
 245        from .mapping import MappingTransform
 246
 247        return it(MappingTransform(self, self.__callback_overload_warpper__(transform)))
 248
 249    @overload
 250    async def map_async(self, transform: Callable[[T], Awaitable[U]]) -> Sequence[U]: ...
 251    @overload
 252    async def map_async(
 253        self,
 254        transform: Callable[[T, int], Awaitable[U]],
 255        return_exceptions: Literal[True],
 256    ) -> Sequence[Union[U, BaseException]]: ...
 257    @overload
 258    async def map_async(
 259        self,
 260        transform: Callable[[T, int, Sequence[T]], Awaitable[U]],
 261        return_exceptions: Literal[False] = False,
 262    ) -> Sequence[U]: ...
 263    async def map_async(
 264        self, transform: Callable[..., Awaitable[U]], return_exceptions: bool = False
 265    ):
 266        """
 267        Similar to `.map()` but you can input a async transform then await it.
 268        """
 269        from asyncio import gather
 270
 271        if return_exceptions:
 272            return it(await gather(*self.map(transform), return_exceptions=True))
 273        return it(await gather(*self.map(transform)))
 274
 275    @overload
 276    def map_not_none(self, transform: Callable[[T], Optional[U]]) -> Sequence[U]: ...
 277    @overload
 278    def map_not_none(self, transform: Callable[[T, int], Optional[U]]) -> Sequence[U]: ...
 279    @overload
 280    def map_not_none(
 281        self, transform: Callable[[T, int, Sequence[T]], Optional[U]]
 282    ) -> Sequence[U]: ...
 283    def map_not_none(self, transform: Callable[..., Optional[U]]) -> Sequence[U]:
 284        """
 285        Returns a Sequence containing only the non-none results of applying the given [transform] function
 286        to each element in the original collection.
 287
 288        Example 1:
 289        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': None}]
 290        >>> it(lst).map_not_none(lambda x: x['age']).to_list()
 291        [12]
 292        """
 293        return self.map(transform).filter_not_none()  # type: ignore
 294
 295    @overload
 296    def parallel_map(
 297        self,
 298        transform: Callable[[T], U],
 299        max_workers: Optional[int] = None,
 300        chunksize: int = 1,
 301        executor: ParallelMappingTransform.Executor = "Thread",
 302    ) -> Sequence[U]: ...
 303    @overload
 304    def parallel_map(
 305        self,
 306        transform: Callable[[T, int], U],
 307        max_workers: Optional[int] = None,
 308        chunksize: int = 1,
 309        executor: ParallelMappingTransform.Executor = "Thread",
 310    ) -> Sequence[U]: ...
 311    @overload
 312    def parallel_map(
 313        self,
 314        transform: Callable[[T, int, Sequence[T]], U],
 315        max_workers: Optional[int] = None,
 316        chunksize: int = 1,
 317        executor: ParallelMappingTransform.Executor = "Thread",
 318    ) -> Sequence[U]: ...
 319    def parallel_map(
 320        self,
 321        transform: Callable[..., U],
 322        max_workers: Optional[int] = None,
 323        chunksize: int = 1,
 324        executor: ParallelMappingTransform.Executor = "Thread",
 325    ) -> Sequence[U]:
 326        """
 327        Returns a Sequence containing the results of applying the given [transform] function
 328        to each element in the original Sequence.
 329
 330        Example 1:
 331        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
 332        >>> it(lst).parallel_map(lambda x: x['age']).to_list()
 333        [12, 13]
 334
 335        Example 2:
 336        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
 337        >>> it(lst).parallel_map(lambda x: x['age'], max_workers=2).to_list()
 338        [12, 13]
 339
 340        Example 3:
 341        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
 342        >>> it(lst).parallel_map(lambda x, i: x['age'] + i, max_workers=2).to_list()
 343        [12, 14]
 344        """
 345        from .parallel_mapping import ParallelMappingTransform
 346
 347        return it(
 348            ParallelMappingTransform(
 349                self,
 350                self.__callback_overload_warpper__(transform),
 351                max_workers,
 352                chunksize,
 353                executor,
 354            )
 355        )
 356
 357    @overload
 358    def find(self, predicate: Callable[[T], bool]) -> Optional[T]: ...
 359    @overload
 360    def find(self, predicate: Callable[[T, int], bool]) -> Optional[T]: ...
 361    @overload
 362    def find(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Optional[T]: ...
 363    def find(self, predicate: Callable[..., bool]) -> Optional[T]:
 364        """
 365        Returns the first element matching the given [predicate], or `None` if no such element was found.
 366
 367        Example 1:
 368        >>> lst = ['a', 'b', 'c']
 369        >>> it(lst).find(lambda x: x == 'b')
 370        'b'
 371        """
 372        return self.first_or_none(predicate)
 373
 374    def find_last(self, predicate: Callable[[T], bool]) -> Optional[T]:
 375        """
 376        Returns the last element matching the given [predicate], or `None` if no such element was found.
 377
 378        Example 1:
 379        >>> lst = ['a', 'b', 'c']
 380        >>> it(lst).find_last(lambda x: x == 'b')
 381        'b'
 382        """
 383        return self.last_or_none(predicate)
 384
 385    @overload
 386    def first(self) -> T: ...
 387    @overload
 388    def first(self, predicate: Callable[[T], bool]) -> T: ...
 389    @overload
 390    def first(self, predicate: Callable[[T, int], bool]) -> T: ...
 391    @overload
 392    def first(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> T: ...
 393    def first(self, predicate: Optional[Callable[..., bool]] = None) -> T:
 394        """
 395        Returns first element.
 396
 397        Example 1:
 398        >>> lst = ['a', 'b', 'c']
 399        >>> it(lst).first()
 400        'a'
 401
 402        Example 2:
 403        >>> lst = []
 404        >>> it(lst).first()
 405        Traceback (most recent call last):
 406        ...
 407        ValueError: Sequence is empty.
 408
 409        Example 3:
 410        >>> lst = ['a', 'b', 'c']
 411        >>> it(lst).first(lambda x: x == 'b')
 412        'b'
 413
 414        Example 4:
 415        >>> lst = ['a', 'b', 'c']
 416        >>> it(lst).first(lambda x: x == 'd')
 417        Traceback (most recent call last):
 418        ...
 419        ValueError: Sequence is empty.
 420
 421        Example 5:
 422        >>> lst = [None]
 423        >>> it(lst).first() is None
 424        True
 425        """
 426        for e in self:
 427            if predicate is None or predicate(e):
 428                return e
 429        raise ValueError("Sequence is empty.")
 430
 431    @overload
 432    def first_not_none_of(self: Sequence[Optional[U]]) -> U: ...
 433    @overload
 434    def first_not_none_of(
 435        self: Sequence[Optional[U]], transform: Callable[[Optional[U]], Optional[U]]
 436    ) -> U: ...
 437    @overload
 438    def first_not_none_of(
 439        self: Sequence[Optional[U]],
 440        transform: Callable[[Optional[U], int], Optional[U]],
 441    ) -> U: ...
 442    @overload
 443    def first_not_none_of(
 444        self: Sequence[Optional[U]],
 445        transform: Callable[[Optional[U], int, Sequence[Optional[U]]], Optional[U]],
 446    ) -> U: ...
 447    def first_not_none_of(
 448        self: Sequence[Optional[U]],
 449        transform: Optional[Callable[..., Optional[U]]] = None,
 450    ) -> U:
 451        """
 452        Returns the first non-`None` result of applying the given [transform] function to each element in the original collection.
 453
 454        Example 1:
 455        >>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': 12}]
 456        >>> it(lst).first_not_none_of(lambda x: x['age'])
 457        12
 458
 459        Example 2:
 460        >>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': None}]
 461        >>> it(lst).first_not_none_of(lambda x: x['age'])
 462        Traceback (most recent call last):
 463        ...
 464        ValueError: No element of the Sequence was transformed to a non-none value.
 465        """
 466
 467        v = (
 468            self.first_not_none_of_or_none()
 469            if transform is None
 470            else self.first_not_none_of_or_none(transform)
 471        )
 472        if v is None:
 473            raise ValueError("No element of the Sequence was transformed to a non-none value.")
 474        return v
 475
 476    @overload
 477    def first_not_none_of_or_none(self) -> T: ...
 478    @overload
 479    def first_not_none_of_or_none(self, transform: Callable[[T], T]) -> T: ...
 480    @overload
 481    def first_not_none_of_or_none(self, transform: Callable[[T, int], T]) -> T: ...
 482    @overload
 483    def first_not_none_of_or_none(self, transform: Callable[[T, int, Sequence[T]], T]) -> T: ...
 484    def first_not_none_of_or_none(self, transform: Optional[Callable[..., T]] = None) -> T:
 485        """
 486        Returns the first non-`None` result of applying the given [transform] function to each element in the original collection.
 487
 488        Example 1:
 489        >>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': 12}]
 490        >>> it(lst).first_not_none_of_or_none(lambda x: x['age'])
 491        12
 492
 493        Example 2:
 494        >>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': None}]
 495        >>> it(lst).first_not_none_of_or_none(lambda x: x['age']) is None
 496        True
 497        """
 498        if transform is None:
 499            return self.first_or_none()
 500        return self.map_not_none(transform).first_or_none()
 501
 502    @overload
 503    def first_or_none(self) -> T: ...
 504    @overload
 505    def first_or_none(self, predicate: Callable[[T], bool]) -> Optional[T]: ...
 506    @overload
 507    def first_or_none(self, predicate: Callable[[T, int], bool]) -> Optional[T]: ...
 508    @overload
 509    def first_or_none(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Optional[T]: ...
 510    def first_or_none(self, predicate: Optional[Callable[..., bool]] = None) -> Optional[T]:
 511        """
 512        Returns the first element, or `None` if the Sequence is empty.
 513
 514        Example 1:
 515        >>> lst = []
 516        >>> it(lst).first_or_none() is None
 517        True
 518
 519        Example 2:
 520        >>> lst = ['a', 'b', 'c']
 521        >>> it(lst).first_or_none()
 522        'a'
 523
 524        Example 2:
 525        >>> lst = ['a', 'b', 'c']
 526        >>> it(lst).first_or_none(lambda x: x == 'b')
 527        'b'
 528        """
 529        if predicate is not None:
 530            return self.first_or_default(predicate, None)
 531        else:
 532            return self.first_or_default(None)
 533
 534    @overload
 535    def first_or_default(self, default: U) -> Union[T, U]: ...
 536    @overload
 537    def first_or_default(self, predicate: Callable[[T], bool], default: U) -> Union[T, U]: ...
 538    @overload
 539    def first_or_default(self, predicate: Callable[[T, int], bool], default: U) -> Union[T, U]: ...
 540    @overload
 541    def first_or_default(
 542        self, predicate: Callable[[T, int, Sequence[T]], bool], default: U
 543    ) -> Union[T, U]: ...
 544    def first_or_default(  # type: ignore
 545        self, predicate: Union[Callable[..., bool], U], default: Optional[U] = None
 546    ) -> Union[T, U, None]:
 547        """
 548        Returns the first element, or the given [default] if the Sequence is empty.
 549
 550        Example 1:
 551        >>> lst = []
 552        >>> it(lst).first_or_default('a')
 553        'a'
 554
 555        Example 2:
 556        >>> lst = ['b']
 557        >>> it(lst).first_or_default('a')
 558        'b'
 559
 560        Example 3:
 561        >>> lst = ['a', 'b', 'c']
 562        >>> it(lst).first_or_default(lambda x: x == 'b', 'd')
 563        'b'
 564
 565        Example 4:
 566        >>> lst = []
 567        >>> it(lst).first_or_default(lambda x: x == 'b', 'd')
 568        'd'
 569        """
 570        seq = self
 571        if isinstance(predicate, Callable):
 572            seq = self.filter(predicate)  # type: ignore
 573        else:
 574            default = predicate
 575        return next(iter(seq), default)
 576
 577    @overload
 578    def last(self) -> T: ...
 579    @overload
 580    def last(self, predicate: Callable[[T], bool]) -> T: ...
 581    @overload
 582    def last(self, predicate: Callable[[T, int], bool]) -> T: ...
 583    @overload
 584    def last(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> T: ...
 585    def last(self, predicate: Optional[Callable[..., bool]] = None) -> T:
 586        """
 587        Returns last element.
 588
 589        Example 1:
 590        >>> lst = ['a', 'b', 'c']
 591        >>> it(lst).last()
 592        'c'
 593
 594        Example 2:
 595        >>> lst = []
 596        >>> it(lst).last()
 597        Traceback (most recent call last):
 598        ...
 599        ValueError: Sequence is empty.
 600        """
 601        v = self.last_or_none(predicate) if predicate is not None else self.last_or_none()
 602        if v is None:
 603            raise ValueError("Sequence is empty.")
 604        return v
 605
 606    @overload
 607    def last_or_none(self) -> Optional[T]: ...
 608    @overload
 609    def last_or_none(self, predicate: Callable[[T], bool]) -> Optional[T]: ...
 610    @overload
 611    def last_or_none(self, predicate: Callable[[T, int], bool]) -> Optional[T]: ...
 612    @overload
 613    def last_or_none(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Optional[T]: ...
 614    def last_or_none(self, predicate: Optional[Callable[..., bool]] = None) -> Optional[T]:
 615        """
 616        Returns the last element matching the given [predicate], or `None` if no such element was found.
 617
 618        Exmaple 1:
 619        >>> lst = ['a', 'b', 'c']
 620        >>> it(lst).last_or_none()
 621        'c'
 622
 623        Exmaple 2:
 624        >>> lst = ['a', 'b', 'c']
 625        >>> it(lst).last_or_none(lambda x: x != 'c')
 626        'b'
 627
 628        Exmaple 3:
 629        >>> lst = []
 630        >>> it(lst).last_or_none(lambda x: x != 'c') is None
 631        True
 632        """
 633        last: Optional[T] = None
 634        for i in self if predicate is None else self.filter(predicate):
 635            last = i
 636        return last
 637
 638    def index_of_or_none(self, element: T) -> Optional[int]:
 639        """
 640        Returns first index of [element], or None if the collection does not contain element.
 641
 642        Example 1:
 643        >>> lst = ['a', 'b', 'c']
 644        >>> it(lst).index_of_or_none('b')
 645        1
 646
 647        Example 2:
 648        >>> lst = ['a', 'b', 'c']
 649        >>> it(lst).index_of_or_none('d')
 650        """
 651        for i, x in enumerate(self):
 652            if x == element:
 653                return i
 654        return None
 655
 656    def index_of(self, element: T) -> int:
 657        """
 658        Returns first index of [element], or -1 if the collection does not contain element.
 659
 660        Example 1:
 661        >>> lst = ['a', 'b', 'c']
 662        >>> it(lst).index_of('b')
 663        1
 664
 665        Example 2:
 666        >>> lst = ['a', 'b', 'c']
 667        >>> it(lst).index_of('d')
 668        -1
 669        """
 670        return none_or(self.index_of_or_none(element), -1)
 671
 672    def index_of_or(self, element: T, default: int) -> int:
 673        """
 674        Returns first index of [element], or default value if the collection does not contain element.
 675
 676        Example 1:
 677        >>> lst = ['a', 'b', 'c']
 678        >>> it(lst).index_of_or('b', 1)
 679        1
 680
 681        Example 2:
 682        >>> lst = ['a', 'b', 'c']
 683        >>> it(lst).index_of_or('d', 0)
 684        0
 685        """
 686        return none_or(self.index_of_or_none(element), default)
 687
 688    def index_of_or_else(self, element: T, f: Callable[[], int]) -> int:
 689        """
 690        Returns first index of [element], or computes the value from a callback if the collection does not contain element.
 691
 692        Example 1:
 693        >>> lst = ['a', 'b', 'c']
 694        >>> it(lst).index_of_or_else('b', lambda: 2)
 695        1
 696
 697        Example 2:
 698        >>> lst = ['a', 'b', 'c']
 699        >>> it(lst).index_of_or_else('d', lambda: 0)
 700        0
 701        """
 702        return none_or_else(self.index_of_or_none(element), f)
 703
 704    def last_index_of_or_none(self, element: T) -> Optional[int]:
 705        """
 706         Returns last index of [element], or None if the collection does not contain element.
 707
 708        Example 1:
 709        >>> lst = ['a', 'b', 'c', 'b']
 710        >>> it(lst).last_index_of_or_none('b')
 711        3
 712
 713        Example 2:
 714        >>> lst = ['a', 'b', 'c']
 715        >>> it(lst).last_index_of_or_none('d')
 716        """
 717        seq = self.reversed()
 718        last_idx = len(seq) - 1
 719        for i, x in enumerate(seq):
 720            if x == element:
 721                return last_idx - i
 722        return None
 723
 724    def last_index_of(self, element: T) -> int:
 725        """
 726         Returns last index of [element], or -1 if the collection does not contain element.
 727
 728        Example 1:
 729        >>> lst = ['a', 'b', 'c', 'b']
 730        >>> it(lst).last_index_of('b')
 731        3
 732
 733        Example 2:
 734        >>> lst = ['a', 'b', 'c']
 735        >>> it(lst).last_index_of('d')
 736        -1
 737        """
 738        return none_or(self.last_index_of_or_none(element), -1)
 739
 740    def last_index_of_or(self, element: T, default: int) -> int:
 741        """
 742         Returns last index of [element], or default value if the collection does not contain element.
 743
 744        Example 1:
 745        >>> lst = ['a', 'b', 'c', 'b']
 746        >>> it(lst).last_index_of_or('b', 0)
 747        3
 748
 749        Example 2:
 750        >>> lst = ['a', 'b', 'c']
 751        >>> it(lst).last_index_of_or('d', len(lst))
 752        3
 753        """
 754        return none_or(self.last_index_of_or_none(element), default)
 755
 756    def last_index_of_or_else(self, element: T, f: Callable[[], int]) -> int:
 757        """
 758         Returns last index of [element], or computes the value from a callback if the collection does not contain element.
 759
 760        Example 1:
 761        >>> lst = ['a', 'b', 'c', 'b']
 762        >>> it(lst).last_index_of_or_else('b', lambda: 0)
 763        3
 764
 765        Example 2:
 766        >>> lst = ['a', 'b', 'c']
 767        >>> it(lst).last_index_of_or_else('d', lambda: len(lst))
 768        3
 769        """
 770        return none_or_else(self.last_index_of_or_none(element), f)
 771
 772    @overload
 773    def index_of_first_or_none(self, predicate: Callable[[T], bool]) -> Optional[int]: ...
 774    @overload
 775    def index_of_first_or_none(self, predicate: Callable[[T, int], bool]) -> Optional[int]: ...
 776    @overload
 777    def index_of_first_or_none(
 778        self, predicate: Callable[[T, int, Sequence[T]], bool]
 779    ) -> Optional[int]: ...
 780    def index_of_first_or_none(self, predicate: Callable[..., bool]) -> Optional[int]:
 781        """
 782        Returns first index of element matching the given [predicate], or None if no such element was found.
 783
 784        Example 1:
 785        >>> lst = ['a', 'b', 'c']
 786        >>> it(lst).index_of_first_or_none(lambda x: x == 'b')
 787        1
 788
 789        Example 2:
 790        >>> lst = ['a', 'b', 'c']
 791        >>> it(lst).index_of_first_or_none(lambda x: x == 'd')
 792        """
 793        predicate = self.__callback_overload_warpper__(predicate)
 794        for i, x in enumerate(self):
 795            if predicate(x):
 796                return i
 797        return None
 798
 799    @overload
 800    def index_of_first(self, predicate: Callable[[T], bool]) -> int: ...
 801    @overload
 802    def index_of_first(self, predicate: Callable[[T, int], bool]) -> int: ...
 803    @overload
 804    def index_of_first(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> int: ...
 805    def index_of_first(self, predicate: Callable[..., bool]) -> int:
 806        """
 807        Returns first index of element matching the given [predicate], or -1 if no such element was found.
 808
 809        Example 1:
 810        >>> lst = ['a', 'b', 'c']
 811        >>> it(lst).index_of_first(lambda x: x == 'b')
 812        1
 813
 814        Example 2:
 815        >>> lst = ['a', 'b', 'c']
 816        >>> it(lst).index_of_first(lambda x: x == 'd')
 817        -1
 818
 819        Example 3:
 820        >>> lst = ['a', 'b', 'c']
 821        >>> it(lst).index_of_first(lambda x: x == 'a')
 822        0
 823        """
 824        return none_or(self.index_of_first_or_none(predicate), -1)
 825
 826    @overload
 827    def index_of_first_or(self, predicate: Callable[[T], bool], default: int) -> int: ...
 828    @overload
 829    def index_of_first_or(self, predicate: Callable[[T, int], bool], default: int) -> int: ...
 830    @overload
 831    def index_of_first_or(
 832        self, predicate: Callable[[T, int, Sequence[T]], bool], default: int
 833    ) -> int: ...
 834    def index_of_first_or(self, predicate: Callable[..., bool], default: int) -> int:
 835        """
 836        Returns first index of element matching the given [predicate], or default value if no such element was found.
 837
 838        Example 1:
 839        >>> lst = ['a', 'b', 'c']
 840        >>> it(lst).index_of_first_or(lambda x: x == 'b', 0)
 841        1
 842
 843        Example 2:
 844        >>> lst = ['a', 'b', 'c']
 845        >>> it(lst).index_of_first_or(lambda x: x == 'd', 0)
 846        0
 847
 848        Example 3:
 849        >>> lst = ['a', 'b', 'c']
 850        >>> it(lst).index_of_first_or(lambda x: x == 'a', 0)
 851        0
 852        """
 853        return none_or(self.index_of_first_or_none(predicate), default)
 854
 855    @overload
 856    def index_of_first_or_else(
 857        self, predicate: Callable[[T], bool], f: Callable[[], int]
 858    ) -> int: ...
 859    @overload
 860    def index_of_first_or_else(
 861        self, predicate: Callable[[T, int], bool], f: Callable[[], int]
 862    ) -> int: ...
 863    @overload
 864    def index_of_first_or_else(
 865        self, predicate: Callable[[T, int, Sequence[T]], bool], f: Callable[[], int]
 866    ) -> int: ...
 867    def index_of_first_or_else(self, predicate: Callable[..., bool], f: Callable[[], int]) -> int:
 868        """
 869        Returns first index of element matching the given [predicate], or computes the value from a callback if no such element was found.
 870
 871        Example 1:
 872        >>> lst = ['a', 'b', 'c']
 873        >>> it(lst).index_of_first_or_else(lambda x: x == 'b', lambda: len(lst))
 874        1
 875
 876        Example 2:
 877        >>> lst = ['a', 'b', 'c']
 878        >>> it(lst).index_of_first_or_else(lambda x: x == 'd', lambda: len(lst))
 879        3
 880
 881        Example 3:
 882        >>> lst = ['a', 'b', 'c']
 883        >>> it(lst).index_of_first_or_else(lambda x: x == 'a', lambda: len(lst))
 884        0
 885        """
 886        return none_or_else(self.index_of_first_or_none(predicate), f)
 887
 888    @overload
 889    def index_of_last_or_none(self, predicate: Callable[[T], bool]) -> Optional[int]: ...
 890    @overload
 891    def index_of_last_or_none(self, predicate: Callable[[T, int], bool]) -> Optional[int]: ...
 892    @overload
 893    def index_of_last_or_none(
 894        self, predicate: Callable[[T, int, Sequence[T]], bool]
 895    ) -> Optional[int]: ...
 896    def index_of_last_or_none(self, predicate: Callable[..., bool]) -> Optional[int]:
 897        """
 898        Returns last index of element matching the given [predicate], or -1 if no such element was found.
 899
 900        Example 1:
 901        >>> lst = ['a', 'b', 'c', 'b']
 902        >>> it(lst).index_of_last_or_none(lambda x: x == 'b')
 903        3
 904
 905        Example 2:
 906        >>> lst = ['a', 'b', 'c']
 907        >>> it(lst).index_of_last_or_none(lambda x: x == 'd')
 908        """
 909        seq = self.reversed()
 910        last_idx = len(seq) - 1
 911        predicate = self.__callback_overload_warpper__(predicate)
 912        for i, x in enumerate(seq):
 913            if predicate(x):
 914                return last_idx - i
 915        return None
 916
 917    @overload
 918    def index_of_last(self, predicate: Callable[[T], bool]) -> int: ...
 919    @overload
 920    def index_of_last(self, predicate: Callable[[T, int], bool]) -> int: ...
 921    @overload
 922    def index_of_last(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> int: ...
 923    def index_of_last(self, predicate: Callable[..., bool]) -> int:
 924        """
 925        Returns last index of element matching the given [predicate], or -1 if no such element was found.
 926
 927        Example 1:
 928        >>> lst = ['a', 'b', 'c', 'b']
 929        >>> it(lst).index_of_last(lambda x: x == 'b')
 930        3
 931
 932        Example 2:
 933        >>> lst = ['a', 'b', 'c']
 934        >>> it(lst).index_of_last(lambda x: x == 'd')
 935        -1
 936
 937        Example 3:
 938        >>> lst = ['a', 'b', 'c']
 939        >>> it(lst).index_of_last(lambda x: x == 'a')
 940        0
 941        """
 942        return none_or(self.index_of_last_or_none(predicate), -1)
 943
 944    @overload
 945    def index_of_last_or(self, predicate: Callable[[T], bool], default: int) -> int: ...
 946    @overload
 947    def index_of_last_or(self, predicate: Callable[[T, int], bool], default: int) -> int: ...
 948    @overload
 949    def index_of_last_or(
 950        self, predicate: Callable[[T, int, Sequence[T]], bool], default: int
 951    ) -> int: ...
 952    def index_of_last_or(self, predicate: Callable[..., bool], default: int) -> int:
 953        """
 954        Returns last index of element matching the given [predicate], or default value if no such element was found.
 955
 956        Example 1:
 957        >>> lst = ['a', 'b', 'c', 'b']
 958        >>> it(lst).index_of_last_or(lambda x: x == 'b', 0)
 959        3
 960
 961        Example 2:
 962        >>> lst = ['a', 'b', 'c']
 963        >>> it(lst).index_of_last_or(lambda x: x == 'd', -99)
 964        -99
 965
 966        Example 3:
 967        >>> lst = ['a', 'b', 'c']
 968        >>> it(lst).index_of_last_or(lambda x: x == 'a', 0)
 969        0
 970        """
 971        return none_or(self.index_of_last_or_none(predicate), default)
 972
 973    @overload
 974    def index_of_last_o_else(self, predicate: Callable[[T], bool], f: Callable[[], int]) -> int: ...
 975    @overload
 976    def index_of_last_o_else(
 977        self, predicate: Callable[[T, int], bool], f: Callable[[], int]
 978    ) -> int: ...
 979    @overload
 980    def index_of_last_o_else(
 981        self, predicate: Callable[[T, int, Sequence[T]], bool], f: Callable[[], int]
 982    ) -> int: ...
 983    def index_of_last_o_else(self, predicate: Callable[..., bool], f: Callable[[], int]) -> int:
 984        """
 985        Returns last index of element matching the given [predicate], or default value if no such element was found.
 986
 987        Example 1:
 988        >>> lst = ['a', 'b', 'c', 'b']
 989        >>> it(lst).index_of_last_o_else(lambda x: x == 'b', lambda: -len(lst))
 990        3
 991
 992        Example 2:
 993        >>> lst = ['a', 'b', 'c']
 994        >>> it(lst).index_of_last_o_else(lambda x: x == 'd', lambda: -len(lst))
 995        -3
 996
 997        Example 3:
 998        >>> lst = ['a', 'b', 'c']
 999        >>> it(lst).index_of_last_o_else(lambda x: x == 'a', lambda: -len(lst))
1000        0
1001        """
1002        return none_or_else(self.index_of_last_or_none(predicate), f)
1003
1004    @overload
1005    def single(self) -> T: ...
1006    @overload
1007    def single(self, predicate: Callable[[T], bool]) -> T: ...
1008    @overload
1009    def single(self, predicate: Callable[[T, int], bool]) -> T: ...
1010    @overload
1011    def single(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> T: ...
1012    def single(self, predicate: Optional[Callable[..., bool]] = None) -> T:
1013        """
1014        Returns the single element matching the given [predicate], or throws exception if there is no
1015        or more than one matching element.
1016
1017        Exmaple 1:
1018        >>> lst = ['a']
1019        >>> it(lst).single()
1020        'a'
1021
1022        Exmaple 2:
1023        >>> lst = []
1024        >>> it(lst).single() is None
1025        Traceback (most recent call last):
1026        ...
1027        ValueError: Sequence contains no element matching the predicate.
1028
1029        Exmaple 2:
1030        >>> lst = ['a', 'b']
1031        >>> it(lst).single() is None
1032        Traceback (most recent call last):
1033        ...
1034        ValueError: Sequence contains more than one matching element.
1035        """
1036        single: Optional[T] = None
1037        found = False
1038        for i in self if predicate is None else self.filter(predicate):
1039            if found:
1040                raise ValueError("Sequence contains more than one matching element.")
1041            single = i
1042            found = True
1043        if single is None:
1044            raise ValueError("Sequence contains no element matching the predicate.")
1045        return single
1046
1047    @overload
1048    def single_or_none(self) -> Optional[T]: ...
1049    @overload
1050    def single_or_none(self, predicate: Callable[[T], bool]) -> Optional[T]: ...
1051    @overload
1052    def single_or_none(self, predicate: Callable[[T, int], bool]) -> Optional[T]: ...
1053    @overload
1054    def single_or_none(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Optional[T]: ...
1055    def single_or_none(self, predicate: Optional[Callable[..., bool]] = None) -> Optional[T]:
1056        """
1057        Returns the single element matching the given [predicate], or `None` if element was not found
1058        or more than one element was found.
1059
1060        Exmaple 1:
1061        >>> lst = ['a']
1062        >>> it(lst).single_or_none()
1063        'a'
1064
1065        Exmaple 2:
1066        >>> lst = []
1067        >>> it(lst).single_or_none()
1068
1069        Exmaple 2:
1070        >>> lst = ['a', 'b']
1071        >>> it(lst).single_or_none()
1072
1073        """
1074        single: Optional[T] = None
1075        found = False
1076        for i in self if predicate is None else self.filter(predicate):
1077            if found:
1078                return None
1079            single = i
1080            found = True
1081        if not found:
1082            return None
1083        return single
1084
1085    # noinspection PyShadowingNames
1086    def drop(self, n: int) -> Sequence[T]:
1087        """
1088        Returns a Sequence containing all elements except first [n] elements.
1089
1090        Example 1:
1091        >>> lst = ['a', 'b', 'c']
1092        >>> it(lst).drop(0).to_list()
1093        ['a', 'b', 'c']
1094
1095        Example 2:
1096        >>> lst = ['a', 'b', 'c']
1097        >>> it(lst).drop(1).to_list()
1098        ['b', 'c']
1099
1100        Example 2:
1101        >>> lst = ['a', 'b', 'c']
1102        >>> it(lst).drop(4).to_list()
1103        []
1104        """
1105        if n < 0:
1106            raise ValueError(f"Requested element count {n} is less than zero.")
1107        if n == 0:
1108            return self
1109
1110        from .drop import DropTransform
1111
1112        return it(DropTransform(self, n))
1113
1114    # noinspection PyShadowingNames
1115    @overload
1116    def drop_while(self, predicate: Callable[[T], bool]) -> Sequence[T]: ...
1117    @overload
1118    def drop_while(self, predicate: Callable[[T, int], bool]) -> Sequence[T]: ...
1119    @overload
1120    def drop_while(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Sequence[T]: ...
1121    def drop_while(self, predicate: Callable[..., bool]) -> Sequence[T]:
1122        """
1123        Returns a Sequence containing all elements except first elements that satisfy the given [predicate].
1124
1125        Example 1:
1126        >>> lst = [1, 2, 3, 4, 1]
1127        >>> it(lst).drop_while(lambda x: x < 3 ).to_list()
1128        [3, 4, 1]
1129        """
1130        from .drop_while import DropWhileTransform
1131
1132        return it(DropWhileTransform(self, self.__callback_overload_warpper__(predicate)))
1133
1134    def skip(self, n: int) -> Sequence[T]:
1135        """
1136        Returns a Sequence containing all elements except first [n] elements.
1137
1138        Example 1:
1139        >>> lst = ['a', 'b', 'c']
1140        >>> it(lst).skip(0).to_list()
1141        ['a', 'b', 'c']
1142
1143         Example 2:
1144        >>> lst = ['a', 'b', 'c']
1145        >>> it(lst).skip(1).to_list()
1146        ['b', 'c']
1147
1148        Example 2:
1149        >>> lst = ['a', 'b', 'c']
1150        >>> it(lst).skip(4).to_list()
1151        []
1152        """
1153        return self.drop(n)
1154
1155    @overload
1156    def skip_while(self, predicate: Callable[[T], bool]) -> Sequence[T]: ...
1157    @overload
1158    def skip_while(self, predicate: Callable[[T, int], bool]) -> Sequence[T]: ...
1159    @overload
1160    def skip_while(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Sequence[T]: ...
1161    def skip_while(self, predicate: Callable[..., bool]) -> Sequence[T]:
1162        """
1163        Returns a Sequence containing all elements except first elements that satisfy the given [predicate].
1164
1165        Example 1:
1166        >>> lst = [1, 2, 3, 4, 1]
1167        >>> it(lst).skip_while(lambda x: x < 3 ).to_list()
1168        [3, 4, 1]
1169        """
1170        return self.drop_while(predicate)
1171
1172    def take(self, n: int) -> Sequence[T]:
1173        """
1174        Returns an Sequence containing first [n] elements.
1175
1176        Example 1:
1177        >>> a = ['a', 'b', 'c']
1178        >>> it(a).take(0).to_list()
1179        []
1180
1181        Example 2:
1182        >>> a = ['a', 'b', 'c']
1183        >>> it(a).take(2).to_list()
1184        ['a', 'b']
1185        """
1186        if n < 0:
1187            raise ValueError(f"Requested element count {n} is less than zero.")
1188        if n == 0:
1189            return Sequence([])
1190        from .take import TakeTransform
1191
1192        return it(TakeTransform(self, n))
1193
1194    # noinspection PyShadowingNames
1195    @overload
1196    def take_while(self, predicate: Callable[[T], bool]) -> Sequence[T]: ...
1197    @overload
1198    def take_while(self, predicate: Callable[[T, int], bool]) -> Sequence[T]: ...
1199    @overload
1200    def take_while(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Sequence[T]: ...
1201    def take_while(self, predicate: Callable[..., bool]) -> Sequence[T]:
1202        """
1203        Returns an Sequence containing first elements satisfying the given [predicate].
1204
1205        Example 1:
1206        >>> lst = ['a', 'b', 'c', 'd']
1207        >>> it(lst).take_while(lambda x: x in ['a', 'b']).to_list()
1208        ['a', 'b']
1209        """
1210        from .take_while import TakeWhileTransform
1211
1212        return it(TakeWhileTransform(self, self.__callback_overload_warpper__(predicate)))
1213
1214    def take_last(self, n: int) -> Sequence[T]:
1215        """
1216        Returns an Sequence containing last [n] elements.
1217
1218        Example 1:
1219        >>> a = ['a', 'b', 'c']
1220        >>> it(a).take_last(0).to_list()
1221        []
1222
1223        Example 2:
1224        >>> a = ['a', 'b', 'c']
1225        >>> it(a).take_last(2).to_list()
1226        ['b', 'c']
1227        """
1228        if n < 0:
1229            raise ValueError(f"Requested element count {n} is less than zero.")
1230        if n == 0:
1231            return Sequence([])
1232
1233        return self.drop(len(self) - n)
1234
1235    # noinspection PyShadowingNames
1236    def sorted(self) -> Sequence[T]:
1237        """
1238        Returns an Sequence that yields elements of this Sequence sorted according to their natural sort order.
1239
1240        Example 1:
1241        >>> lst = ['b', 'a', 'e', 'c']
1242        >>> it(lst).sorted().to_list()
1243        ['a', 'b', 'c', 'e']
1244
1245         Example 2:
1246        >>> lst = [2, 1, 4, 3]
1247        >>> it(lst).sorted().to_list()
1248        [1, 2, 3, 4]
1249        """
1250        lst = list(self)
1251        lst.sort()  # type: ignore
1252        return it(lst)
1253
1254    # noinspection PyShadowingNames
1255    @overload
1256    def sorted_by(self, key_selector: Callable[[T], SupportsRichComparisonT]) -> Sequence[T]: ...
1257    @overload
1258    def sorted_by(
1259        self, key_selector: Callable[[T, int], SupportsRichComparisonT]
1260    ) -> Sequence[T]: ...
1261    @overload
1262    def sorted_by(
1263        self, key_selector: Callable[[T, int, Sequence[T]], SupportsRichComparisonT]
1264    ) -> Sequence[T]: ...
1265    def sorted_by(self, key_selector: Callable[..., SupportsRichComparisonT]) -> Sequence[T]:
1266        """
1267        Returns a sequence that yields elements of this sequence sorted according to natural sort
1268        order of the value returned by specified [key_selector] function.
1269
1270        Example 1:
1271        >>> lst = [ {'name': 'A', 'age': 12 }, {'name': 'C', 'age': 10 }, {'name': 'B', 'age': 11 } ]
1272        >>> it(lst).sorted_by(lambda x: x['name']).to_list()
1273        [{'name': 'A', 'age': 12}, {'name': 'B', 'age': 11}, {'name': 'C', 'age': 10}]
1274        >>> it(lst).sorted_by(lambda x: x['age']).to_list()
1275        [{'name': 'C', 'age': 10}, {'name': 'B', 'age': 11}, {'name': 'A', 'age': 12}]
1276        """
1277        lst = list(self)
1278        lst.sort(key=self.__callback_overload_warpper__(key_selector))
1279        return it(lst)
1280
1281    def sorted_descending(self) -> Sequence[T]:
1282        """
1283        Returns a Sequence of all elements sorted descending according to their natural sort order.
1284
1285        Example 1:
1286        >>> lst = ['b', 'c', 'a']
1287        >>> it(lst).sorted_descending().to_list()
1288        ['c', 'b', 'a']
1289        """
1290        return self.sorted().reversed()
1291
1292    @overload
1293    def sorted_by_descending(
1294        self, key_selector: Callable[[T], SupportsRichComparisonT]
1295    ) -> Sequence[T]: ...
1296    @overload
1297    def sorted_by_descending(
1298        self, key_selector: Callable[[T, int], SupportsRichComparisonT]
1299    ) -> Sequence[T]: ...
1300    @overload
1301    def sorted_by_descending(
1302        self, key_selector: Callable[[T, int, Sequence[T]], SupportsRichComparisonT]
1303    ) -> Sequence[T]: ...
1304    def sorted_by_descending(
1305        self, key_selector: Callable[..., SupportsRichComparisonT]
1306    ) -> Sequence[T]:
1307        """
1308        Returns a sequence that yields elements of this sequence sorted descending according
1309        to natural sort order of the value returned by specified [key_selector] function.
1310
1311        Example 1:
1312        >>> lst = [ {'name': 'A', 'age': 12 }, {'name': 'C', 'age': 10 }, {'name': 'B', 'age': 11 } ]
1313        >>> it(lst).sorted_by_descending(lambda x: x['name']).to_list()
1314        [{'name': 'C', 'age': 10}, {'name': 'B', 'age': 11}, {'name': 'A', 'age': 12}]
1315        >>> it(lst).sorted_by_descending(lambda x: x['age']).to_list()
1316        [{'name': 'A', 'age': 12}, {'name': 'B', 'age': 11}, {'name': 'C', 'age': 10}]
1317        """
1318        return self.sorted_by(key_selector).reversed()
1319
1320    # noinspection PyShadowingNames
1321    def sorted_with(self, comparator: Callable[[T, T], int]) -> Sequence[T]:
1322        """
1323        Returns a sequence that yields elements of this sequence sorted according to the specified [comparator].
1324
1325        Example 1:
1326        >>> lst = ['aa', 'bbb', 'c']
1327        >>> it(lst).sorted_with(lambda a, b: len(a)-len(b)).to_list()
1328        ['c', 'aa', 'bbb']
1329        """
1330        from functools import cmp_to_key
1331
1332        lst = list(self)
1333        lst.sort(key=cmp_to_key(comparator))
1334        return it(lst)
1335
1336    @overload
1337    def associate(self, transform: Callable[[T], Tuple[K, V]]) -> Dict[K, V]: ...
1338    @overload
1339    def associate(self, transform: Callable[[T, int], Tuple[K, V]]) -> Dict[K, V]: ...
1340    @overload
1341    def associate(self, transform: Callable[[T, int, Sequence[T]], Tuple[K, V]]) -> Dict[K, V]: ...
1342    def associate(self, transform: Callable[..., Tuple[K, V]]) -> Dict[K, V]:
1343        """
1344        Returns a [Dict] containing key-value Tuple provided by [transform] function
1345        applied to elements of the given Sequence.
1346
1347        Example 1:
1348        >>> lst = ['1', '2', '3']
1349        >>> it(lst).associate(lambda x: (int(x), x))
1350        {1: '1', 2: '2', 3: '3'}
1351        """
1352        transform = self.__callback_overload_warpper__(transform)
1353        dic: Dict[K, V] = dict()
1354        for i in self:
1355            k, v = transform(i)
1356            dic[k] = v
1357        return dic
1358
1359    @overload
1360    def associate_by(self, key_selector: Callable[[T], K]) -> Dict[K, T]: ...
1361    @overload
1362    def associate_by(self, key_selector: Callable[[T, int], K]) -> Dict[K, T]: ...
1363    @overload
1364    def associate_by(self, key_selector: Callable[[T, int, Sequence[T]], K]) -> Dict[K, T]: ...
1365    @overload
1366    def associate_by(
1367        self, key_selector: Callable[[T], K], value_transform: Callable[[T], V]
1368    ) -> Dict[K, V]: ...
1369    def associate_by(
1370        self,
1371        key_selector: Callable[..., K],
1372        value_transform: Optional[Callable[[T], V]] = None,
1373    ) -> Union[Dict[K, T], Dict[K, V]]:
1374        """
1375        Returns a [Dict] containing key-value Tuple provided by [transform] function
1376        applied to elements of the given Sequence.
1377
1378        Example 1:
1379        >>> lst = ['1', '2', '3']
1380        >>> it(lst).associate_by(lambda x: int(x))
1381        {1: '1', 2: '2', 3: '3'}
1382
1383        Example 2:
1384        >>> lst = ['1', '2', '3']
1385        >>> it(lst).associate_by(lambda x: int(x), lambda x: x+x)
1386        {1: '11', 2: '22', 3: '33'}
1387
1388        """
1389        key_selector = self.__callback_overload_warpper__(key_selector)
1390
1391        dic: Dict[K, Any] = dict()
1392        for i in self:
1393            k = key_selector(i)
1394            dic[k] = i if value_transform is None else value_transform(i)
1395        return dic
1396
1397    @overload
1398    def associate_by_to(
1399        self, destination: Dict[K, T], key_selector: Callable[[T], K]
1400    ) -> Dict[K, T]: ...
1401    @overload
1402    def associate_by_to(
1403        self,
1404        destination: Dict[K, V],
1405        key_selector: Callable[[T], K],
1406        value_transform: Callable[[T], V],
1407    ) -> Dict[K, V]: ...
1408    def associate_by_to(
1409        self,
1410        destination: Dict[K, Any],
1411        key_selector: Callable[[T], K],
1412        value_transform: Optional[Callable[[T], Any]] = None,
1413    ) -> Dict[K, Any]:
1414        """
1415        Returns a [Dict] containing key-value Tuple provided by [transform] function
1416        applied to elements of the given Sequence.
1417
1418        Example 1:
1419        >>> lst = ['1', '2', '3']
1420        >>> it(lst).associate_by_to({}, lambda x: int(x))
1421        {1: '1', 2: '2', 3: '3'}
1422
1423        Example 2:
1424        >>> lst = ['1', '2', '3']
1425        >>> it(lst).associate_by_to({}, lambda x: int(x), lambda x: x+'!' )
1426        {1: '1!', 2: '2!', 3: '3!'}
1427
1428        """
1429        for i in self:
1430            k = key_selector(i)
1431            destination[k] = i if value_transform is None else value_transform(i)
1432        return destination
1433
1434    @overload
1435    def all(self, predicate: Callable[[T], bool]) -> bool: ...
1436    @overload
1437    def all(self, predicate: Callable[[T, int], bool]) -> bool: ...
1438    @overload
1439    def all(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> bool: ...
1440    def all(self, predicate: Callable[..., bool]) -> bool:
1441        """
1442        Returns True if all elements of the Sequence satisfy the specified [predicate] function.
1443
1444        Example 1:
1445        >>> lst = [1, 2, 3]
1446        >>> it(lst).all(lambda x: x > 0)
1447        True
1448        >>> it(lst).all(lambda x: x > 1)
1449        False
1450        """
1451        predicate = self.__callback_overload_warpper__(predicate)
1452        for i in self:
1453            if not predicate(i):
1454                return False
1455        return True
1456
1457    @overload
1458    def any(self, predicate: Callable[[T], bool]) -> bool: ...
1459    @overload
1460    def any(self, predicate: Callable[[T, int], bool]) -> bool: ...
1461    @overload
1462    def any(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> bool: ...
1463    def any(self, predicate: Callable[..., bool]) -> bool:
1464        """
1465        Returns True if any elements of the Sequence satisfy the specified [predicate] function.
1466
1467        Example 1:
1468        >>> lst = [1, 2, 3]
1469        >>> it(lst).any(lambda x: x > 0)
1470        True
1471        >>> it(lst).any(lambda x: x > 3)
1472        False
1473        """
1474        predicate = self.__callback_overload_warpper__(predicate)
1475        for i in self:
1476            if predicate(i):
1477                return True
1478        return False
1479
1480    @overload
1481    def count(self) -> int: ...
1482    @overload
1483    def count(self, predicate: Callable[[T], bool]) -> int: ...
1484    @overload
1485    def count(self, predicate: Callable[[T, int], bool]) -> int: ...
1486    @overload
1487    def count(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> int: ...
1488    def count(self, predicate: Optional[Callable[..., bool]] = None) -> int:
1489        """
1490        Returns the number of elements in the Sequence that satisfy the specified [predicate] function.
1491
1492        Example 1:
1493        >>> lst = [1, 2, 3]
1494        >>> it(lst).count()
1495        3
1496        >>> it(lst).count(lambda x: x > 0)
1497        3
1498        >>> it(lst).count(lambda x: x > 2)
1499        1
1500        """
1501        if predicate is None:
1502            return len(self)
1503        predicate = self.__callback_overload_warpper__(predicate)
1504        return sum(1 for i in self if predicate(i))
1505
1506    def contains(self, value: T) -> bool:
1507        """
1508        Returns True if the Sequence contains the specified [value].
1509
1510        Example 1:
1511        >>> lst = [1, 2, 3]
1512        >>> it(lst).contains(1)
1513        True
1514        >>> it(lst).contains(4)
1515        False
1516        """
1517        return value in self
1518
1519    def element_at(self, index: int) -> T:
1520        """
1521        Returns the element at the specified [index] in the Sequence.
1522
1523        Example 1:
1524        >>> lst = [1, 2, 3]
1525        >>> it(lst).element_at(1)
1526        2
1527
1528        Example 2:
1529        >>> lst = [1, 2, 3]
1530        >>> it(lst).element_at(3)
1531        Traceback (most recent call last):
1532        ...
1533        IndexError: Index 3 out of range
1534        """
1535        return self.element_at_or_else(
1536            index, lambda index: throw(IndexError(f"Index {index} out of range"))
1537        )
1538
1539    @overload
1540    def element_at_or_else(self, index: int) -> Optional[T]:
1541        """
1542        Returns the element at the specified [index] in the Sequence or the [default] value if the index is out of bounds.
1543
1544        Example 1:
1545        >>> lst = [1, 2, 3]
1546        >>> it(lst).element_at_or_else(1, 'default')
1547        2
1548        >>> it(lst).element_at_or_else(4, lambda x: 'default')
1549        'default'
1550        """
1551        ...
1552
1553    @overload
1554    def element_at_or_else(self, index: int, default: T) -> T: ...
1555    @overload
1556    def element_at_or_else(self, index: int, default: Callable[[int], T]) -> T: ...
1557    def element_at_or_else(
1558        self, index: int, default: Union[Callable[[int], T], T, None] = None
1559    ) -> Optional[T]:
1560        """
1561        Returns the element at the specified [index] in the Sequence or the [default] value if the index is out of bounds.
1562
1563        Example 1:
1564        >>> lst = [1, 2, 3]
1565        >>> it(lst).element_at_or_else(1, lambda x: 'default')
1566        2
1567        >>> it(lst).element_at_or_else(4, lambda x: 'default')
1568        'default'
1569
1570        """
1571        if index >= 0:
1572            if (
1573                isinstance(self.__transform__, NonTransform)
1574                and isinstance(self.__transform__.iter, list)
1575                and index < len(self.__transform__.iter)
1576            ):
1577                return self.__transform__.iter[index]
1578            for i, e in enumerate(self):
1579                if i == index:
1580                    return e
1581        return default(index) if callable(default) else default  # type: ignore
1582
1583    def element_at_or_default(self, index: int, default: T) -> T:
1584        """
1585        Returns the element at the specified [index] in the Sequence or the [default] value if the index is out of bounds.
1586
1587        Example 1:
1588        >>> lst = [1, 2, 3]
1589        >>> it(lst).element_at_or_default(1, 'default')
1590        2
1591        >>> it(lst).element_at_or_default(4, 'default')
1592        'default'
1593
1594        """
1595        return self.element_at_or_else(index, default)
1596
1597    def element_at_or_none(self, index: int) -> Optional[T]:
1598        """
1599        Returns the element at the specified [index] in the Sequence or None if the index is out of bounds.
1600
1601        Example 1:
1602        >>> lst = [1, 2, 3]
1603        >>> it(lst).element_at_or_none(1)
1604        2
1605        >>> it(lst).element_at_or_none(4) is None
1606        True
1607        """
1608        return self.element_at_or_else(index)
1609
1610    def distinct(self) -> Sequence[T]:
1611        """
1612        Returns a new Sequence containing the distinct elements of the given Sequence.
1613
1614        Example 1:
1615        >>> lst = [1, 2, 3, 1, 2, 3]
1616        >>> it(lst).distinct().to_list()
1617        [1, 2, 3]
1618
1619        Example 2:
1620        >>> lst = [(1, 'A'), (1, 'A'), (1, 'A'), (2, 'A'), (3, 'C'), (3, 'D')]
1621        >>> it(lst).distinct().sorted().to_list()
1622        [(1, 'A'), (2, 'A'), (3, 'C'), (3, 'D')]
1623
1624        """
1625        from .distinct import DistinctTransform
1626
1627        return it(DistinctTransform(self))
1628
1629    @overload
1630    def distinct_by(self, key_selector: Callable[[T], Any]) -> Sequence[T]: ...
1631    @overload
1632    def distinct_by(self, key_selector: Callable[[T, int], Any]) -> Sequence[T]: ...
1633    @overload
1634    def distinct_by(self, key_selector: Callable[[T, int, Sequence[T]], Any]) -> Sequence[T]: ...
1635    def distinct_by(self, key_selector: Callable[..., Any]) -> Sequence[T]:
1636        """
1637        Returns a new Sequence containing the distinct elements of the given Sequence.
1638
1639        Example 1:
1640        >>> lst = [1, 2, 3, 1, 2, 3]
1641        >>> it(lst).distinct_by(lambda x: x%2).to_list()
1642        [1, 2]
1643        """
1644        from .distinct import DistinctTransform
1645
1646        return it(DistinctTransform(self, self.__callback_overload_warpper__(key_selector)))
1647
1648    @overload
1649    def reduce(self, accumulator: Callable[[T, T], T]) -> T: ...
1650    @overload
1651    def reduce(self, accumulator: Callable[[U, T], U], initial: U) -> U: ...
1652    def reduce(self, accumulator: Callable[..., U], initial: Optional[U] = None) -> Optional[U]:
1653        """
1654        Returns the result of applying the specified [accumulator] function to the given Sequence's elements.
1655
1656        Example 1:
1657        >>> lst = [1, 2, 3]
1658        >>> it(lst).reduce(lambda x, y: x+y)
1659        6
1660        """
1661        result: Optional[U] = initial
1662        for i, e in enumerate(self):
1663            if i == 0 and initial is None:
1664                result = e  # type: ignore
1665                continue
1666
1667            result = accumulator(result, e)
1668        return result
1669
1670    def fold(self, initial: U, accumulator: Callable[[U, T], U]) -> U:
1671        """
1672        Returns the result of applying the specified [accumulator] function to the given Sequence's elements.
1673
1674        Example 1:
1675        >>> lst = [1, 2, 3]
1676        >>> it(lst).fold(0, lambda x, y: x+y)
1677        6
1678        """
1679        return self.reduce(accumulator, initial)
1680
1681    @overload
1682    def sum_of(self, selector: Callable[[T], int]) -> int: ...
1683    @overload
1684    def sum_of(self, selector: Callable[[T], float]) -> float: ...
1685    def sum_of(self, selector: Callable[[T], Union[int, float]]) -> Union[int, float]:
1686        """
1687        Returns the sum of the elements of the given Sequence.
1688
1689        Example 1:
1690        >>> lst = [1, 2, 3]
1691        >>> it(lst).sum_of(lambda x: x)
1692        6
1693        """
1694        return sum(selector(i) for i in self)
1695
1696    @overload
1697    def max_of(self, selector: Callable[[T], int]) -> int: ...
1698    @overload
1699    def max_of(self, selector: Callable[[T], float]) -> float: ...
1700    def max_of(self, selector: Callable[[T], Union[int, float]]) -> Union[int, float]:
1701        """
1702        Returns the maximum element of the given Sequence.
1703
1704        Example 1:
1705        >>> lst = [1, 2, 3]
1706        >>> it(lst).max_of(lambda x: x)
1707        3
1708        """
1709        return max(selector(i) for i in self)
1710
1711    @overload
1712    def max_by_or_none(self, selector: Callable[[T], int]) -> Optional[T]: ...
1713    @overload
1714    def max_by_or_none(self, selector: Callable[[T], float]) -> Optional[T]: ...
1715    def max_by_or_none(self, selector: Callable[[T], Union[float, int]]) -> Optional[T]:
1716        """
1717        Returns the first element yielding the largest value of the given function
1718        or `none` if there are no elements.
1719
1720        Example 1:
1721        >>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
1722        >>> it(lst).max_by_or_none(lambda x: x["num"])
1723        {'name': 'B', 'num': 200}
1724
1725        Example 2:
1726        >>> lst = []
1727        >>> it(lst).max_by_or_none(lambda x: x["num"])
1728        """
1729
1730        max_item = None
1731        max_val = None
1732
1733        for item in self:
1734            val = selector(item)
1735            if max_val is None or val > max_val:
1736                max_item = item
1737                max_val = val
1738
1739        return max_item
1740
1741    @overload
1742    def max_by(self, selector: Callable[[T], int]) -> T: ...
1743    @overload
1744    def max_by(self, selector: Callable[[T], float]) -> T: ...
1745    def max_by(self, selector: Callable[[T], Union[float, int]]) -> T:
1746        """
1747        Returns the first element yielding the largest value of the given function.
1748
1749        Example 1:
1750        >>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
1751        >>> it(lst).max_by(lambda x: x["num"])
1752        {'name': 'B', 'num': 200}
1753
1754        Exmaple 2:
1755        >>> lst = []
1756        >>> it(lst).max_by(lambda x: x["num"])
1757        Traceback (most recent call last):
1758        ...
1759        ValueError: Sequence is empty.
1760        """
1761        max_item = self.max_by_or_none(selector)
1762        if max_item is None:
1763            raise ValueError("Sequence is empty.")
1764        return max_item
1765
1766    @overload
1767    def min_of(self, selector: Callable[[T], int]) -> int:
1768        """
1769        Returns the minimum element of the given Sequence.
1770
1771        Example 1:
1772        >>> lst = [1, 2, 3]
1773        >>> it(lst).min_of(lambda x: x)
1774        1
1775        """
1776        ...
1777
1778    @overload
1779    def min_of(self, selector: Callable[[T], float]) -> float: ...
1780    def min_of(self, selector: Callable[[T], Union[int, float]]) -> Union[int, float]:
1781        return min(selector(i) for i in self)
1782
1783    @overload
1784    def min_by_or_none(self, selector: Callable[[T], int]) -> Optional[T]: ...
1785    @overload
1786    def min_by_or_none(self, selector: Callable[[T], float]) -> Optional[T]: ...
1787    def min_by_or_none(self, selector: Callable[[T], float]) -> Optional[T]:
1788        """
1789        Returns the first element yielding the smallest value of the given function
1790        or `none` if there are no elements.
1791
1792        Example 1:
1793        >>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
1794        >>> it(lst).min_by_or_none(lambda x: x["num"])
1795        {'name': 'A', 'num': 100}
1796
1797        Exmaple 2:
1798        >>> lst = []
1799        >>> it(lst).min_by_or_none(lambda x: x["num"])
1800        """
1801        min_item = None
1802        min_val = None
1803
1804        for item in self:
1805            val = selector(item)
1806            if min_val is None or val < min_val:
1807                min_item = item
1808                min_val = val
1809
1810        return min_item
1811
1812    @overload
1813    def min_by(self, selector: Callable[[T], int]) -> T: ...
1814    @overload
1815    def min_by(self, selector: Callable[[T], float]) -> T: ...
1816    def min_by(self, selector: Callable[[T], float]) -> T:
1817        """
1818        Returns the first element yielding the smallest value of the given function.
1819
1820        Example 1:
1821        >>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
1822        >>> it(lst).min_by(lambda x: x["num"])
1823        {'name': 'A', 'num': 100}
1824
1825        Exmaple 2:
1826        >>> lst = []
1827        >>> it(lst).min_by(lambda x: x["num"])
1828        Traceback (most recent call last):
1829        ...
1830        ValueError: Sequence is empty.
1831        """
1832        min_item = self.min_by_or_none(selector)
1833        if min_item is None:
1834            raise ValueError("Sequence is empty.")
1835
1836        return min_item
1837
1838    def mean_of(self, selector: Callable[[T], Union[int, float]]) -> Union[int, float]:
1839        """
1840        Returns the mean of the elements of the given Sequence.
1841
1842        Example 1:
1843        >>> lst = [1, 2, 3]
1844        >>> it(lst).mean_of(lambda x: x)
1845        2.0
1846        """
1847        return self.sum_of(selector) / len(self)
1848
1849    @overload
1850    def sum(self: Sequence[int]) -> int:
1851        """
1852        Returns the sum of the elements of the given Sequence.
1853
1854        Example 1:
1855        >>> lst = [1, 2, 3]
1856        >>> it(lst).sum()
1857        6
1858        """
1859        ...
1860
1861    @overload
1862    def sum(self: Sequence[float]) -> float: ...
1863    def sum(self: Union[Sequence[int], Sequence[float]]) -> Union[float, int]:
1864        """
1865        Returns the sum of the elements of the given Sequence.
1866
1867        Example 1:
1868        >>> lst = [1, 2, 3]
1869        >>> it(lst).sum()
1870        6
1871        """
1872        return sum(self)
1873
1874    @overload
1875    def max(self: Sequence[int]) -> int: ...
1876    @overload
1877    def max(self: Sequence[float]) -> float: ...
1878    def max(self: Union[Sequence[int], Sequence[float]]) -> Union[float, int]:
1879        """
1880        Returns the maximum element of the given Sequence.
1881
1882        Example 1:
1883        >>> lst = [1, 2, 3]
1884        >>> it(lst).max()
1885        3
1886        """
1887        return max(self)
1888
1889    @overload
1890    def max_or_default(self: Sequence[int]) -> int: ...
1891    @overload
1892    def max_or_default(self: Sequence[int], default: V) -> Union[int, V]: ...
1893    @overload
1894    def max_or_default(self: Sequence[float]) -> float: ...
1895    @overload
1896    def max_or_default(self: Sequence[float], default: V) -> Union[float, V]: ...
1897    def max_or_default(
1898        self: Union[Sequence[int], Sequence[float]], default: Optional[V] = None
1899    ) -> Union[float, int, V, None]:
1900        """
1901        Returns the maximum element of the given Sequence.
1902
1903        Example 1:
1904        >>> lst = [1, 2, 3]
1905        >>> it(lst).max_or_default()
1906        3
1907
1908        Example 2:
1909        >>> lst = []
1910        >>> it(lst).max_or_default() is None
1911        True
1912
1913        Example 3:
1914        >>> lst = []
1915        >>> it(lst).max_or_default(9)
1916        9
1917        """
1918        if self.is_empty():
1919            return default
1920        return max(self)
1921
1922    @overload
1923    def max_or_none(self: Sequence[int]) -> int: ...
1924    @overload
1925    def max_or_none(self: Sequence[float]) -> float: ...
1926    def max_or_none(
1927        self: Union[Sequence[int], Sequence[float]],
1928    ) -> Union[float, int, None]:
1929        """
1930        Returns the maximum element of the given Sequence.
1931
1932        Example 1:
1933        >>> lst = [1, 2, 3]
1934        >>> it(lst).max_or_none()
1935        3
1936
1937        Example 2:
1938        >>> lst = []
1939        >>> it(lst).max_or_none() is None
1940        True
1941        """
1942        return self.max_or_default(None)
1943
1944    @overload
1945    def min(self: Sequence[int]) -> int:
1946        """
1947        Returns the minimum element of the given Sequence.
1948
1949        Example 1:
1950        >>> lst = [1, 2, 3]
1951        >>> it(lst).min()
1952        1
1953        """
1954        ...
1955
1956    @overload
1957    def min(self: Sequence[float]) -> float: ...
1958    def min(self: Union[Sequence[int], Sequence[float]]) -> Union[float, int]:
1959        """
1960        Returns the minimum element of the given Sequence.
1961
1962        Example 1:
1963        >>> lst = [1, 2, 3]
1964        >>> it(lst).min()
1965        1
1966        """
1967        return min(self)
1968
1969    @overload
1970    def min_or_none(self: Sequence[int]) -> Optional[int]:
1971        """
1972        Returns the minimum element of the given Sequence.
1973
1974        Example 1:
1975        >>> lst = [1, 2, 3]
1976        >>> it(lst).min_or_none()
1977        1
1978        """
1979        ...
1980
1981    @overload
1982    def min_or_none(self: Sequence[float]) -> Optional[float]: ...
1983    def min_or_none(
1984        self: Union[Sequence[int], Sequence[float]],
1985    ) -> Union[float, int, None]:
1986        """
1987        Returns the minimum element of the given Sequence.
1988
1989        Example 1:
1990        >>> lst = [1, 2, 3]
1991        >>> it(lst).min_or_none()
1992        1
1993        """
1994        return self.min_or_default(None)
1995
1996    @overload
1997    def min_or_default(self: Sequence[int]) -> int:
1998        """
1999        Returns the minimum element of the given Sequence.
2000
2001        Example 1:
2002        >>> lst = [1, 2, 3]
2003        >>> it(lst).min_or_default()
2004        1
2005        """
2006        ...
2007
2008    @overload
2009    def min_or_default(self: Sequence[int], default: V) -> Union[int, V]: ...
2010    @overload
2011    def min_or_default(self: Sequence[float]) -> float: ...
2012    @overload
2013    def min_or_default(self: Sequence[float], default: V) -> Union[float, V]: ...
2014    def min_or_default(
2015        self: Union[Sequence[int], Sequence[float]], default: Optional[V] = None
2016    ) -> Union[float, int, V, None]:
2017        """
2018        Returns the minimum element of the given Sequence.
2019
2020        Example 1:
2021        >>> lst = [1, 2, 3]
2022        >>> it(lst).min_or_default()
2023        1
2024
2025        Example 2:
2026        >>> lst = []
2027        >>> it(lst).min_or_default(9)
2028        9
2029        """
2030        if self.is_empty():
2031            return default
2032        return min(self)
2033
2034    @overload
2035    def mean(self: Sequence[int]) -> float:
2036        """
2037        Returns the mean of the elements of the given Sequence.
2038
2039        Example 1:
2040        >>> lst = [1, 2, 3]
2041        >>> it(lst).mean()
2042        2.0
2043        """
2044        ...
2045
2046    @overload
2047    def mean(self: Sequence[float]) -> float: ...
2048    def mean(self: Union[Sequence[int], Sequence[float]]) -> float:
2049        """
2050        Returns the mean of the elements of the given Sequence.
2051
2052        Example 1:
2053        >>> lst = [1, 2, 3]
2054        >>> it(lst).mean()
2055        2.0
2056        """
2057        return self.sum() / len(self)
2058
2059    # noinspection PyShadowingNames
2060    def reversed(self) -> Sequence[T]:
2061        """
2062        Returns a list with elements in reversed order.
2063
2064        Example 1:
2065        >>> lst = ['b', 'c', 'a']
2066        >>> it(lst).reversed().to_list()
2067        ['a', 'c', 'b']
2068        """
2069        lst = list(self)
2070        lst.reverse()
2071        return it(lst)
2072
2073    @overload
2074    def flat_map(self, transform: Callable[[T], Iterable[U]]) -> Sequence[U]: ...
2075    @overload
2076    def flat_map(self, transform: Callable[[T, int], Iterable[U]]) -> Sequence[U]: ...
2077    @overload
2078    def flat_map(self, transform: Callable[[T, int, Sequence[T]], Iterable[U]]) -> Sequence[U]: ...
2079    def flat_map(self, transform: Callable[..., Iterable[U]]) -> Sequence[U]:
2080        """
2081        Returns a single list of all elements yielded from results of [transform]
2082        function being invoked on each element of original collection.
2083
2084        Example 1:
2085        >>> lst = [['a', 'b'], ['c'], ['d', 'e']]
2086        >>> it(lst).flat_map(lambda x: x).to_list()
2087        ['a', 'b', 'c', 'd', 'e']
2088        """
2089        return self.map(transform).flatten()
2090
2091    def flatten(self: Iterable[Iterable[U]]) -> Sequence[U]:
2092        """
2093        Returns a sequence of all elements from all sequences in this sequence.
2094
2095        Example 1:
2096        >>> lst = [['a', 'b'], ['c'], ['d', 'e']]
2097        >>> it(lst).flatten().to_list()
2098        ['a', 'b', 'c', 'd', 'e']
2099        """
2100        from .flattening import FlatteningTransform
2101
2102        return it(FlatteningTransform(self))
2103
2104    @overload
2105    def group_by(self, key_selector: Callable[[T], K]) -> Sequence[Grouping[K, T]]: ...
2106    @overload
2107    def group_by(self, key_selector: Callable[[T, int], K]) -> Sequence[Grouping[K, T]]: ...
2108    @overload
2109    def group_by(
2110        self, key_selector: Callable[[T, int, Sequence[T]], K]
2111    ) -> Sequence[Grouping[K, T]]: ...
2112    def group_by(self, key_selector: Callable[..., K]) -> Sequence[Grouping[K, T]]:
2113        """
2114        Returns a dictionary with keys being the result of [key_selector] function being invoked on each element of original collection
2115        and values being the corresponding elements of original collection.
2116
2117        Example 1:
2118        >>> lst = [1, 2, 3, 4, 5]
2119        >>> it(lst).group_by(lambda x: x%2).map(lambda x: (x.key, x.values.to_list())).to_list()
2120        [(1, [1, 3, 5]), (0, [2, 4])]
2121        """
2122        from .grouping import GroupingTransform
2123
2124        return it(GroupingTransform(self, self.__callback_overload_warpper__(key_selector)))
2125
2126    @overload
2127    def group_by_to(
2128        self, destination: Dict[K, List[T]], key_selector: Callable[[T], K]
2129    ) -> Dict[K, List[T]]: ...
2130    @overload
2131    def group_by_to(
2132        self, destination: Dict[K, List[T]], key_selector: Callable[[T, int], K]
2133    ) -> Dict[K, List[T]]: ...
2134    @overload
2135    def group_by_to(
2136        self,
2137        destination: Dict[K, List[T]],
2138        key_selector: Callable[[T, int, Sequence[T]], K],
2139    ) -> Dict[K, List[T]]: ...
2140    def group_by_to(
2141        self, destination: Dict[K, List[T]], key_selector: Callable[..., K]
2142    ) -> Dict[K, List[T]]:
2143        """
2144        Returns a dictionary with keys being the result of [key_selector] function being invoked on each element of original collection
2145        and values being the corresponding elements of original collection.
2146
2147        Example 1:
2148        >>> lst = [1, 2, 3, 4, 5]
2149        >>> it(lst).group_by_to({}, lambda x: x%2)
2150        {1: [1, 3, 5], 0: [2, 4]}
2151        """
2152        key_selector = self.__callback_overload_warpper__(key_selector)
2153        for e in self:
2154            k = key_selector(e)
2155            if k not in destination:
2156                destination[k] = []
2157            destination[k].append(e)
2158        return destination
2159
2160    @overload
2161    def for_each(self, action: Callable[[T], None]) -> None: ...
2162    @overload
2163    def for_each(self, action: Callable[[T, int], None]) -> None: ...
2164    @overload
2165    def for_each(self, action: Callable[[T, int, Sequence[T]], None]) -> None: ...
2166    def for_each(self, action: Callable[..., None]) -> None:
2167        """
2168        Invokes [action] function on each element of the given Sequence.
2169
2170        Example 1:
2171        >>> lst = ['a', 'b', 'c']
2172        >>> it(lst).for_each(lambda x: print(x))
2173        a
2174        b
2175        c
2176
2177        Example 2:
2178        >>> lst = ['a', 'b', 'c']
2179        >>> it(lst).for_each(lambda x, i: print(x, i))
2180        a 0
2181        b 1
2182        c 2
2183        """
2184        self.on_each(action)
2185
2186    @overload
2187    def parallel_for_each(
2188        self, action: Callable[[T], None], max_workers: Optional[int] = None
2189    ) -> None: ...
2190    @overload
2191    def parallel_for_each(
2192        self, action: Callable[[T, int], None], max_workers: Optional[int] = None
2193    ) -> None: ...
2194    @overload
2195    def parallel_for_each(
2196        self,
2197        action: Callable[[T, int, Sequence[T]], None],
2198        max_workers: Optional[int] = None,
2199    ) -> None: ...
2200    def parallel_for_each(
2201        self, action: Callable[..., None], max_workers: Optional[int] = None
2202    ) -> None:
2203        """
2204        Invokes [action] function on each element of the given Sequence in parallel.
2205
2206        Example 1:
2207        >>> lst = ['a', 'b', 'c']
2208        >>> it(lst).parallel_for_each(lambda x: print(x))
2209        a
2210        b
2211        c
2212
2213        Example 2:
2214        >>> lst = ['a', 'b', 'c']
2215        >>> it(lst).parallel_for_each(lambda x: print(x), max_workers=2)
2216        a
2217        b
2218        c
2219        """
2220        self.parallel_on_each(action, max_workers)
2221
2222    @overload
2223    def on_each(self, action: Callable[[T], None]) -> Sequence[T]: ...
2224    @overload
2225    def on_each(self, action: Callable[[T, int], None]) -> Sequence[T]: ...
2226    @overload
2227    def on_each(self, action: Callable[[T, int, Sequence[T]], None]) -> Sequence[T]: ...
2228    def on_each(self, action: Callable[..., None]) -> Sequence[T]:
2229        """
2230        Invokes [action] function on each element of the given Sequence.
2231
2232        Example 1:
2233        >>> lst = ['a', 'b', 'c']
2234        >>> it(lst).on_each(lambda x: print(x)) and None
2235        a
2236        b
2237        c
2238
2239        Example 2:
2240        >>> lst = ['a', 'b', 'c']
2241        >>> it(lst).on_each(lambda x, i: print(x, i)) and None
2242        a 0
2243        b 1
2244        c 2
2245        """
2246        action = self.__callback_overload_warpper__(action)
2247        for i in self:
2248            action(i)
2249        return self
2250
2251    @overload
2252    def parallel_on_each(
2253        self,
2254        action: Callable[[T], None],
2255        max_workers: Optional[int] = None,
2256        chunksize: int = 1,
2257        executor: "ParallelMappingTransform.Executor" = "Thread",
2258    ) -> Sequence[T]: ...
2259    @overload
2260    def parallel_on_each(
2261        self,
2262        action: Callable[[T, int], None],
2263        max_workers: Optional[int] = None,
2264        chunksize: int = 1,
2265        executor: "ParallelMappingTransform.Executor" = "Thread",
2266    ) -> Sequence[T]: ...
2267    @overload
2268    def parallel_on_each(
2269        self,
2270        action: Callable[[T, int, Sequence[T]], None],
2271        max_workers: Optional[int] = None,
2272        chunksize: int = 1,
2273        executor: "ParallelMappingTransform.Executor" = "Thread",
2274    ) -> Sequence[T]: ...
2275    def parallel_on_each(
2276        self,
2277        action: Callable[..., None],
2278        max_workers: Optional[int] = None,
2279        chunksize: int = 1,
2280        executor: "ParallelMappingTransform.Executor" = "Thread",
2281    ) -> Sequence[T]:
2282        """
2283        Invokes [action] function on each element of the given Sequence.
2284
2285        Example 1:
2286        >>> lst = ['a', 'b', 'c']
2287        >>> it(lst).parallel_on_each(lambda x: print(x)) and None
2288        a
2289        b
2290        c
2291
2292        Example 2:
2293        >>> lst = ['a', 'b', 'c']
2294        >>> it(lst).parallel_on_each(lambda x: print(x), max_workers=2) and None
2295        a
2296        b
2297        c
2298        """
2299        from .parallel_mapping import ParallelMappingTransform
2300
2301        action = self.__callback_overload_warpper__(action)
2302        for _ in ParallelMappingTransform(self, action, max_workers, chunksize, executor):
2303            pass
2304        return self
2305
2306    @overload
2307    def zip(self, other: Iterable[U]) -> Sequence[Tuple[T, U]]: ...
2308    @overload
2309    def zip(self, other: Iterable[U], transform: Callable[[T, U], V]) -> Sequence[V]: ...
2310    def zip(
2311        self,
2312        other: Iterable[Any],
2313        transform: Optional[Callable[..., V]] = None,  # type: ignore
2314    ) -> Sequence[Any]:
2315        """
2316        Returns a new Sequence of tuples, where each tuple contains two elements.
2317
2318        Example 1:
2319        >>> lst1 = ['a', 'b', 'c']
2320        >>> lst2 = [1, 2, 3]
2321        >>> it(lst1).zip(lst2).to_list()
2322        [('a', 1), ('b', 2), ('c', 3)]
2323
2324        Example 2:
2325        >>> lst1 = ['a', 'b', 'c']
2326        >>> lst2 = [1, 2, 3]
2327        >>> it(lst1).zip(lst2, lambda x, y: x + '__' +str( y)).to_list()
2328        ['a__1', 'b__2', 'c__3']
2329        """
2330        if transform is None:
2331
2332            def transform(*x: Any) -> Tuple[Any, ...]:
2333                return (*x,)
2334
2335        from .merging import MergingTransform
2336
2337        return it(MergingTransform(self, other, transform))
2338
2339    @overload
2340    def zip_with_next(self) -> Sequence[Tuple[T, T]]: ...
2341    @overload
2342    def zip_with_next(self, transform: Callable[[T, T], V]) -> Sequence[V]: ...
2343    def zip_with_next(self, transform: Optional[Callable[[T, T], Any]] = None) -> Sequence[Any]:
2344        """
2345        Returns a sequence containing the results of applying the given [transform] function
2346        to an each pair of two adjacent elements in this sequence.
2347
2348        Example 1:
2349        >>> lst = ['a', 'b', 'c']
2350        >>> it(lst).zip_with_next(lambda x, y: x + '__' + y).to_list()
2351        ['a__b', 'b__c']
2352
2353        Example 2:
2354        >>> lst = ['a', 'b', 'c']
2355        >>> it(lst).zip_with_next().to_list()
2356        [('a', 'b'), ('b', 'c')]
2357        """
2358        from .merging_with_next import MergingWithNextTransform
2359
2360        return it(MergingWithNextTransform(self, transform or (lambda a, b: (a, b))))
2361
2362    @overload
2363    def unzip(self: Sequence[Tuple[U, V]]) -> "Tuple[ListLike[U], ListLike[V]]": ...
2364    @overload
2365    def unzip(self, transform: Callable[[T], Tuple[U, V]]) -> "Tuple[ListLike[U], ListLike[V]]": ...
2366    @overload
2367    def unzip(
2368        self, transform: Callable[[T, int], Tuple[U, V]]
2369    ) -> "Tuple[ListLike[U], ListLike[V]]": ...
2370    @overload
2371    def unzip(
2372        self, transform: Callable[[T, int, Sequence[T]], Tuple[U, V]]
2373    ) -> "Tuple[ListLike[U], ListLike[V]]": ...
2374    def unzip(  # type: ignore
2375        self: Sequence[Tuple[U, V]],
2376        transform: Union[Optional[Callable[..., Tuple[Any, Any]]], bool] = None,
2377    ) -> "Tuple[ListLike[U], ListLike[V]]":
2378        """
2379        Returns a pair of lists, where first list is built from the first values of each pair from this array, second list is built from the second values of each pair from this array.
2380
2381        Example 1:
2382        >>> lst = [{'name': 'a', 'age': 11}, {'name': 'b', 'age': 12}, {'name': 'c', 'age': 13}]
2383        >>> a, b = it(lst).unzip(lambda x: (x['name'], x['age']))
2384        >>> a
2385        ['a', 'b', 'c']
2386        >>> b
2387        [11, 12, 13]
2388
2389        Example 1:
2390        >>> lst = [('a', 11), ('b', 12), ('c', 13)]
2391        >>> a, b = it(lst).unzip()
2392        >>> a
2393        ['a', 'b', 'c']
2394        >>> b
2395        [11, 12, 13]
2396        """
2397        from .list_like import ListLike
2398
2399        it = self
2400        if isinstance(transform, bool):
2401            transform = None
2402
2403        if transform is not None:
2404            transform = self.__callback_overload_warpper__(transform)
2405            it = it.map(transform)
2406
2407        a = it.map(lambda x: x[0])  # type: ignore
2408        b = it.map(lambda x: x[1])  # type: ignore
2409
2410        return ListLike(a), ListLike(b)
2411
2412    def with_index(self):
2413        """
2414        Returns a sequence containing the elements of this sequence and their indexes.
2415
2416        Example 1:
2417        >>> lst = ['a', 'b', 'c']
2418        >>> it(lst).with_index().to_list()
2419        [IndexedValue(0, a), IndexedValue(1, b), IndexedValue(2, c)]
2420        """
2421        return self.indexed()
2422
2423    @overload
2424    def shuffled(self) -> Sequence[T]: ...
2425    @overload
2426    def shuffled(self, seed: int) -> Sequence[T]: ...
2427    @overload
2428    def shuffled(self, seed: str) -> Sequence[T]: ...
2429    @overload
2430    def shuffled(self, random: "Random") -> Sequence[T]: ...
2431    def shuffled(  # type: ignore
2432        self, random: Optional[Union["Random", int, str]] = None
2433    ) -> Sequence[T]:
2434        """
2435        Returns a sequence that yields elements of this sequence randomly shuffled
2436        using the specified [random] instance as the source of randomness.
2437
2438        Example 1:
2439        >>> lst = ['a', 'b', 'c']
2440        >>> it(lst).shuffled('123').to_list()
2441        ['b', 'a', 'c']
2442
2443        Example 2:
2444        >>> from random import Random
2445        >>> lst = ['a', 'b', 'c']
2446        >>> it(lst).shuffled(Random('123')).to_list()
2447        ['b', 'a', 'c']
2448
2449        Example 3:
2450        >>> lst = ['a', 'b', 'c']
2451        >>> it(lst).shuffled(123).to_list()
2452        ['c', 'b', 'a']
2453        """
2454        from .shuffling import ShufflingTransform
2455
2456        return it(ShufflingTransform(self, random))
2457
2458    @overload
2459    def partition(self, predicate: Callable[[T], bool]) -> "Tuple[ListLike[T], ListLike[T]]": ...
2460    @overload
2461    def partition(
2462        self, predicate: Callable[[T, int], bool]
2463    ) -> "Tuple[ListLike[T], ListLike[T]]": ...
2464    @overload
2465    def partition(
2466        self, predicate: Callable[[T, int, Sequence[T]], bool]
2467    ) -> "Tuple[ListLike[T], ListLike[T]]": ...
2468    def partition(self, predicate: Callable[..., bool]) -> "Tuple[ListLike[T], ListLike[T]]":
2469        """
2470        Partitions the elements of the given Sequence into two groups,
2471        the first group containing the elements for which the predicate returns true,
2472        and the second containing the rest.
2473
2474        Example 1:
2475        >>> lst = ['a', 'b', 'c', '2']
2476        >>> it(lst).partition(lambda x: x.isalpha())
2477        (['a', 'b', 'c'], ['2'])
2478
2479        Example 2:
2480        >>> lst = ['a', 'b', 'c', '2']
2481        >>> it(lst).partition(lambda _, i: i % 2 == 0)
2482        (['a', 'c'], ['b', '2'])
2483        """
2484        from .list_like import ListLike
2485
2486        predicate_a = self.__callback_overload_warpper__(predicate)
2487        predicate_b = self.__callback_overload_warpper__(predicate)
2488        part_a = self.filter(predicate_a)
2489        part_b = self.filter(lambda x: not predicate_b(x))
2490        return ListLike(part_a), ListLike(part_b)
2491
2492    def indexed(self) -> Sequence[IndexedValue[T]]:
2493        return self.map(lambda x, i: IndexedValue(x, i))
2494
2495    @overload
2496    def combinations(self, n: Literal[2]) -> Sequence[Tuple[T, T]]: ...
2497    @overload
2498    def combinations(self, n: Literal[3]) -> Sequence[Tuple[T, T, T]]: ...
2499    @overload
2500    def combinations(self, n: Literal[4]) -> Sequence[Tuple[T, T, T, T]]: ...
2501    @overload
2502    def combinations(self, n: Literal[5]) -> Sequence[Tuple[T, T, T, T, T]]: ...
2503    def combinations(self, n: int) -> Sequence[Tuple[T, ...]]:
2504        """
2505        Returns a Sequence of all possible combinations of size [n] from the given Sequence.
2506
2507        Example 1:
2508        >>> lst = ['a', 'b', 'c']
2509        >>> it(lst).combinations(2).to_list()
2510        [('a', 'b'), ('a', 'c'), ('b', 'c')]
2511        """
2512        from .combination import CombinationTransform
2513
2514        return it(CombinationTransform(self, n))
2515
2516    def nth(self, n: int) -> T:
2517        """
2518        Returns the nth element of the given Sequence.
2519
2520        Example 1:
2521        >>> lst = ['a', 'b', 'c']
2522        >>> it(lst).nth(2)
2523        'c'
2524        """
2525        return self.skip(n).first()
2526
2527    def windowed(self, size: int, step: int = 1, partialWindows: bool = False) -> Sequence[List[T]]:
2528        """
2529         Returns a Sequence of all possible sliding windows of size [size] from the given Sequence.
2530
2531        Example 1:
2532        >>> lst = ['a', 'b', 'c', 'd', 'e']
2533        >>> it(lst).windowed(3).to_list()
2534        [['a', 'b', 'c'], ['b', 'c', 'd'], ['c', 'd', 'e']]
2535
2536        Example 2:
2537        >>> lst = ['a', 'b', 'c', 'd', 'e']
2538        >>> it(lst).windowed(3, 2).to_list()
2539        [['a', 'b', 'c'], ['c', 'd', 'e']]
2540
2541        Example 3:
2542        >>> lst = ['a', 'b', 'c', 'd', 'e', 'f']
2543        >>> it(lst).windowed(3, 2, True).to_list()
2544        [['a', 'b', 'c'], ['c', 'd', 'e'], ['e', 'f']]
2545        """
2546        from .windowed import WindowedTransform
2547
2548        return it(WindowedTransform(self, size, step, partialWindows))
2549
2550    def chunked(self, size: int) -> Sequence[List[T]]:
2551        """
2552        Returns a Sequence of all possible chunks of size [size] from the given Sequence.
2553
2554        Example 1:
2555        >>> lst = ['a', 'b', 'c', 'd', 'e']
2556        >>> it(lst).chunked(3).to_list()
2557        [['a', 'b', 'c'], ['d', 'e']]
2558
2559
2560        Example 2:
2561        >>> lst = ['a', 'b', 'c', 'd', 'e', 'f']
2562        >>> it(lst).chunked(3).to_list()
2563        [['a', 'b', 'c'], ['d', 'e', 'f']]
2564        """
2565        return self.windowed(size, size, True)
2566
2567    def repeat(self, n: int) -> Sequence[T]:
2568        """
2569        Returns a Sequence containing this sequence repeated n times.
2570
2571        Example 1:
2572        >>> lst = ['a', 'b']
2573        >>> it(lst).repeat(3).to_list()
2574        ['a', 'b', 'a', 'b', 'a', 'b']
2575        """
2576        from .concat import ConcatTransform
2577
2578        return it(ConcatTransform([self] * n))
2579
2580    def concat(self, *other: Sequence[T]) -> Sequence[T]:
2581        """
2582        Returns a Sequence of all elements of the given Sequence, followed by all elements of the given Sequence.
2583
2584        Example 1:
2585        >>> lst1 = ['a', 'b', 'c']
2586        >>> lst2 = [1, 2, 3]
2587        >>> it(lst1).concat(lst2).to_list()
2588        ['a', 'b', 'c', 1, 2, 3]
2589
2590        Example 2:
2591        >>> lst1 = ['a', 'b', 'c']
2592        >>> lst2 = [1, 2, 3]
2593        >>> lst3 = [4, 5, 6]
2594        >>> it(lst1).concat(lst2, lst3).to_list()
2595        ['a', 'b', 'c', 1, 2, 3, 4, 5, 6]
2596        """
2597        from .concat import ConcatTransform
2598
2599        return it(ConcatTransform([self, *other]))
2600
2601    def intersect(self, *other: Sequence[T]) -> Sequence[T]:
2602        """
2603        Returns a set containing all elements that are contained by both this collection and the specified collection.
2604
2605        The returned set preserves the element iteration order of the original collection.
2606
2607        To get a set containing all elements that are contained at least in one of these collections use union.
2608
2609        Example 1:
2610        >>> lst1 = ['a', 'b', 'c']
2611        >>> lst2 = ['a2', 'b2', 'c']
2612        >>> it(lst1).intersect(lst2).to_list()
2613        ['c']
2614
2615        Example 2:
2616        >>> lst1 = ['a', 'b', 'c']
2617        >>> lst2 = ['a2', 'b', 'c']
2618        >>> lst3 = ['a3', 'b', 'c3']
2619        >>> it(lst1).intersect(lst2, lst3).to_list()
2620        ['b']
2621
2622
2623        Example 1:
2624        >>> lst1 = ['a', 'a', 'c']
2625        >>> lst2 = ['a2', 'b2', 'a']
2626        >>> it(lst1).intersect(lst2).to_list()
2627        ['a']
2628        """
2629        from .intersection import IntersectionTransform
2630
2631        return it(IntersectionTransform([self, *other]))
2632
2633    def union(self, *other: Sequence[T]) -> Sequence[T]:
2634        """
2635        Returns a set containing all distinct elements from both collections.
2636
2637        The returned set preserves the element iteration order of the original collection. Those elements of the other collection that are unique are iterated in the end in the order of the other collection.
2638
2639        To get a set containing all elements that are contained in both collections use intersect.
2640
2641        Example 1:
2642        >>> lst1 = ['a', 'b', 'c']
2643        >>> lst2 = ['a2', 'b2', 'c']
2644        >>> it(lst1).union(lst2).to_list()
2645        ['a', 'b', 'c', 'a2', 'b2']
2646
2647        Example 2:
2648        >>> lst1 = ['a', 'b', 'c']
2649        >>> lst2 = ['a2', 'b', 'c']
2650        >>> lst3 = ['a3', 'b', 'c3']
2651        >>> it(lst1).union(lst2, lst3).to_list()
2652        ['a', 'b', 'c', 'a2', 'a3', 'c3']
2653
2654
2655        Example 1:
2656        >>> lst1 = ['a', 'a', 'c']
2657        >>> lst2 = ['a2', 'b2', 'a']
2658        >>> it(lst1).union(lst2).to_list()
2659        ['a', 'c', 'a2', 'b2']
2660        """
2661        return self.concat(*other).distinct()
2662
2663    def join(self: Sequence[str], separator: str = " ") -> str:
2664        """
2665        Joins the elements of the given Sequence into a string.
2666
2667        Example 1:
2668        >>> lst = ['a', 'b', 'c']
2669        >>> it(lst).join(', ')
2670        'a, b, c'
2671        """
2672        return separator.join(self)
2673
2674    @overload
2675    def progress(self) -> Sequence[T]: ...
2676    @overload
2677    def progress(
2678        self, progress_func: Union[Literal["tqdm"], Literal["tqdm_rich"]]
2679    ) -> Sequence[T]: ...
2680    @overload
2681    def progress(self, progress_func: Callable[[Iterable[T]], Iterable[T]]) -> Sequence[T]: ...
2682    def progress(
2683        self,
2684        progress_func: Union[
2685            Callable[[Iterable[T]], Iterable[T]],
2686            Literal["tqdm"],
2687            Literal["tqdm_rich"],
2688            None,
2689        ] = None,
2690    ) -> Sequence[T]:
2691        """
2692        Returns a Sequence that enable a progress bar for the given Sequence.
2693
2694        Example 1:
2695        >>> from tqdm import tqdm
2696        >>> from time import sleep
2697        >>> it(range(10)).progress(lambda x: tqdm(x, total=len(x))).parallel_map(lambda x: sleep(0.), max_workers=5).to_list() and None
2698        >>> for _ in it(list(range(10))).progress(lambda x: tqdm(x, total=len(x))).to_list(): pass
2699        """
2700        if progress_func is not None and callable(progress_func):
2701            from .progress import ProgressTransform
2702
2703            return it(ProgressTransform(self, progress_func))
2704
2705        def import_tqdm():
2706            if progress_func == "tqdm_rich":
2707                from tqdm.rich import tqdm
2708            else:
2709                from tqdm import tqdm
2710            return tqdm
2711
2712        try:
2713            tqdm = import_tqdm()
2714        except ImportError:
2715            from pip import main as pip
2716
2717            pip(["install", "tqdm"])
2718            tqdm = import_tqdm()
2719
2720        return it(tqdm(self, total=len(self)))
2721
2722    def typing_as(self, typ: Type[U]) -> Sequence[U]:
2723        """
2724        Cast the element as specific Type to gain code completion base on type annotations.
2725        """
2726        el = self.first_not_none_of_or_none()
2727        if el is None or isinstance(el, typ) or not isinstance(el, dict):
2728            return self  # type: ignore
2729
2730        class AttrDict(Dict[str, Any]):
2731            def __init__(self, value: Dict[str, Any]) -> None:
2732                super().__init__(**value)
2733                setattr(self, "__dict__", value)
2734                self.__getattr__ = value.__getitem__
2735                self.__setattr__ = value.__setattr__  # type: ignore
2736
2737        return self.map(AttrDict)  # type: ignore  # use https://github.com/cdgriffith/Box ?
2738
2739    def to_set(self) -> Set[T]:
2740        """
2741        Returns a set containing all elements of this Sequence.
2742
2743        Example 1:
2744        >>> it(['a', 'b', 'c', 'c']).to_set() == {'a', 'b', 'c'}
2745        True
2746        """
2747        return set(self)
2748
2749    @overload
2750    def to_dict(self: Sequence[Tuple[K, V]]) -> Dict[K, V]: ...
2751    @overload
2752    def to_dict(self, transform: Callable[[T], Tuple[K, V]]) -> Dict[K, V]: ...
2753    @overload
2754    def to_dict(self, transform: Callable[[T, int], Tuple[K, V]]) -> Dict[K, V]: ...
2755    @overload
2756    def to_dict(self, transform: Callable[[T, int, Sequence[T]], Tuple[K, V]]) -> Dict[K, V]: ...
2757    def to_dict(self, transform: Optional[Callable[..., Tuple[K, V]]] = None) -> Dict[K, V]:
2758        """
2759        Returns a [Dict] containing key-value Tuple provided by [transform] function
2760        applied to elements of the given Sequence.
2761
2762        Example 1:
2763        >>> lst = ['1', '2', '3']
2764        >>> it(lst).to_dict(lambda x: (int(x), x))
2765        {1: '1', 2: '2', 3: '3'}
2766
2767        Example 2:
2768        >>> lst = [(1, '1'), (2, '2'), (3, '3')]
2769        >>> it(lst).to_dict()
2770        {1: '1', 2: '2', 3: '3'}
2771        """
2772        return self.associate(transform or (lambda x: x))  # type: ignore
2773
2774    def to_list(self) -> List[T]:
2775        """
2776        Returns a list with elements of the given Sequence.
2777
2778        Example 1:
2779        >>> it(['b', 'c', 'a']).to_list()
2780        ['b', 'c', 'a']
2781        """
2782        if self.__transform__.cache is not None:
2783            return self.__transform__.cache.copy()
2784        return [s for s in self]
2785
2786    async def to_list_async(self: Iterable[Awaitable[T]]) -> List[T]:
2787        """
2788        Returns a list with elements of the given Sequence.
2789
2790        Example 1:
2791        >>> it(['b', 'c', 'a']).to_list()
2792        ['b', 'c', 'a']
2793        """
2794        from asyncio import gather
2795
2796        return await gather(*self)  # type: ignore
2797
2798    def let(self, block: Callable[[Sequence[T]], U]) -> U:
2799        """
2800        Calls the specified function [block] with `self` value as its argument and returns its result.
2801
2802        Example 1:
2803        >>> it(['a', 'b', 'c']).let(lambda x: x.map(lambda y: y + '!')).to_list()
2804        ['a!', 'b!', 'c!']
2805        """
2806        return block(self)
2807
2808    def also(self, block: Callable[[Sequence[T]], Any]) -> Sequence[T]:
2809        """
2810        Calls the specified function [block] with `self` value as its argument and returns `self` value.
2811
2812        Example 1:
2813        >>> it(['a', 'b', 'c']).also(lambda x: x.map(lambda y: y + '!')).to_list()
2814        ['a', 'b', 'c']
2815        """
2816        block(self)
2817        return self
2818
2819    @property
2820    def size(self) -> int:
2821        """
2822        Returns the size of the given Sequence.
2823        """
2824        return len(self.data)
2825
2826    def is_empty(self) -> bool:
2827        """
2828        Returns True if the Sequence is empty, False otherwise.
2829
2830        Example 1:
2831        >>> it(['a', 'b', 'c']).is_empty()
2832        False
2833
2834        Example 2:
2835        >>> it([None]).is_empty()
2836        False
2837
2838        Example 3:
2839        >>> it([]).is_empty()
2840        True
2841        """
2842        return id(self.first_or_default(self)) == id(self)
2843
2844    def __iter__(self) -> Iterator[T]:
2845        return self.__do_iter__()
2846
2847    def iter(self) -> Iterator[T]:
2848        return self.__do_iter__()
2849
2850    def __do_iter__(self) -> Iterator[T]:
2851        yield from self.__transform__
2852
2853    def __len__(self):
2854        return len(self.__transform__)
2855
2856    def __repr__(self):
2857        if self.__transform__.cache is None:
2858            return "[...]"
2859        return repr(self.to_list())
2860
2861    def __getitem__(self, key: int):
2862        """
2863        Returns the element at the specified [index] in the Sequence.
2864
2865        Example 1:
2866        >>> lst = [1, 2, 3]
2867        >>> it(lst)[1]
2868        2
2869
2870        Example 2:
2871        >>> lst = [1, 2, 3]
2872        >>> it(lst)[3]
2873        Traceback (most recent call last):
2874        ...
2875        IndexError: Index 3 out of range
2876        """
2877        return self.element_at(key)
2878
2879    @overload
2880    def __callback_overload_warpper__(self, callback: Callable[[T], U]) -> Callable[[T], U]: ...
2881    @overload
2882    def __callback_overload_warpper__(
2883        self, callback: Callable[[T, int], U]
2884    ) -> Callable[[T], U]: ...
2885    @overload
2886    def __callback_overload_warpper__(
2887        self, callback: Callable[[T, int, Sequence[T]], U]
2888    ) -> Callable[[T], U]: ...
2889    def __callback_overload_warpper__(self, callback: Callable[..., U]) -> Callable[[T], U]:
2890        if hasattr(callback, "__code__"):
2891            if callback.__code__.co_argcount == 2:
2892                index = AutoIncrementIndex()
2893                return lambda x: callback(x, index())
2894            if callback.__code__.co_argcount == 3:
2895                index = AutoIncrementIndex()
2896                return lambda x: callback(x, index(), self)
2897        return callback
2898
2899
2900class AutoIncrementIndex:
2901    idx = 0
2902
2903    def __call__(self) -> int:
2904        val = self.idx
2905        self.idx += 1
2906        return val
2907
2908
2909class IndexedValue(NamedTuple, Generic[T]):
2910    val: T
2911    idx: int
2912
2913    def __repr__(self) -> str:
2914        return f"IndexedValue({self.idx}, {self.val})"
2915
2916
2917def throw(exception: Exception) -> Any:
2918    raise exception
2919
2920
2921def none_or(value: Optional[T], default: T) -> T:
2922    return value if value is not None else default
2923
2924
2925def none_or_else(value: Optional[T], f: Callable[[], T]) -> T:
2926    return value if value is not None else f()
2927
2928
2929def is_debugging() -> bool:
2930    from inspect import currentframe
2931    from traceback import walk_stack
2932
2933    return (
2934        it(walk_stack(currentframe()))
2935        .take(20)
2936        .map(lambda s: s[0])
2937        .any(
2938            lambda s: s.f_code.co_name == "get_contents_debug_adapter_protocol"
2939            and "pydevd_resolver.py" in s.f_code.co_filename
2940        )
2941    )
2942
2943
2944class SequenceProducer:
2945    @overload
2946    def __call__(self, elements: List[T]) -> Sequence[T]: ...
2947    @overload
2948    def __call__(self, elements: Iterable[T]) -> Sequence[T]: ...
2949    @overload
2950    def __call__(self, *elements: T) -> Sequence[T]: ...
2951    def __call__(self, *iterable: Union[Iterable[T], List[T], T]) -> Sequence[T]:  # type: ignore
2952        if len(iterable) == 1:
2953            iter = iterable[0]
2954            if isinstance(iter, Sequence):
2955                return iter  # type: ignore
2956            if isinstance(iter, Iterable) and not isinstance(iter, str):
2957                return Sequence(iter)  # type: ignore
2958        return Sequence(iterable)  # type: ignore
2959
2960    def json(self, filepath: str, **kwargs: Dict[str, Any]) -> Sequence[Any]:
2961        """
2962        Reads and parses the input of a json file.
2963        """
2964        import json
2965
2966        with open(filepath, "r") as f:
2967            data = json.load(f, **kwargs)  # type: ignore
2968            return self(data)
2969
2970    def csv(self, filepath: str):
2971        """
2972        Reads and parses the input of a csv file.
2973        """
2974        return self.read_csv(filepath)
2975
2976    def read_csv(self, filepath: str, header: Optional[int] = 0):
2977        """
2978        Reads and parses the input of a csv file.
2979
2980        Example 1:
2981        >>> it.read_csv('tests/data/a.csv').to_list()
2982        [{'a': 'a1', 'b': '1'}, {'a': 'a2', 'b': '2'}]
2983        """
2984        import csv
2985
2986        it = self
2987        with open(filepath) as f:
2988            reader = csv.reader(f)
2989            iter = it(*reader)
2990            if header is None or header < 0:
2991                return iter
2992
2993            headers = iter.element_at_or_none(header)
2994            if headers is not None:
2995                if header == 0:
2996                    iter = iter.skip(1)
2997                else:
2998                    iter = iter.filter(lambda _, i: i != header)
2999
3000                return iter.map(
3001                    lambda row: it(row).associate_by(
3002                        lambda _, ordinal: headers[ordinal]
3003                        if ordinal < len(headers)
3004                        else f"undefined_{ordinal}"
3005                    )
3006                )
3007            return iter
3008
3009    def __repr__(self) -> str:
3010        return __package__ or self.__class__.__name__
3011
3012
3013sequence = SequenceProducer()
3014"""
3015    Creates an iterator from a list of elements or given Iterable.
3016
3017    Example 1:
3018>>> sequence('hello', 'world').map(lambda x: x.upper()).to_list()
3019['HELLO', 'WORLD']
3020
3021    Example 2:
3022>>> sequence(['hello', 'world']).map(lambda x: x.upper()).to_list()
3023['HELLO', 'WORLD']
3024
3025    Example 3:
3026>>> sequence(range(10)).map(lambda x: x*x).to_list()
3027[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
3028"""
3029
3030seq = sequence
3031"""
3032    Creates an iterator from a list of elements or given Iterable.
3033
3034    Example 1:
3035>>> seq('hello', 'world').map(lambda x: x.upper()).to_list()
3036['HELLO', 'WORLD']
3037
3038    Example 2:
3039>>> seq(['hello', 'world']).map(lambda x: x.upper()).to_list()
3040['HELLO', 'WORLD']
3041
3042    Example 3:
3043>>> seq(range(10)).map(lambda x: x*x).to_list()
3044[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
3045"""
3046
3047it = sequence
3048"""
3049    Creates an iterator from a list of elements or given Iterable.
3050
3051    Example 1:
3052>>> it('hello', 'world').map(lambda x: x.upper()).to_list()
3053['HELLO', 'WORLD']
3054
3055    Example 2:
3056>>> it(['hello', 'world']).map(lambda x: x.upper()).to_list()
3057['HELLO', 'WORLD']
3058
3059    Example 3:
3060>>> it(range(10)).map(lambda x: x*x).to_list()
3061[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
3062"""
3063
3064
3065if __name__ == "__main__":
3066    import doctest
3067
3068    doctest.testmod()
class Sequence(typing.Generic[~T], typing.Iterable[~T]):
  50class Sequence(Generic[T], Iterable[T]):
  51    """
  52    Given an [iterator] function constructs a [Sequence] that returns values through the [Iterator]
  53    provided by that function.
  54
  55    The values are evaluated lazily, and the sequence is potentially infinite.
  56    """
  57
  58    __transform__: Transform[Any, T]
  59
  60    def __init__(self, iterable: Union[Iterable[T], Transform[Any, T]]) -> None:
  61        super().__init__()
  62
  63        self.__transform__ = new_transform(iterable)
  64
  65    @cached_property
  66    def transforms(self):
  67        return [*self.__transform__.transforms()]
  68
  69    @property
  70    def data(self) -> List[T]:
  71        if self.__transform__.cache is not None:
  72            return self.__transform__.cache.copy()
  73        if is_debugging():
  74            raise LazyEvaluationException("The sequence has not been evaluated yet.")
  75        return self.to_list()
  76
  77    def dedup(self) -> Sequence[T]:
  78        """
  79        Removes consecutive repeated elements in the sequence.
  80
  81        If the sequence is sorted, this removes all duplicates.
  82
  83        Example 1:
  84        >>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
  85        >>> it(lst).dedup().to_list()
  86        ['a1', 'b2', 'a2', 'a1']
  87
  88        Example 1:
  89        >>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
  90        >>> it(lst).sorted().dedup().to_list()
  91        ['a1', 'a2', 'b2']
  92        """
  93        return self.dedup_by(lambda x: x)
  94
  95    @overload
  96    def dedup_by(self, key_selector: Callable[[T], Any]) -> Sequence[T]: ...
  97    @overload
  98    def dedup_by(self, key_selector: Callable[[T, int], Any]) -> Sequence[T]: ...
  99    @overload
 100    def dedup_by(self, key_selector: Callable[[T, int, Sequence[T]], Any]) -> Sequence[T]: ...
 101    def dedup_by(self, key_selector: Callable[..., Any]) -> Sequence[T]:
 102        """
 103        Removes all but the first of consecutive elements in the sequence that resolve to the same key.
 104        """
 105        return self.dedup_into_group_by(key_selector).map(lambda x: x[0])
 106
 107    @overload
 108    def dedup_with_count_by(self, key_selector: Callable[[T], Any]) -> Sequence[Tuple[T, int]]: ...
 109    @overload
 110    def dedup_with_count_by(
 111        self, key_selector: Callable[[T, int], Any]
 112    ) -> Sequence[Tuple[T, int]]: ...
 113    @overload
 114    def dedup_with_count_by(
 115        self, key_selector: Callable[[T, int, Sequence[T]], Any]
 116    ) -> Sequence[Tuple[T, int]]: ...
 117    def dedup_with_count_by(self, key_selector: Callable[..., Any]) -> Sequence[Tuple[T, int]]:
 118        """
 119        Removes all but the first of consecutive elements and its count that resolve to the same key.
 120
 121        Example 1:
 122        >>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
 123        >>> it(lst).dedup_with_count_by(lambda x: x).to_list()
 124        [('a1', 2), ('b2', 1), ('a2', 1), ('a1', 1)]
 125
 126        Example 1:
 127        >>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
 128        >>> it(lst).sorted().dedup_with_count_by(lambda x: x).to_list()
 129        [('a1', 3), ('a2', 1), ('b2', 1)]
 130        """
 131        return self.dedup_into_group_by(key_selector).map(lambda x: (x[0], len(x)))
 132
 133    @overload
 134    def dedup_into_group_by(self, key_selector: Callable[[T], Any]) -> Sequence[List[T]]: ...
 135    @overload
 136    def dedup_into_group_by(self, key_selector: Callable[[T, int], Any]) -> Sequence[List[T]]: ...
 137    @overload
 138    def dedup_into_group_by(
 139        self, key_selector: Callable[[T, int, Sequence[T]], Any]
 140    ) -> Sequence[List[T]]: ...
 141    def dedup_into_group_by(self, key_selector: Callable[..., Any]) -> Sequence[List[T]]:
 142        from .dedup import DedupTransform
 143
 144        return it(DedupTransform(self, key_selector))
 145
 146    @overload
 147    def filter(self, predicate: Callable[[T], bool]) -> Sequence[T]: ...
 148    @overload
 149    def filter(self, predicate: Callable[[T, int], bool]) -> Sequence[T]: ...
 150    @overload
 151    def filter(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Sequence[T]: ...
 152    def filter(self, predicate: Callable[..., bool]) -> Sequence[T]:
 153        """
 154        Returns a Sequence containing only elements matching the given [predicate].
 155
 156        Example 1:
 157        >>> lst = [ 'a1', 'b1', 'b2', 'a2']
 158        >>> it(lst).filter(lambda x: x.startswith('a')).to_list()
 159        ['a1', 'a2']
 160
 161        Example 2:
 162        >>> lst = [ 'a1', 'b1', 'b2', 'a2']
 163        >>> it(lst).filter(lambda x, i: x.startswith('a') or i % 2 == 0 ).to_list()
 164        ['a1', 'b2', 'a2']
 165        """
 166        from .filtering import FilteringTransform
 167
 168        return it(FilteringTransform(self, self.__callback_overload_warpper__(predicate)))
 169
 170    def filter_is_instance(self, typ: Type[U]) -> Sequence[U]:
 171        """
 172        Returns a Sequence containing all elements that are instances of specified type parameter typ.
 173
 174        Example 1:
 175        >>> lst = [ 'a1', 1, 'b2', 3]
 176        >>> it(lst).filter_is_instance(int).to_list()
 177        [1, 3]
 178
 179        """
 180        return self.filter(lambda x: isinstance(x, typ))  # type: ignore
 181
 182    @overload
 183    def filter_not(self, predicate: Callable[[T], bool]) -> Sequence[T]: ...
 184    @overload
 185    def filter_not(self, predicate: Callable[[T, int], bool]) -> Sequence[T]: ...
 186    @overload
 187    def filter_not(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Sequence[T]: ...
 188    def filter_not(self, predicate: Callable[..., bool]) -> Sequence[T]:
 189        """
 190        Returns a Sequence containing all elements not matching the given [predicate].
 191
 192        Example 1:
 193        >>> lst = [ 'a1', 'b1', 'b2', 'a2']
 194        >>> it(lst).filter_not(lambda x: x.startswith('a')).to_list()
 195        ['b1', 'b2']
 196
 197        Example 2:
 198        >>> lst = [ 'a1', 'a2', 'b1', 'b2']
 199        >>> it(lst).filter_not(lambda x, i: x.startswith('a') and i % 2 == 0 ).to_list()
 200        ['a2', 'b1', 'b2']
 201        """
 202        predicate = self.__callback_overload_warpper__(predicate)
 203        return self.filter(lambda x: not predicate(x))
 204
 205    @overload
 206    def filter_not_none(self: Sequence[Optional[U]]) -> Sequence[U]: ...
 207    @overload
 208    def filter_not_none(self: Sequence[T]) -> Sequence[T]: ...
 209    def filter_not_none(self: Sequence[Optional[U]]) -> Sequence[U]:
 210        """
 211        Returns a Sequence containing all elements that are not `None`.
 212
 213        Example 1:
 214        >>> lst = [ 'a', None, 'b']
 215        >>> it(lst).filter_not_none().to_list()
 216        ['a', 'b']
 217        """
 218        return self.filter(lambda x: x is not None)  # type: ignore
 219
 220    @overload
 221    def map(self, transform: Callable[[T], U]) -> Sequence[U]: ...
 222    @overload
 223    def map(self, transform: Callable[[T, int], U]) -> Sequence[U]: ...
 224    @overload
 225    def map(self, transform: Callable[[T, int, Sequence[T]], U]) -> Sequence[U]: ...
 226    def map(self, transform: Callable[..., U]) -> Sequence[U]:
 227        """
 228        Returns a Sequence containing the results of applying the given [transform] function
 229        to each element in the original Sequence.
 230
 231        Example 1:
 232        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
 233        >>> it(lst).map(lambda x: x['age']).to_list()
 234        [12, 13]
 235
 236        Example 2:
 237        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
 238        >>> it(lst).map(lambda x, i: x['name'] + str(i)).to_list()
 239        ['A0', 'B1']
 240
 241        Example 3:
 242        >>> lst = ['hi', 'abc']
 243        >>> it(lst).map(len).to_list()
 244        [2, 3]
 245        """
 246        from .mapping import MappingTransform
 247
 248        return it(MappingTransform(self, self.__callback_overload_warpper__(transform)))
 249
 250    @overload
 251    async def map_async(self, transform: Callable[[T], Awaitable[U]]) -> Sequence[U]: ...
 252    @overload
 253    async def map_async(
 254        self,
 255        transform: Callable[[T, int], Awaitable[U]],
 256        return_exceptions: Literal[True],
 257    ) -> Sequence[Union[U, BaseException]]: ...
 258    @overload
 259    async def map_async(
 260        self,
 261        transform: Callable[[T, int, Sequence[T]], Awaitable[U]],
 262        return_exceptions: Literal[False] = False,
 263    ) -> Sequence[U]: ...
 264    async def map_async(
 265        self, transform: Callable[..., Awaitable[U]], return_exceptions: bool = False
 266    ):
 267        """
 268        Similar to `.map()` but you can input a async transform then await it.
 269        """
 270        from asyncio import gather
 271
 272        if return_exceptions:
 273            return it(await gather(*self.map(transform), return_exceptions=True))
 274        return it(await gather(*self.map(transform)))
 275
 276    @overload
 277    def map_not_none(self, transform: Callable[[T], Optional[U]]) -> Sequence[U]: ...
 278    @overload
 279    def map_not_none(self, transform: Callable[[T, int], Optional[U]]) -> Sequence[U]: ...
 280    @overload
 281    def map_not_none(
 282        self, transform: Callable[[T, int, Sequence[T]], Optional[U]]
 283    ) -> Sequence[U]: ...
 284    def map_not_none(self, transform: Callable[..., Optional[U]]) -> Sequence[U]:
 285        """
 286        Returns a Sequence containing only the non-none results of applying the given [transform] function
 287        to each element in the original collection.
 288
 289        Example 1:
 290        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': None}]
 291        >>> it(lst).map_not_none(lambda x: x['age']).to_list()
 292        [12]
 293        """
 294        return self.map(transform).filter_not_none()  # type: ignore
 295
 296    @overload
 297    def parallel_map(
 298        self,
 299        transform: Callable[[T], U],
 300        max_workers: Optional[int] = None,
 301        chunksize: int = 1,
 302        executor: ParallelMappingTransform.Executor = "Thread",
 303    ) -> Sequence[U]: ...
 304    @overload
 305    def parallel_map(
 306        self,
 307        transform: Callable[[T, int], U],
 308        max_workers: Optional[int] = None,
 309        chunksize: int = 1,
 310        executor: ParallelMappingTransform.Executor = "Thread",
 311    ) -> Sequence[U]: ...
 312    @overload
 313    def parallel_map(
 314        self,
 315        transform: Callable[[T, int, Sequence[T]], U],
 316        max_workers: Optional[int] = None,
 317        chunksize: int = 1,
 318        executor: ParallelMappingTransform.Executor = "Thread",
 319    ) -> Sequence[U]: ...
 320    def parallel_map(
 321        self,
 322        transform: Callable[..., U],
 323        max_workers: Optional[int] = None,
 324        chunksize: int = 1,
 325        executor: ParallelMappingTransform.Executor = "Thread",
 326    ) -> Sequence[U]:
 327        """
 328        Returns a Sequence containing the results of applying the given [transform] function
 329        to each element in the original Sequence.
 330
 331        Example 1:
 332        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
 333        >>> it(lst).parallel_map(lambda x: x['age']).to_list()
 334        [12, 13]
 335
 336        Example 2:
 337        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
 338        >>> it(lst).parallel_map(lambda x: x['age'], max_workers=2).to_list()
 339        [12, 13]
 340
 341        Example 3:
 342        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
 343        >>> it(lst).parallel_map(lambda x, i: x['age'] + i, max_workers=2).to_list()
 344        [12, 14]
 345        """
 346        from .parallel_mapping import ParallelMappingTransform
 347
 348        return it(
 349            ParallelMappingTransform(
 350                self,
 351                self.__callback_overload_warpper__(transform),
 352                max_workers,
 353                chunksize,
 354                executor,
 355            )
 356        )
 357
 358    @overload
 359    def find(self, predicate: Callable[[T], bool]) -> Optional[T]: ...
 360    @overload
 361    def find(self, predicate: Callable[[T, int], bool]) -> Optional[T]: ...
 362    @overload
 363    def find(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Optional[T]: ...
 364    def find(self, predicate: Callable[..., bool]) -> Optional[T]:
 365        """
 366        Returns the first element matching the given [predicate], or `None` if no such element was found.
 367
 368        Example 1:
 369        >>> lst = ['a', 'b', 'c']
 370        >>> it(lst).find(lambda x: x == 'b')
 371        'b'
 372        """
 373        return self.first_or_none(predicate)
 374
 375    def find_last(self, predicate: Callable[[T], bool]) -> Optional[T]:
 376        """
 377        Returns the last element matching the given [predicate], or `None` if no such element was found.
 378
 379        Example 1:
 380        >>> lst = ['a', 'b', 'c']
 381        >>> it(lst).find_last(lambda x: x == 'b')
 382        'b'
 383        """
 384        return self.last_or_none(predicate)
 385
 386    @overload
 387    def first(self) -> T: ...
 388    @overload
 389    def first(self, predicate: Callable[[T], bool]) -> T: ...
 390    @overload
 391    def first(self, predicate: Callable[[T, int], bool]) -> T: ...
 392    @overload
 393    def first(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> T: ...
 394    def first(self, predicate: Optional[Callable[..., bool]] = None) -> T:
 395        """
 396        Returns first element.
 397
 398        Example 1:
 399        >>> lst = ['a', 'b', 'c']
 400        >>> it(lst).first()
 401        'a'
 402
 403        Example 2:
 404        >>> lst = []
 405        >>> it(lst).first()
 406        Traceback (most recent call last):
 407        ...
 408        ValueError: Sequence is empty.
 409
 410        Example 3:
 411        >>> lst = ['a', 'b', 'c']
 412        >>> it(lst).first(lambda x: x == 'b')
 413        'b'
 414
 415        Example 4:
 416        >>> lst = ['a', 'b', 'c']
 417        >>> it(lst).first(lambda x: x == 'd')
 418        Traceback (most recent call last):
 419        ...
 420        ValueError: Sequence is empty.
 421
 422        Example 5:
 423        >>> lst = [None]
 424        >>> it(lst).first() is None
 425        True
 426        """
 427        for e in self:
 428            if predicate is None or predicate(e):
 429                return e
 430        raise ValueError("Sequence is empty.")
 431
 432    @overload
 433    def first_not_none_of(self: Sequence[Optional[U]]) -> U: ...
 434    @overload
 435    def first_not_none_of(
 436        self: Sequence[Optional[U]], transform: Callable[[Optional[U]], Optional[U]]
 437    ) -> U: ...
 438    @overload
 439    def first_not_none_of(
 440        self: Sequence[Optional[U]],
 441        transform: Callable[[Optional[U], int], Optional[U]],
 442    ) -> U: ...
 443    @overload
 444    def first_not_none_of(
 445        self: Sequence[Optional[U]],
 446        transform: Callable[[Optional[U], int, Sequence[Optional[U]]], Optional[U]],
 447    ) -> U: ...
 448    def first_not_none_of(
 449        self: Sequence[Optional[U]],
 450        transform: Optional[Callable[..., Optional[U]]] = None,
 451    ) -> U:
 452        """
 453        Returns the first non-`None` result of applying the given [transform] function to each element in the original collection.
 454
 455        Example 1:
 456        >>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': 12}]
 457        >>> it(lst).first_not_none_of(lambda x: x['age'])
 458        12
 459
 460        Example 2:
 461        >>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': None}]
 462        >>> it(lst).first_not_none_of(lambda x: x['age'])
 463        Traceback (most recent call last):
 464        ...
 465        ValueError: No element of the Sequence was transformed to a non-none value.
 466        """
 467
 468        v = (
 469            self.first_not_none_of_or_none()
 470            if transform is None
 471            else self.first_not_none_of_or_none(transform)
 472        )
 473        if v is None:
 474            raise ValueError("No element of the Sequence was transformed to a non-none value.")
 475        return v
 476
 477    @overload
 478    def first_not_none_of_or_none(self) -> T: ...
 479    @overload
 480    def first_not_none_of_or_none(self, transform: Callable[[T], T]) -> T: ...
 481    @overload
 482    def first_not_none_of_or_none(self, transform: Callable[[T, int], T]) -> T: ...
 483    @overload
 484    def first_not_none_of_or_none(self, transform: Callable[[T, int, Sequence[T]], T]) -> T: ...
 485    def first_not_none_of_or_none(self, transform: Optional[Callable[..., T]] = None) -> T:
 486        """
 487        Returns the first non-`None` result of applying the given [transform] function to each element in the original collection.
 488
 489        Example 1:
 490        >>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': 12}]
 491        >>> it(lst).first_not_none_of_or_none(lambda x: x['age'])
 492        12
 493
 494        Example 2:
 495        >>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': None}]
 496        >>> it(lst).first_not_none_of_or_none(lambda x: x['age']) is None
 497        True
 498        """
 499        if transform is None:
 500            return self.first_or_none()
 501        return self.map_not_none(transform).first_or_none()
 502
 503    @overload
 504    def first_or_none(self) -> T: ...
 505    @overload
 506    def first_or_none(self, predicate: Callable[[T], bool]) -> Optional[T]: ...
 507    @overload
 508    def first_or_none(self, predicate: Callable[[T, int], bool]) -> Optional[T]: ...
 509    @overload
 510    def first_or_none(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Optional[T]: ...
 511    def first_or_none(self, predicate: Optional[Callable[..., bool]] = None) -> Optional[T]:
 512        """
 513        Returns the first element, or `None` if the Sequence is empty.
 514
 515        Example 1:
 516        >>> lst = []
 517        >>> it(lst).first_or_none() is None
 518        True
 519
 520        Example 2:
 521        >>> lst = ['a', 'b', 'c']
 522        >>> it(lst).first_or_none()
 523        'a'
 524
 525        Example 2:
 526        >>> lst = ['a', 'b', 'c']
 527        >>> it(lst).first_or_none(lambda x: x == 'b')
 528        'b'
 529        """
 530        if predicate is not None:
 531            return self.first_or_default(predicate, None)
 532        else:
 533            return self.first_or_default(None)
 534
 535    @overload
 536    def first_or_default(self, default: U) -> Union[T, U]: ...
 537    @overload
 538    def first_or_default(self, predicate: Callable[[T], bool], default: U) -> Union[T, U]: ...
 539    @overload
 540    def first_or_default(self, predicate: Callable[[T, int], bool], default: U) -> Union[T, U]: ...
 541    @overload
 542    def first_or_default(
 543        self, predicate: Callable[[T, int, Sequence[T]], bool], default: U
 544    ) -> Union[T, U]: ...
 545    def first_or_default(  # type: ignore
 546        self, predicate: Union[Callable[..., bool], U], default: Optional[U] = None
 547    ) -> Union[T, U, None]:
 548        """
 549        Returns the first element, or the given [default] if the Sequence is empty.
 550
 551        Example 1:
 552        >>> lst = []
 553        >>> it(lst).first_or_default('a')
 554        'a'
 555
 556        Example 2:
 557        >>> lst = ['b']
 558        >>> it(lst).first_or_default('a')
 559        'b'
 560
 561        Example 3:
 562        >>> lst = ['a', 'b', 'c']
 563        >>> it(lst).first_or_default(lambda x: x == 'b', 'd')
 564        'b'
 565
 566        Example 4:
 567        >>> lst = []
 568        >>> it(lst).first_or_default(lambda x: x == 'b', 'd')
 569        'd'
 570        """
 571        seq = self
 572        if isinstance(predicate, Callable):
 573            seq = self.filter(predicate)  # type: ignore
 574        else:
 575            default = predicate
 576        return next(iter(seq), default)
 577
 578    @overload
 579    def last(self) -> T: ...
 580    @overload
 581    def last(self, predicate: Callable[[T], bool]) -> T: ...
 582    @overload
 583    def last(self, predicate: Callable[[T, int], bool]) -> T: ...
 584    @overload
 585    def last(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> T: ...
 586    def last(self, predicate: Optional[Callable[..., bool]] = None) -> T:
 587        """
 588        Returns last element.
 589
 590        Example 1:
 591        >>> lst = ['a', 'b', 'c']
 592        >>> it(lst).last()
 593        'c'
 594
 595        Example 2:
 596        >>> lst = []
 597        >>> it(lst).last()
 598        Traceback (most recent call last):
 599        ...
 600        ValueError: Sequence is empty.
 601        """
 602        v = self.last_or_none(predicate) if predicate is not None else self.last_or_none()
 603        if v is None:
 604            raise ValueError("Sequence is empty.")
 605        return v
 606
 607    @overload
 608    def last_or_none(self) -> Optional[T]: ...
 609    @overload
 610    def last_or_none(self, predicate: Callable[[T], bool]) -> Optional[T]: ...
 611    @overload
 612    def last_or_none(self, predicate: Callable[[T, int], bool]) -> Optional[T]: ...
 613    @overload
 614    def last_or_none(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Optional[T]: ...
 615    def last_or_none(self, predicate: Optional[Callable[..., bool]] = None) -> Optional[T]:
 616        """
 617        Returns the last element matching the given [predicate], or `None` if no such element was found.
 618
 619        Exmaple 1:
 620        >>> lst = ['a', 'b', 'c']
 621        >>> it(lst).last_or_none()
 622        'c'
 623
 624        Exmaple 2:
 625        >>> lst = ['a', 'b', 'c']
 626        >>> it(lst).last_or_none(lambda x: x != 'c')
 627        'b'
 628
 629        Exmaple 3:
 630        >>> lst = []
 631        >>> it(lst).last_or_none(lambda x: x != 'c') is None
 632        True
 633        """
 634        last: Optional[T] = None
 635        for i in self if predicate is None else self.filter(predicate):
 636            last = i
 637        return last
 638
 639    def index_of_or_none(self, element: T) -> Optional[int]:
 640        """
 641        Returns first index of [element], or None if the collection does not contain element.
 642
 643        Example 1:
 644        >>> lst = ['a', 'b', 'c']
 645        >>> it(lst).index_of_or_none('b')
 646        1
 647
 648        Example 2:
 649        >>> lst = ['a', 'b', 'c']
 650        >>> it(lst).index_of_or_none('d')
 651        """
 652        for i, x in enumerate(self):
 653            if x == element:
 654                return i
 655        return None
 656
 657    def index_of(self, element: T) -> int:
 658        """
 659        Returns first index of [element], or -1 if the collection does not contain element.
 660
 661        Example 1:
 662        >>> lst = ['a', 'b', 'c']
 663        >>> it(lst).index_of('b')
 664        1
 665
 666        Example 2:
 667        >>> lst = ['a', 'b', 'c']
 668        >>> it(lst).index_of('d')
 669        -1
 670        """
 671        return none_or(self.index_of_or_none(element), -1)
 672
 673    def index_of_or(self, element: T, default: int) -> int:
 674        """
 675        Returns first index of [element], or default value if the collection does not contain element.
 676
 677        Example 1:
 678        >>> lst = ['a', 'b', 'c']
 679        >>> it(lst).index_of_or('b', 1)
 680        1
 681
 682        Example 2:
 683        >>> lst = ['a', 'b', 'c']
 684        >>> it(lst).index_of_or('d', 0)
 685        0
 686        """
 687        return none_or(self.index_of_or_none(element), default)
 688
 689    def index_of_or_else(self, element: T, f: Callable[[], int]) -> int:
 690        """
 691        Returns first index of [element], or computes the value from a callback if the collection does not contain element.
 692
 693        Example 1:
 694        >>> lst = ['a', 'b', 'c']
 695        >>> it(lst).index_of_or_else('b', lambda: 2)
 696        1
 697
 698        Example 2:
 699        >>> lst = ['a', 'b', 'c']
 700        >>> it(lst).index_of_or_else('d', lambda: 0)
 701        0
 702        """
 703        return none_or_else(self.index_of_or_none(element), f)
 704
 705    def last_index_of_or_none(self, element: T) -> Optional[int]:
 706        """
 707         Returns last index of [element], or None if the collection does not contain element.
 708
 709        Example 1:
 710        >>> lst = ['a', 'b', 'c', 'b']
 711        >>> it(lst).last_index_of_or_none('b')
 712        3
 713
 714        Example 2:
 715        >>> lst = ['a', 'b', 'c']
 716        >>> it(lst).last_index_of_or_none('d')
 717        """
 718        seq = self.reversed()
 719        last_idx = len(seq) - 1
 720        for i, x in enumerate(seq):
 721            if x == element:
 722                return last_idx - i
 723        return None
 724
 725    def last_index_of(self, element: T) -> int:
 726        """
 727         Returns last index of [element], or -1 if the collection does not contain element.
 728
 729        Example 1:
 730        >>> lst = ['a', 'b', 'c', 'b']
 731        >>> it(lst).last_index_of('b')
 732        3
 733
 734        Example 2:
 735        >>> lst = ['a', 'b', 'c']
 736        >>> it(lst).last_index_of('d')
 737        -1
 738        """
 739        return none_or(self.last_index_of_or_none(element), -1)
 740
 741    def last_index_of_or(self, element: T, default: int) -> int:
 742        """
 743         Returns last index of [element], or default value if the collection does not contain element.
 744
 745        Example 1:
 746        >>> lst = ['a', 'b', 'c', 'b']
 747        >>> it(lst).last_index_of_or('b', 0)
 748        3
 749
 750        Example 2:
 751        >>> lst = ['a', 'b', 'c']
 752        >>> it(lst).last_index_of_or('d', len(lst))
 753        3
 754        """
 755        return none_or(self.last_index_of_or_none(element), default)
 756
 757    def last_index_of_or_else(self, element: T, f: Callable[[], int]) -> int:
 758        """
 759         Returns last index of [element], or computes the value from a callback if the collection does not contain element.
 760
 761        Example 1:
 762        >>> lst = ['a', 'b', 'c', 'b']
 763        >>> it(lst).last_index_of_or_else('b', lambda: 0)
 764        3
 765
 766        Example 2:
 767        >>> lst = ['a', 'b', 'c']
 768        >>> it(lst).last_index_of_or_else('d', lambda: len(lst))
 769        3
 770        """
 771        return none_or_else(self.last_index_of_or_none(element), f)
 772
 773    @overload
 774    def index_of_first_or_none(self, predicate: Callable[[T], bool]) -> Optional[int]: ...
 775    @overload
 776    def index_of_first_or_none(self, predicate: Callable[[T, int], bool]) -> Optional[int]: ...
 777    @overload
 778    def index_of_first_or_none(
 779        self, predicate: Callable[[T, int, Sequence[T]], bool]
 780    ) -> Optional[int]: ...
 781    def index_of_first_or_none(self, predicate: Callable[..., bool]) -> Optional[int]:
 782        """
 783        Returns first index of element matching the given [predicate], or None if no such element was found.
 784
 785        Example 1:
 786        >>> lst = ['a', 'b', 'c']
 787        >>> it(lst).index_of_first_or_none(lambda x: x == 'b')
 788        1
 789
 790        Example 2:
 791        >>> lst = ['a', 'b', 'c']
 792        >>> it(lst).index_of_first_or_none(lambda x: x == 'd')
 793        """
 794        predicate = self.__callback_overload_warpper__(predicate)
 795        for i, x in enumerate(self):
 796            if predicate(x):
 797                return i
 798        return None
 799
 800    @overload
 801    def index_of_first(self, predicate: Callable[[T], bool]) -> int: ...
 802    @overload
 803    def index_of_first(self, predicate: Callable[[T, int], bool]) -> int: ...
 804    @overload
 805    def index_of_first(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> int: ...
 806    def index_of_first(self, predicate: Callable[..., bool]) -> int:
 807        """
 808        Returns first index of element matching the given [predicate], or -1 if no such element was found.
 809
 810        Example 1:
 811        >>> lst = ['a', 'b', 'c']
 812        >>> it(lst).index_of_first(lambda x: x == 'b')
 813        1
 814
 815        Example 2:
 816        >>> lst = ['a', 'b', 'c']
 817        >>> it(lst).index_of_first(lambda x: x == 'd')
 818        -1
 819
 820        Example 3:
 821        >>> lst = ['a', 'b', 'c']
 822        >>> it(lst).index_of_first(lambda x: x == 'a')
 823        0
 824        """
 825        return none_or(self.index_of_first_or_none(predicate), -1)
 826
 827    @overload
 828    def index_of_first_or(self, predicate: Callable[[T], bool], default: int) -> int: ...
 829    @overload
 830    def index_of_first_or(self, predicate: Callable[[T, int], bool], default: int) -> int: ...
 831    @overload
 832    def index_of_first_or(
 833        self, predicate: Callable[[T, int, Sequence[T]], bool], default: int
 834    ) -> int: ...
 835    def index_of_first_or(self, predicate: Callable[..., bool], default: int) -> int:
 836        """
 837        Returns first index of element matching the given [predicate], or default value if no such element was found.
 838
 839        Example 1:
 840        >>> lst = ['a', 'b', 'c']
 841        >>> it(lst).index_of_first_or(lambda x: x == 'b', 0)
 842        1
 843
 844        Example 2:
 845        >>> lst = ['a', 'b', 'c']
 846        >>> it(lst).index_of_first_or(lambda x: x == 'd', 0)
 847        0
 848
 849        Example 3:
 850        >>> lst = ['a', 'b', 'c']
 851        >>> it(lst).index_of_first_or(lambda x: x == 'a', 0)
 852        0
 853        """
 854        return none_or(self.index_of_first_or_none(predicate), default)
 855
 856    @overload
 857    def index_of_first_or_else(
 858        self, predicate: Callable[[T], bool], f: Callable[[], int]
 859    ) -> int: ...
 860    @overload
 861    def index_of_first_or_else(
 862        self, predicate: Callable[[T, int], bool], f: Callable[[], int]
 863    ) -> int: ...
 864    @overload
 865    def index_of_first_or_else(
 866        self, predicate: Callable[[T, int, Sequence[T]], bool], f: Callable[[], int]
 867    ) -> int: ...
 868    def index_of_first_or_else(self, predicate: Callable[..., bool], f: Callable[[], int]) -> int:
 869        """
 870        Returns first index of element matching the given [predicate], or computes the value from a callback if no such element was found.
 871
 872        Example 1:
 873        >>> lst = ['a', 'b', 'c']
 874        >>> it(lst).index_of_first_or_else(lambda x: x == 'b', lambda: len(lst))
 875        1
 876
 877        Example 2:
 878        >>> lst = ['a', 'b', 'c']
 879        >>> it(lst).index_of_first_or_else(lambda x: x == 'd', lambda: len(lst))
 880        3
 881
 882        Example 3:
 883        >>> lst = ['a', 'b', 'c']
 884        >>> it(lst).index_of_first_or_else(lambda x: x == 'a', lambda: len(lst))
 885        0
 886        """
 887        return none_or_else(self.index_of_first_or_none(predicate), f)
 888
 889    @overload
 890    def index_of_last_or_none(self, predicate: Callable[[T], bool]) -> Optional[int]: ...
 891    @overload
 892    def index_of_last_or_none(self, predicate: Callable[[T, int], bool]) -> Optional[int]: ...
 893    @overload
 894    def index_of_last_or_none(
 895        self, predicate: Callable[[T, int, Sequence[T]], bool]
 896    ) -> Optional[int]: ...
 897    def index_of_last_or_none(self, predicate: Callable[..., bool]) -> Optional[int]:
 898        """
 899        Returns last index of element matching the given [predicate], or -1 if no such element was found.
 900
 901        Example 1:
 902        >>> lst = ['a', 'b', 'c', 'b']
 903        >>> it(lst).index_of_last_or_none(lambda x: x == 'b')
 904        3
 905
 906        Example 2:
 907        >>> lst = ['a', 'b', 'c']
 908        >>> it(lst).index_of_last_or_none(lambda x: x == 'd')
 909        """
 910        seq = self.reversed()
 911        last_idx = len(seq) - 1
 912        predicate = self.__callback_overload_warpper__(predicate)
 913        for i, x in enumerate(seq):
 914            if predicate(x):
 915                return last_idx - i
 916        return None
 917
 918    @overload
 919    def index_of_last(self, predicate: Callable[[T], bool]) -> int: ...
 920    @overload
 921    def index_of_last(self, predicate: Callable[[T, int], bool]) -> int: ...
 922    @overload
 923    def index_of_last(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> int: ...
 924    def index_of_last(self, predicate: Callable[..., bool]) -> int:
 925        """
 926        Returns last index of element matching the given [predicate], or -1 if no such element was found.
 927
 928        Example 1:
 929        >>> lst = ['a', 'b', 'c', 'b']
 930        >>> it(lst).index_of_last(lambda x: x == 'b')
 931        3
 932
 933        Example 2:
 934        >>> lst = ['a', 'b', 'c']
 935        >>> it(lst).index_of_last(lambda x: x == 'd')
 936        -1
 937
 938        Example 3:
 939        >>> lst = ['a', 'b', 'c']
 940        >>> it(lst).index_of_last(lambda x: x == 'a')
 941        0
 942        """
 943        return none_or(self.index_of_last_or_none(predicate), -1)
 944
 945    @overload
 946    def index_of_last_or(self, predicate: Callable[[T], bool], default: int) -> int: ...
 947    @overload
 948    def index_of_last_or(self, predicate: Callable[[T, int], bool], default: int) -> int: ...
 949    @overload
 950    def index_of_last_or(
 951        self, predicate: Callable[[T, int, Sequence[T]], bool], default: int
 952    ) -> int: ...
 953    def index_of_last_or(self, predicate: Callable[..., bool], default: int) -> int:
 954        """
 955        Returns last index of element matching the given [predicate], or default value if no such element was found.
 956
 957        Example 1:
 958        >>> lst = ['a', 'b', 'c', 'b']
 959        >>> it(lst).index_of_last_or(lambda x: x == 'b', 0)
 960        3
 961
 962        Example 2:
 963        >>> lst = ['a', 'b', 'c']
 964        >>> it(lst).index_of_last_or(lambda x: x == 'd', -99)
 965        -99
 966
 967        Example 3:
 968        >>> lst = ['a', 'b', 'c']
 969        >>> it(lst).index_of_last_or(lambda x: x == 'a', 0)
 970        0
 971        """
 972        return none_or(self.index_of_last_or_none(predicate), default)
 973
 974    @overload
 975    def index_of_last_o_else(self, predicate: Callable[[T], bool], f: Callable[[], int]) -> int: ...
 976    @overload
 977    def index_of_last_o_else(
 978        self, predicate: Callable[[T, int], bool], f: Callable[[], int]
 979    ) -> int: ...
 980    @overload
 981    def index_of_last_o_else(
 982        self, predicate: Callable[[T, int, Sequence[T]], bool], f: Callable[[], int]
 983    ) -> int: ...
 984    def index_of_last_o_else(self, predicate: Callable[..., bool], f: Callable[[], int]) -> int:
 985        """
 986        Returns last index of element matching the given [predicate], or default value if no such element was found.
 987
 988        Example 1:
 989        >>> lst = ['a', 'b', 'c', 'b']
 990        >>> it(lst).index_of_last_o_else(lambda x: x == 'b', lambda: -len(lst))
 991        3
 992
 993        Example 2:
 994        >>> lst = ['a', 'b', 'c']
 995        >>> it(lst).index_of_last_o_else(lambda x: x == 'd', lambda: -len(lst))
 996        -3
 997
 998        Example 3:
 999        >>> lst = ['a', 'b', 'c']
1000        >>> it(lst).index_of_last_o_else(lambda x: x == 'a', lambda: -len(lst))
1001        0
1002        """
1003        return none_or_else(self.index_of_last_or_none(predicate), f)
1004
1005    @overload
1006    def single(self) -> T: ...
1007    @overload
1008    def single(self, predicate: Callable[[T], bool]) -> T: ...
1009    @overload
1010    def single(self, predicate: Callable[[T, int], bool]) -> T: ...
1011    @overload
1012    def single(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> T: ...
1013    def single(self, predicate: Optional[Callable[..., bool]] = None) -> T:
1014        """
1015        Returns the single element matching the given [predicate], or throws exception if there is no
1016        or more than one matching element.
1017
1018        Exmaple 1:
1019        >>> lst = ['a']
1020        >>> it(lst).single()
1021        'a'
1022
1023        Exmaple 2:
1024        >>> lst = []
1025        >>> it(lst).single() is None
1026        Traceback (most recent call last):
1027        ...
1028        ValueError: Sequence contains no element matching the predicate.
1029
1030        Exmaple 2:
1031        >>> lst = ['a', 'b']
1032        >>> it(lst).single() is None
1033        Traceback (most recent call last):
1034        ...
1035        ValueError: Sequence contains more than one matching element.
1036        """
1037        single: Optional[T] = None
1038        found = False
1039        for i in self if predicate is None else self.filter(predicate):
1040            if found:
1041                raise ValueError("Sequence contains more than one matching element.")
1042            single = i
1043            found = True
1044        if single is None:
1045            raise ValueError("Sequence contains no element matching the predicate.")
1046        return single
1047
1048    @overload
1049    def single_or_none(self) -> Optional[T]: ...
1050    @overload
1051    def single_or_none(self, predicate: Callable[[T], bool]) -> Optional[T]: ...
1052    @overload
1053    def single_or_none(self, predicate: Callable[[T, int], bool]) -> Optional[T]: ...
1054    @overload
1055    def single_or_none(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Optional[T]: ...
1056    def single_or_none(self, predicate: Optional[Callable[..., bool]] = None) -> Optional[T]:
1057        """
1058        Returns the single element matching the given [predicate], or `None` if element was not found
1059        or more than one element was found.
1060
1061        Exmaple 1:
1062        >>> lst = ['a']
1063        >>> it(lst).single_or_none()
1064        'a'
1065
1066        Exmaple 2:
1067        >>> lst = []
1068        >>> it(lst).single_or_none()
1069
1070        Exmaple 2:
1071        >>> lst = ['a', 'b']
1072        >>> it(lst).single_or_none()
1073
1074        """
1075        single: Optional[T] = None
1076        found = False
1077        for i in self if predicate is None else self.filter(predicate):
1078            if found:
1079                return None
1080            single = i
1081            found = True
1082        if not found:
1083            return None
1084        return single
1085
1086    # noinspection PyShadowingNames
1087    def drop(self, n: int) -> Sequence[T]:
1088        """
1089        Returns a Sequence containing all elements except first [n] elements.
1090
1091        Example 1:
1092        >>> lst = ['a', 'b', 'c']
1093        >>> it(lst).drop(0).to_list()
1094        ['a', 'b', 'c']
1095
1096        Example 2:
1097        >>> lst = ['a', 'b', 'c']
1098        >>> it(lst).drop(1).to_list()
1099        ['b', 'c']
1100
1101        Example 2:
1102        >>> lst = ['a', 'b', 'c']
1103        >>> it(lst).drop(4).to_list()
1104        []
1105        """
1106        if n < 0:
1107            raise ValueError(f"Requested element count {n} is less than zero.")
1108        if n == 0:
1109            return self
1110
1111        from .drop import DropTransform
1112
1113        return it(DropTransform(self, n))
1114
1115    # noinspection PyShadowingNames
1116    @overload
1117    def drop_while(self, predicate: Callable[[T], bool]) -> Sequence[T]: ...
1118    @overload
1119    def drop_while(self, predicate: Callable[[T, int], bool]) -> Sequence[T]: ...
1120    @overload
1121    def drop_while(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Sequence[T]: ...
1122    def drop_while(self, predicate: Callable[..., bool]) -> Sequence[T]:
1123        """
1124        Returns a Sequence containing all elements except first elements that satisfy the given [predicate].
1125
1126        Example 1:
1127        >>> lst = [1, 2, 3, 4, 1]
1128        >>> it(lst).drop_while(lambda x: x < 3 ).to_list()
1129        [3, 4, 1]
1130        """
1131        from .drop_while import DropWhileTransform
1132
1133        return it(DropWhileTransform(self, self.__callback_overload_warpper__(predicate)))
1134
1135    def skip(self, n: int) -> Sequence[T]:
1136        """
1137        Returns a Sequence containing all elements except first [n] elements.
1138
1139        Example 1:
1140        >>> lst = ['a', 'b', 'c']
1141        >>> it(lst).skip(0).to_list()
1142        ['a', 'b', 'c']
1143
1144         Example 2:
1145        >>> lst = ['a', 'b', 'c']
1146        >>> it(lst).skip(1).to_list()
1147        ['b', 'c']
1148
1149        Example 2:
1150        >>> lst = ['a', 'b', 'c']
1151        >>> it(lst).skip(4).to_list()
1152        []
1153        """
1154        return self.drop(n)
1155
1156    @overload
1157    def skip_while(self, predicate: Callable[[T], bool]) -> Sequence[T]: ...
1158    @overload
1159    def skip_while(self, predicate: Callable[[T, int], bool]) -> Sequence[T]: ...
1160    @overload
1161    def skip_while(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Sequence[T]: ...
1162    def skip_while(self, predicate: Callable[..., bool]) -> Sequence[T]:
1163        """
1164        Returns a Sequence containing all elements except first elements that satisfy the given [predicate].
1165
1166        Example 1:
1167        >>> lst = [1, 2, 3, 4, 1]
1168        >>> it(lst).skip_while(lambda x: x < 3 ).to_list()
1169        [3, 4, 1]
1170        """
1171        return self.drop_while(predicate)
1172
1173    def take(self, n: int) -> Sequence[T]:
1174        """
1175        Returns an Sequence containing first [n] elements.
1176
1177        Example 1:
1178        >>> a = ['a', 'b', 'c']
1179        >>> it(a).take(0).to_list()
1180        []
1181
1182        Example 2:
1183        >>> a = ['a', 'b', 'c']
1184        >>> it(a).take(2).to_list()
1185        ['a', 'b']
1186        """
1187        if n < 0:
1188            raise ValueError(f"Requested element count {n} is less than zero.")
1189        if n == 0:
1190            return Sequence([])
1191        from .take import TakeTransform
1192
1193        return it(TakeTransform(self, n))
1194
1195    # noinspection PyShadowingNames
1196    @overload
1197    def take_while(self, predicate: Callable[[T], bool]) -> Sequence[T]: ...
1198    @overload
1199    def take_while(self, predicate: Callable[[T, int], bool]) -> Sequence[T]: ...
1200    @overload
1201    def take_while(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> Sequence[T]: ...
1202    def take_while(self, predicate: Callable[..., bool]) -> Sequence[T]:
1203        """
1204        Returns an Sequence containing first elements satisfying the given [predicate].
1205
1206        Example 1:
1207        >>> lst = ['a', 'b', 'c', 'd']
1208        >>> it(lst).take_while(lambda x: x in ['a', 'b']).to_list()
1209        ['a', 'b']
1210        """
1211        from .take_while import TakeWhileTransform
1212
1213        return it(TakeWhileTransform(self, self.__callback_overload_warpper__(predicate)))
1214
1215    def take_last(self, n: int) -> Sequence[T]:
1216        """
1217        Returns an Sequence containing last [n] elements.
1218
1219        Example 1:
1220        >>> a = ['a', 'b', 'c']
1221        >>> it(a).take_last(0).to_list()
1222        []
1223
1224        Example 2:
1225        >>> a = ['a', 'b', 'c']
1226        >>> it(a).take_last(2).to_list()
1227        ['b', 'c']
1228        """
1229        if n < 0:
1230            raise ValueError(f"Requested element count {n} is less than zero.")
1231        if n == 0:
1232            return Sequence([])
1233
1234        return self.drop(len(self) - n)
1235
1236    # noinspection PyShadowingNames
1237    def sorted(self) -> Sequence[T]:
1238        """
1239        Returns an Sequence that yields elements of this Sequence sorted according to their natural sort order.
1240
1241        Example 1:
1242        >>> lst = ['b', 'a', 'e', 'c']
1243        >>> it(lst).sorted().to_list()
1244        ['a', 'b', 'c', 'e']
1245
1246         Example 2:
1247        >>> lst = [2, 1, 4, 3]
1248        >>> it(lst).sorted().to_list()
1249        [1, 2, 3, 4]
1250        """
1251        lst = list(self)
1252        lst.sort()  # type: ignore
1253        return it(lst)
1254
1255    # noinspection PyShadowingNames
1256    @overload
1257    def sorted_by(self, key_selector: Callable[[T], SupportsRichComparisonT]) -> Sequence[T]: ...
1258    @overload
1259    def sorted_by(
1260        self, key_selector: Callable[[T, int], SupportsRichComparisonT]
1261    ) -> Sequence[T]: ...
1262    @overload
1263    def sorted_by(
1264        self, key_selector: Callable[[T, int, Sequence[T]], SupportsRichComparisonT]
1265    ) -> Sequence[T]: ...
1266    def sorted_by(self, key_selector: Callable[..., SupportsRichComparisonT]) -> Sequence[T]:
1267        """
1268        Returns a sequence that yields elements of this sequence sorted according to natural sort
1269        order of the value returned by specified [key_selector] function.
1270
1271        Example 1:
1272        >>> lst = [ {'name': 'A', 'age': 12 }, {'name': 'C', 'age': 10 }, {'name': 'B', 'age': 11 } ]
1273        >>> it(lst).sorted_by(lambda x: x['name']).to_list()
1274        [{'name': 'A', 'age': 12}, {'name': 'B', 'age': 11}, {'name': 'C', 'age': 10}]
1275        >>> it(lst).sorted_by(lambda x: x['age']).to_list()
1276        [{'name': 'C', 'age': 10}, {'name': 'B', 'age': 11}, {'name': 'A', 'age': 12}]
1277        """
1278        lst = list(self)
1279        lst.sort(key=self.__callback_overload_warpper__(key_selector))
1280        return it(lst)
1281
1282    def sorted_descending(self) -> Sequence[T]:
1283        """
1284        Returns a Sequence of all elements sorted descending according to their natural sort order.
1285
1286        Example 1:
1287        >>> lst = ['b', 'c', 'a']
1288        >>> it(lst).sorted_descending().to_list()
1289        ['c', 'b', 'a']
1290        """
1291        return self.sorted().reversed()
1292
1293    @overload
1294    def sorted_by_descending(
1295        self, key_selector: Callable[[T], SupportsRichComparisonT]
1296    ) -> Sequence[T]: ...
1297    @overload
1298    def sorted_by_descending(
1299        self, key_selector: Callable[[T, int], SupportsRichComparisonT]
1300    ) -> Sequence[T]: ...
1301    @overload
1302    def sorted_by_descending(
1303        self, key_selector: Callable[[T, int, Sequence[T]], SupportsRichComparisonT]
1304    ) -> Sequence[T]: ...
1305    def sorted_by_descending(
1306        self, key_selector: Callable[..., SupportsRichComparisonT]
1307    ) -> Sequence[T]:
1308        """
1309        Returns a sequence that yields elements of this sequence sorted descending according
1310        to natural sort order of the value returned by specified [key_selector] function.
1311
1312        Example 1:
1313        >>> lst = [ {'name': 'A', 'age': 12 }, {'name': 'C', 'age': 10 }, {'name': 'B', 'age': 11 } ]
1314        >>> it(lst).sorted_by_descending(lambda x: x['name']).to_list()
1315        [{'name': 'C', 'age': 10}, {'name': 'B', 'age': 11}, {'name': 'A', 'age': 12}]
1316        >>> it(lst).sorted_by_descending(lambda x: x['age']).to_list()
1317        [{'name': 'A', 'age': 12}, {'name': 'B', 'age': 11}, {'name': 'C', 'age': 10}]
1318        """
1319        return self.sorted_by(key_selector).reversed()
1320
1321    # noinspection PyShadowingNames
1322    def sorted_with(self, comparator: Callable[[T, T], int]) -> Sequence[T]:
1323        """
1324        Returns a sequence that yields elements of this sequence sorted according to the specified [comparator].
1325
1326        Example 1:
1327        >>> lst = ['aa', 'bbb', 'c']
1328        >>> it(lst).sorted_with(lambda a, b: len(a)-len(b)).to_list()
1329        ['c', 'aa', 'bbb']
1330        """
1331        from functools import cmp_to_key
1332
1333        lst = list(self)
1334        lst.sort(key=cmp_to_key(comparator))
1335        return it(lst)
1336
1337    @overload
1338    def associate(self, transform: Callable[[T], Tuple[K, V]]) -> Dict[K, V]: ...
1339    @overload
1340    def associate(self, transform: Callable[[T, int], Tuple[K, V]]) -> Dict[K, V]: ...
1341    @overload
1342    def associate(self, transform: Callable[[T, int, Sequence[T]], Tuple[K, V]]) -> Dict[K, V]: ...
1343    def associate(self, transform: Callable[..., Tuple[K, V]]) -> Dict[K, V]:
1344        """
1345        Returns a [Dict] containing key-value Tuple provided by [transform] function
1346        applied to elements of the given Sequence.
1347
1348        Example 1:
1349        >>> lst = ['1', '2', '3']
1350        >>> it(lst).associate(lambda x: (int(x), x))
1351        {1: '1', 2: '2', 3: '3'}
1352        """
1353        transform = self.__callback_overload_warpper__(transform)
1354        dic: Dict[K, V] = dict()
1355        for i in self:
1356            k, v = transform(i)
1357            dic[k] = v
1358        return dic
1359
1360    @overload
1361    def associate_by(self, key_selector: Callable[[T], K]) -> Dict[K, T]: ...
1362    @overload
1363    def associate_by(self, key_selector: Callable[[T, int], K]) -> Dict[K, T]: ...
1364    @overload
1365    def associate_by(self, key_selector: Callable[[T, int, Sequence[T]], K]) -> Dict[K, T]: ...
1366    @overload
1367    def associate_by(
1368        self, key_selector: Callable[[T], K], value_transform: Callable[[T], V]
1369    ) -> Dict[K, V]: ...
1370    def associate_by(
1371        self,
1372        key_selector: Callable[..., K],
1373        value_transform: Optional[Callable[[T], V]] = None,
1374    ) -> Union[Dict[K, T], Dict[K, V]]:
1375        """
1376        Returns a [Dict] containing key-value Tuple provided by [transform] function
1377        applied to elements of the given Sequence.
1378
1379        Example 1:
1380        >>> lst = ['1', '2', '3']
1381        >>> it(lst).associate_by(lambda x: int(x))
1382        {1: '1', 2: '2', 3: '3'}
1383
1384        Example 2:
1385        >>> lst = ['1', '2', '3']
1386        >>> it(lst).associate_by(lambda x: int(x), lambda x: x+x)
1387        {1: '11', 2: '22', 3: '33'}
1388
1389        """
1390        key_selector = self.__callback_overload_warpper__(key_selector)
1391
1392        dic: Dict[K, Any] = dict()
1393        for i in self:
1394            k = key_selector(i)
1395            dic[k] = i if value_transform is None else value_transform(i)
1396        return dic
1397
1398    @overload
1399    def associate_by_to(
1400        self, destination: Dict[K, T], key_selector: Callable[[T], K]
1401    ) -> Dict[K, T]: ...
1402    @overload
1403    def associate_by_to(
1404        self,
1405        destination: Dict[K, V],
1406        key_selector: Callable[[T], K],
1407        value_transform: Callable[[T], V],
1408    ) -> Dict[K, V]: ...
1409    def associate_by_to(
1410        self,
1411        destination: Dict[K, Any],
1412        key_selector: Callable[[T], K],
1413        value_transform: Optional[Callable[[T], Any]] = None,
1414    ) -> Dict[K, Any]:
1415        """
1416        Returns a [Dict] containing key-value Tuple provided by [transform] function
1417        applied to elements of the given Sequence.
1418
1419        Example 1:
1420        >>> lst = ['1', '2', '3']
1421        >>> it(lst).associate_by_to({}, lambda x: int(x))
1422        {1: '1', 2: '2', 3: '3'}
1423
1424        Example 2:
1425        >>> lst = ['1', '2', '3']
1426        >>> it(lst).associate_by_to({}, lambda x: int(x), lambda x: x+'!' )
1427        {1: '1!', 2: '2!', 3: '3!'}
1428
1429        """
1430        for i in self:
1431            k = key_selector(i)
1432            destination[k] = i if value_transform is None else value_transform(i)
1433        return destination
1434
1435    @overload
1436    def all(self, predicate: Callable[[T], bool]) -> bool: ...
1437    @overload
1438    def all(self, predicate: Callable[[T, int], bool]) -> bool: ...
1439    @overload
1440    def all(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> bool: ...
1441    def all(self, predicate: Callable[..., bool]) -> bool:
1442        """
1443        Returns True if all elements of the Sequence satisfy the specified [predicate] function.
1444
1445        Example 1:
1446        >>> lst = [1, 2, 3]
1447        >>> it(lst).all(lambda x: x > 0)
1448        True
1449        >>> it(lst).all(lambda x: x > 1)
1450        False
1451        """
1452        predicate = self.__callback_overload_warpper__(predicate)
1453        for i in self:
1454            if not predicate(i):
1455                return False
1456        return True
1457
1458    @overload
1459    def any(self, predicate: Callable[[T], bool]) -> bool: ...
1460    @overload
1461    def any(self, predicate: Callable[[T, int], bool]) -> bool: ...
1462    @overload
1463    def any(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> bool: ...
1464    def any(self, predicate: Callable[..., bool]) -> bool:
1465        """
1466        Returns True if any elements of the Sequence satisfy the specified [predicate] function.
1467
1468        Example 1:
1469        >>> lst = [1, 2, 3]
1470        >>> it(lst).any(lambda x: x > 0)
1471        True
1472        >>> it(lst).any(lambda x: x > 3)
1473        False
1474        """
1475        predicate = self.__callback_overload_warpper__(predicate)
1476        for i in self:
1477            if predicate(i):
1478                return True
1479        return False
1480
1481    @overload
1482    def count(self) -> int: ...
1483    @overload
1484    def count(self, predicate: Callable[[T], bool]) -> int: ...
1485    @overload
1486    def count(self, predicate: Callable[[T, int], bool]) -> int: ...
1487    @overload
1488    def count(self, predicate: Callable[[T, int, Sequence[T]], bool]) -> int: ...
1489    def count(self, predicate: Optional[Callable[..., bool]] = None) -> int:
1490        """
1491        Returns the number of elements in the Sequence that satisfy the specified [predicate] function.
1492
1493        Example 1:
1494        >>> lst = [1, 2, 3]
1495        >>> it(lst).count()
1496        3
1497        >>> it(lst).count(lambda x: x > 0)
1498        3
1499        >>> it(lst).count(lambda x: x > 2)
1500        1
1501        """
1502        if predicate is None:
1503            return len(self)
1504        predicate = self.__callback_overload_warpper__(predicate)
1505        return sum(1 for i in self if predicate(i))
1506
1507    def contains(self, value: T) -> bool:
1508        """
1509        Returns True if the Sequence contains the specified [value].
1510
1511        Example 1:
1512        >>> lst = [1, 2, 3]
1513        >>> it(lst).contains(1)
1514        True
1515        >>> it(lst).contains(4)
1516        False
1517        """
1518        return value in self
1519
1520    def element_at(self, index: int) -> T:
1521        """
1522        Returns the element at the specified [index] in the Sequence.
1523
1524        Example 1:
1525        >>> lst = [1, 2, 3]
1526        >>> it(lst).element_at(1)
1527        2
1528
1529        Example 2:
1530        >>> lst = [1, 2, 3]
1531        >>> it(lst).element_at(3)
1532        Traceback (most recent call last):
1533        ...
1534        IndexError: Index 3 out of range
1535        """
1536        return self.element_at_or_else(
1537            index, lambda index: throw(IndexError(f"Index {index} out of range"))
1538        )
1539
1540    @overload
1541    def element_at_or_else(self, index: int) -> Optional[T]:
1542        """
1543        Returns the element at the specified [index] in the Sequence or the [default] value if the index is out of bounds.
1544
1545        Example 1:
1546        >>> lst = [1, 2, 3]
1547        >>> it(lst).element_at_or_else(1, 'default')
1548        2
1549        >>> it(lst).element_at_or_else(4, lambda x: 'default')
1550        'default'
1551        """
1552        ...
1553
1554    @overload
1555    def element_at_or_else(self, index: int, default: T) -> T: ...
1556    @overload
1557    def element_at_or_else(self, index: int, default: Callable[[int], T]) -> T: ...
1558    def element_at_or_else(
1559        self, index: int, default: Union[Callable[[int], T], T, None] = None
1560    ) -> Optional[T]:
1561        """
1562        Returns the element at the specified [index] in the Sequence or the [default] value if the index is out of bounds.
1563
1564        Example 1:
1565        >>> lst = [1, 2, 3]
1566        >>> it(lst).element_at_or_else(1, lambda x: 'default')
1567        2
1568        >>> it(lst).element_at_or_else(4, lambda x: 'default')
1569        'default'
1570
1571        """
1572        if index >= 0:
1573            if (
1574                isinstance(self.__transform__, NonTransform)
1575                and isinstance(self.__transform__.iter, list)
1576                and index < len(self.__transform__.iter)
1577            ):
1578                return self.__transform__.iter[index]
1579            for i, e in enumerate(self):
1580                if i == index:
1581                    return e
1582        return default(index) if callable(default) else default  # type: ignore
1583
1584    def element_at_or_default(self, index: int, default: T) -> T:
1585        """
1586        Returns the element at the specified [index] in the Sequence or the [default] value if the index is out of bounds.
1587
1588        Example 1:
1589        >>> lst = [1, 2, 3]
1590        >>> it(lst).element_at_or_default(1, 'default')
1591        2
1592        >>> it(lst).element_at_or_default(4, 'default')
1593        'default'
1594
1595        """
1596        return self.element_at_or_else(index, default)
1597
1598    def element_at_or_none(self, index: int) -> Optional[T]:
1599        """
1600        Returns the element at the specified [index] in the Sequence or None if the index is out of bounds.
1601
1602        Example 1:
1603        >>> lst = [1, 2, 3]
1604        >>> it(lst).element_at_or_none(1)
1605        2
1606        >>> it(lst).element_at_or_none(4) is None
1607        True
1608        """
1609        return self.element_at_or_else(index)
1610
1611    def distinct(self) -> Sequence[T]:
1612        """
1613        Returns a new Sequence containing the distinct elements of the given Sequence.
1614
1615        Example 1:
1616        >>> lst = [1, 2, 3, 1, 2, 3]
1617        >>> it(lst).distinct().to_list()
1618        [1, 2, 3]
1619
1620        Example 2:
1621        >>> lst = [(1, 'A'), (1, 'A'), (1, 'A'), (2, 'A'), (3, 'C'), (3, 'D')]
1622        >>> it(lst).distinct().sorted().to_list()
1623        [(1, 'A'), (2, 'A'), (3, 'C'), (3, 'D')]
1624
1625        """
1626        from .distinct import DistinctTransform
1627
1628        return it(DistinctTransform(self))
1629
1630    @overload
1631    def distinct_by(self, key_selector: Callable[[T], Any]) -> Sequence[T]: ...
1632    @overload
1633    def distinct_by(self, key_selector: Callable[[T, int], Any]) -> Sequence[T]: ...
1634    @overload
1635    def distinct_by(self, key_selector: Callable[[T, int, Sequence[T]], Any]) -> Sequence[T]: ...
1636    def distinct_by(self, key_selector: Callable[..., Any]) -> Sequence[T]:
1637        """
1638        Returns a new Sequence containing the distinct elements of the given Sequence.
1639
1640        Example 1:
1641        >>> lst = [1, 2, 3, 1, 2, 3]
1642        >>> it(lst).distinct_by(lambda x: x%2).to_list()
1643        [1, 2]
1644        """
1645        from .distinct import DistinctTransform
1646
1647        return it(DistinctTransform(self, self.__callback_overload_warpper__(key_selector)))
1648
1649    @overload
1650    def reduce(self, accumulator: Callable[[T, T], T]) -> T: ...
1651    @overload
1652    def reduce(self, accumulator: Callable[[U, T], U], initial: U) -> U: ...
1653    def reduce(self, accumulator: Callable[..., U], initial: Optional[U] = None) -> Optional[U]:
1654        """
1655        Returns the result of applying the specified [accumulator] function to the given Sequence's elements.
1656
1657        Example 1:
1658        >>> lst = [1, 2, 3]
1659        >>> it(lst).reduce(lambda x, y: x+y)
1660        6
1661        """
1662        result: Optional[U] = initial
1663        for i, e in enumerate(self):
1664            if i == 0 and initial is None:
1665                result = e  # type: ignore
1666                continue
1667
1668            result = accumulator(result, e)
1669        return result
1670
1671    def fold(self, initial: U, accumulator: Callable[[U, T], U]) -> U:
1672        """
1673        Returns the result of applying the specified [accumulator] function to the given Sequence's elements.
1674
1675        Example 1:
1676        >>> lst = [1, 2, 3]
1677        >>> it(lst).fold(0, lambda x, y: x+y)
1678        6
1679        """
1680        return self.reduce(accumulator, initial)
1681
1682    @overload
1683    def sum_of(self, selector: Callable[[T], int]) -> int: ...
1684    @overload
1685    def sum_of(self, selector: Callable[[T], float]) -> float: ...
1686    def sum_of(self, selector: Callable[[T], Union[int, float]]) -> Union[int, float]:
1687        """
1688        Returns the sum of the elements of the given Sequence.
1689
1690        Example 1:
1691        >>> lst = [1, 2, 3]
1692        >>> it(lst).sum_of(lambda x: x)
1693        6
1694        """
1695        return sum(selector(i) for i in self)
1696
1697    @overload
1698    def max_of(self, selector: Callable[[T], int]) -> int: ...
1699    @overload
1700    def max_of(self, selector: Callable[[T], float]) -> float: ...
1701    def max_of(self, selector: Callable[[T], Union[int, float]]) -> Union[int, float]:
1702        """
1703        Returns the maximum element of the given Sequence.
1704
1705        Example 1:
1706        >>> lst = [1, 2, 3]
1707        >>> it(lst).max_of(lambda x: x)
1708        3
1709        """
1710        return max(selector(i) for i in self)
1711
1712    @overload
1713    def max_by_or_none(self, selector: Callable[[T], int]) -> Optional[T]: ...
1714    @overload
1715    def max_by_or_none(self, selector: Callable[[T], float]) -> Optional[T]: ...
1716    def max_by_or_none(self, selector: Callable[[T], Union[float, int]]) -> Optional[T]:
1717        """
1718        Returns the first element yielding the largest value of the given function
1719        or `none` if there are no elements.
1720
1721        Example 1:
1722        >>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
1723        >>> it(lst).max_by_or_none(lambda x: x["num"])
1724        {'name': 'B', 'num': 200}
1725
1726        Example 2:
1727        >>> lst = []
1728        >>> it(lst).max_by_or_none(lambda x: x["num"])
1729        """
1730
1731        max_item = None
1732        max_val = None
1733
1734        for item in self:
1735            val = selector(item)
1736            if max_val is None or val > max_val:
1737                max_item = item
1738                max_val = val
1739
1740        return max_item
1741
1742    @overload
1743    def max_by(self, selector: Callable[[T], int]) -> T: ...
1744    @overload
1745    def max_by(self, selector: Callable[[T], float]) -> T: ...
1746    def max_by(self, selector: Callable[[T], Union[float, int]]) -> T:
1747        """
1748        Returns the first element yielding the largest value of the given function.
1749
1750        Example 1:
1751        >>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
1752        >>> it(lst).max_by(lambda x: x["num"])
1753        {'name': 'B', 'num': 200}
1754
1755        Exmaple 2:
1756        >>> lst = []
1757        >>> it(lst).max_by(lambda x: x["num"])
1758        Traceback (most recent call last):
1759        ...
1760        ValueError: Sequence is empty.
1761        """
1762        max_item = self.max_by_or_none(selector)
1763        if max_item is None:
1764            raise ValueError("Sequence is empty.")
1765        return max_item
1766
1767    @overload
1768    def min_of(self, selector: Callable[[T], int]) -> int:
1769        """
1770        Returns the minimum element of the given Sequence.
1771
1772        Example 1:
1773        >>> lst = [1, 2, 3]
1774        >>> it(lst).min_of(lambda x: x)
1775        1
1776        """
1777        ...
1778
1779    @overload
1780    def min_of(self, selector: Callable[[T], float]) -> float: ...
1781    def min_of(self, selector: Callable[[T], Union[int, float]]) -> Union[int, float]:
1782        return min(selector(i) for i in self)
1783
1784    @overload
1785    def min_by_or_none(self, selector: Callable[[T], int]) -> Optional[T]: ...
1786    @overload
1787    def min_by_or_none(self, selector: Callable[[T], float]) -> Optional[T]: ...
1788    def min_by_or_none(self, selector: Callable[[T], float]) -> Optional[T]:
1789        """
1790        Returns the first element yielding the smallest value of the given function
1791        or `none` if there are no elements.
1792
1793        Example 1:
1794        >>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
1795        >>> it(lst).min_by_or_none(lambda x: x["num"])
1796        {'name': 'A', 'num': 100}
1797
1798        Exmaple 2:
1799        >>> lst = []
1800        >>> it(lst).min_by_or_none(lambda x: x["num"])
1801        """
1802        min_item = None
1803        min_val = None
1804
1805        for item in self:
1806            val = selector(item)
1807            if min_val is None or val < min_val:
1808                min_item = item
1809                min_val = val
1810
1811        return min_item
1812
1813    @overload
1814    def min_by(self, selector: Callable[[T], int]) -> T: ...
1815    @overload
1816    def min_by(self, selector: Callable[[T], float]) -> T: ...
1817    def min_by(self, selector: Callable[[T], float]) -> T:
1818        """
1819        Returns the first element yielding the smallest value of the given function.
1820
1821        Example 1:
1822        >>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
1823        >>> it(lst).min_by(lambda x: x["num"])
1824        {'name': 'A', 'num': 100}
1825
1826        Exmaple 2:
1827        >>> lst = []
1828        >>> it(lst).min_by(lambda x: x["num"])
1829        Traceback (most recent call last):
1830        ...
1831        ValueError: Sequence is empty.
1832        """
1833        min_item = self.min_by_or_none(selector)
1834        if min_item is None:
1835            raise ValueError("Sequence is empty.")
1836
1837        return min_item
1838
1839    def mean_of(self, selector: Callable[[T], Union[int, float]]) -> Union[int, float]:
1840        """
1841        Returns the mean of the elements of the given Sequence.
1842
1843        Example 1:
1844        >>> lst = [1, 2, 3]
1845        >>> it(lst).mean_of(lambda x: x)
1846        2.0
1847        """
1848        return self.sum_of(selector) / len(self)
1849
1850    @overload
1851    def sum(self: Sequence[int]) -> int:
1852        """
1853        Returns the sum of the elements of the given Sequence.
1854
1855        Example 1:
1856        >>> lst = [1, 2, 3]
1857        >>> it(lst).sum()
1858        6
1859        """
1860        ...
1861
1862    @overload
1863    def sum(self: Sequence[float]) -> float: ...
1864    def sum(self: Union[Sequence[int], Sequence[float]]) -> Union[float, int]:
1865        """
1866        Returns the sum of the elements of the given Sequence.
1867
1868        Example 1:
1869        >>> lst = [1, 2, 3]
1870        >>> it(lst).sum()
1871        6
1872        """
1873        return sum(self)
1874
1875    @overload
1876    def max(self: Sequence[int]) -> int: ...
1877    @overload
1878    def max(self: Sequence[float]) -> float: ...
1879    def max(self: Union[Sequence[int], Sequence[float]]) -> Union[float, int]:
1880        """
1881        Returns the maximum element of the given Sequence.
1882
1883        Example 1:
1884        >>> lst = [1, 2, 3]
1885        >>> it(lst).max()
1886        3
1887        """
1888        return max(self)
1889
1890    @overload
1891    def max_or_default(self: Sequence[int]) -> int: ...
1892    @overload
1893    def max_or_default(self: Sequence[int], default: V) -> Union[int, V]: ...
1894    @overload
1895    def max_or_default(self: Sequence[float]) -> float: ...
1896    @overload
1897    def max_or_default(self: Sequence[float], default: V) -> Union[float, V]: ...
1898    def max_or_default(
1899        self: Union[Sequence[int], Sequence[float]], default: Optional[V] = None
1900    ) -> Union[float, int, V, None]:
1901        """
1902        Returns the maximum element of the given Sequence.
1903
1904        Example 1:
1905        >>> lst = [1, 2, 3]
1906        >>> it(lst).max_or_default()
1907        3
1908
1909        Example 2:
1910        >>> lst = []
1911        >>> it(lst).max_or_default() is None
1912        True
1913
1914        Example 3:
1915        >>> lst = []
1916        >>> it(lst).max_or_default(9)
1917        9
1918        """
1919        if self.is_empty():
1920            return default
1921        return max(self)
1922
1923    @overload
1924    def max_or_none(self: Sequence[int]) -> int: ...
1925    @overload
1926    def max_or_none(self: Sequence[float]) -> float: ...
1927    def max_or_none(
1928        self: Union[Sequence[int], Sequence[float]],
1929    ) -> Union[float, int, None]:
1930        """
1931        Returns the maximum element of the given Sequence.
1932
1933        Example 1:
1934        >>> lst = [1, 2, 3]
1935        >>> it(lst).max_or_none()
1936        3
1937
1938        Example 2:
1939        >>> lst = []
1940        >>> it(lst).max_or_none() is None
1941        True
1942        """
1943        return self.max_or_default(None)
1944
1945    @overload
1946    def min(self: Sequence[int]) -> int:
1947        """
1948        Returns the minimum element of the given Sequence.
1949
1950        Example 1:
1951        >>> lst = [1, 2, 3]
1952        >>> it(lst).min()
1953        1
1954        """
1955        ...
1956
1957    @overload
1958    def min(self: Sequence[float]) -> float: ...
1959    def min(self: Union[Sequence[int], Sequence[float]]) -> Union[float, int]:
1960        """
1961        Returns the minimum element of the given Sequence.
1962
1963        Example 1:
1964        >>> lst = [1, 2, 3]
1965        >>> it(lst).min()
1966        1
1967        """
1968        return min(self)
1969
1970    @overload
1971    def min_or_none(self: Sequence[int]) -> Optional[int]:
1972        """
1973        Returns the minimum element of the given Sequence.
1974
1975        Example 1:
1976        >>> lst = [1, 2, 3]
1977        >>> it(lst).min_or_none()
1978        1
1979        """
1980        ...
1981
1982    @overload
1983    def min_or_none(self: Sequence[float]) -> Optional[float]: ...
1984    def min_or_none(
1985        self: Union[Sequence[int], Sequence[float]],
1986    ) -> Union[float, int, None]:
1987        """
1988        Returns the minimum element of the given Sequence.
1989
1990        Example 1:
1991        >>> lst = [1, 2, 3]
1992        >>> it(lst).min_or_none()
1993        1
1994        """
1995        return self.min_or_default(None)
1996
1997    @overload
1998    def min_or_default(self: Sequence[int]) -> int:
1999        """
2000        Returns the minimum element of the given Sequence.
2001
2002        Example 1:
2003        >>> lst = [1, 2, 3]
2004        >>> it(lst).min_or_default()
2005        1
2006        """
2007        ...
2008
2009    @overload
2010    def min_or_default(self: Sequence[int], default: V) -> Union[int, V]: ...
2011    @overload
2012    def min_or_default(self: Sequence[float]) -> float: ...
2013    @overload
2014    def min_or_default(self: Sequence[float], default: V) -> Union[float, V]: ...
2015    def min_or_default(
2016        self: Union[Sequence[int], Sequence[float]], default: Optional[V] = None
2017    ) -> Union[float, int, V, None]:
2018        """
2019        Returns the minimum element of the given Sequence.
2020
2021        Example 1:
2022        >>> lst = [1, 2, 3]
2023        >>> it(lst).min_or_default()
2024        1
2025
2026        Example 2:
2027        >>> lst = []
2028        >>> it(lst).min_or_default(9)
2029        9
2030        """
2031        if self.is_empty():
2032            return default
2033        return min(self)
2034
2035    @overload
2036    def mean(self: Sequence[int]) -> float:
2037        """
2038        Returns the mean of the elements of the given Sequence.
2039
2040        Example 1:
2041        >>> lst = [1, 2, 3]
2042        >>> it(lst).mean()
2043        2.0
2044        """
2045        ...
2046
2047    @overload
2048    def mean(self: Sequence[float]) -> float: ...
2049    def mean(self: Union[Sequence[int], Sequence[float]]) -> float:
2050        """
2051        Returns the mean of the elements of the given Sequence.
2052
2053        Example 1:
2054        >>> lst = [1, 2, 3]
2055        >>> it(lst).mean()
2056        2.0
2057        """
2058        return self.sum() / len(self)
2059
2060    # noinspection PyShadowingNames
2061    def reversed(self) -> Sequence[T]:
2062        """
2063        Returns a list with elements in reversed order.
2064
2065        Example 1:
2066        >>> lst = ['b', 'c', 'a']
2067        >>> it(lst).reversed().to_list()
2068        ['a', 'c', 'b']
2069        """
2070        lst = list(self)
2071        lst.reverse()
2072        return it(lst)
2073
2074    @overload
2075    def flat_map(self, transform: Callable[[T], Iterable[U]]) -> Sequence[U]: ...
2076    @overload
2077    def flat_map(self, transform: Callable[[T, int], Iterable[U]]) -> Sequence[U]: ...
2078    @overload
2079    def flat_map(self, transform: Callable[[T, int, Sequence[T]], Iterable[U]]) -> Sequence[U]: ...
2080    def flat_map(self, transform: Callable[..., Iterable[U]]) -> Sequence[U]:
2081        """
2082        Returns a single list of all elements yielded from results of [transform]
2083        function being invoked on each element of original collection.
2084
2085        Example 1:
2086        >>> lst = [['a', 'b'], ['c'], ['d', 'e']]
2087        >>> it(lst).flat_map(lambda x: x).to_list()
2088        ['a', 'b', 'c', 'd', 'e']
2089        """
2090        return self.map(transform).flatten()
2091
2092    def flatten(self: Iterable[Iterable[U]]) -> Sequence[U]:
2093        """
2094        Returns a sequence of all elements from all sequences in this sequence.
2095
2096        Example 1:
2097        >>> lst = [['a', 'b'], ['c'], ['d', 'e']]
2098        >>> it(lst).flatten().to_list()
2099        ['a', 'b', 'c', 'd', 'e']
2100        """
2101        from .flattening import FlatteningTransform
2102
2103        return it(FlatteningTransform(self))
2104
2105    @overload
2106    def group_by(self, key_selector: Callable[[T], K]) -> Sequence[Grouping[K, T]]: ...
2107    @overload
2108    def group_by(self, key_selector: Callable[[T, int], K]) -> Sequence[Grouping[K, T]]: ...
2109    @overload
2110    def group_by(
2111        self, key_selector: Callable[[T, int, Sequence[T]], K]
2112    ) -> Sequence[Grouping[K, T]]: ...
2113    def group_by(self, key_selector: Callable[..., K]) -> Sequence[Grouping[K, T]]:
2114        """
2115        Returns a dictionary with keys being the result of [key_selector] function being invoked on each element of original collection
2116        and values being the corresponding elements of original collection.
2117
2118        Example 1:
2119        >>> lst = [1, 2, 3, 4, 5]
2120        >>> it(lst).group_by(lambda x: x%2).map(lambda x: (x.key, x.values.to_list())).to_list()
2121        [(1, [1, 3, 5]), (0, [2, 4])]
2122        """
2123        from .grouping import GroupingTransform
2124
2125        return it(GroupingTransform(self, self.__callback_overload_warpper__(key_selector)))
2126
2127    @overload
2128    def group_by_to(
2129        self, destination: Dict[K, List[T]], key_selector: Callable[[T], K]
2130    ) -> Dict[K, List[T]]: ...
2131    @overload
2132    def group_by_to(
2133        self, destination: Dict[K, List[T]], key_selector: Callable[[T, int], K]
2134    ) -> Dict[K, List[T]]: ...
2135    @overload
2136    def group_by_to(
2137        self,
2138        destination: Dict[K, List[T]],
2139        key_selector: Callable[[T, int, Sequence[T]], K],
2140    ) -> Dict[K, List[T]]: ...
2141    def group_by_to(
2142        self, destination: Dict[K, List[T]], key_selector: Callable[..., K]
2143    ) -> Dict[K, List[T]]:
2144        """
2145        Returns a dictionary with keys being the result of [key_selector] function being invoked on each element of original collection
2146        and values being the corresponding elements of original collection.
2147
2148        Example 1:
2149        >>> lst = [1, 2, 3, 4, 5]
2150        >>> it(lst).group_by_to({}, lambda x: x%2)
2151        {1: [1, 3, 5], 0: [2, 4]}
2152        """
2153        key_selector = self.__callback_overload_warpper__(key_selector)
2154        for e in self:
2155            k = key_selector(e)
2156            if k not in destination:
2157                destination[k] = []
2158            destination[k].append(e)
2159        return destination
2160
2161    @overload
2162    def for_each(self, action: Callable[[T], None]) -> None: ...
2163    @overload
2164    def for_each(self, action: Callable[[T, int], None]) -> None: ...
2165    @overload
2166    def for_each(self, action: Callable[[T, int, Sequence[T]], None]) -> None: ...
2167    def for_each(self, action: Callable[..., None]) -> None:
2168        """
2169        Invokes [action] function on each element of the given Sequence.
2170
2171        Example 1:
2172        >>> lst = ['a', 'b', 'c']
2173        >>> it(lst).for_each(lambda x: print(x))
2174        a
2175        b
2176        c
2177
2178        Example 2:
2179        >>> lst = ['a', 'b', 'c']
2180        >>> it(lst).for_each(lambda x, i: print(x, i))
2181        a 0
2182        b 1
2183        c 2
2184        """
2185        self.on_each(action)
2186
2187    @overload
2188    def parallel_for_each(
2189        self, action: Callable[[T], None], max_workers: Optional[int] = None
2190    ) -> None: ...
2191    @overload
2192    def parallel_for_each(
2193        self, action: Callable[[T, int], None], max_workers: Optional[int] = None
2194    ) -> None: ...
2195    @overload
2196    def parallel_for_each(
2197        self,
2198        action: Callable[[T, int, Sequence[T]], None],
2199        max_workers: Optional[int] = None,
2200    ) -> None: ...
2201    def parallel_for_each(
2202        self, action: Callable[..., None], max_workers: Optional[int] = None
2203    ) -> None:
2204        """
2205        Invokes [action] function on each element of the given Sequence in parallel.
2206
2207        Example 1:
2208        >>> lst = ['a', 'b', 'c']
2209        >>> it(lst).parallel_for_each(lambda x: print(x))
2210        a
2211        b
2212        c
2213
2214        Example 2:
2215        >>> lst = ['a', 'b', 'c']
2216        >>> it(lst).parallel_for_each(lambda x: print(x), max_workers=2)
2217        a
2218        b
2219        c
2220        """
2221        self.parallel_on_each(action, max_workers)
2222
2223    @overload
2224    def on_each(self, action: Callable[[T], None]) -> Sequence[T]: ...
2225    @overload
2226    def on_each(self, action: Callable[[T, int], None]) -> Sequence[T]: ...
2227    @overload
2228    def on_each(self, action: Callable[[T, int, Sequence[T]], None]) -> Sequence[T]: ...
2229    def on_each(self, action: Callable[..., None]) -> Sequence[T]:
2230        """
2231        Invokes [action] function on each element of the given Sequence.
2232
2233        Example 1:
2234        >>> lst = ['a', 'b', 'c']
2235        >>> it(lst).on_each(lambda x: print(x)) and None
2236        a
2237        b
2238        c
2239
2240        Example 2:
2241        >>> lst = ['a', 'b', 'c']
2242        >>> it(lst).on_each(lambda x, i: print(x, i)) and None
2243        a 0
2244        b 1
2245        c 2
2246        """
2247        action = self.__callback_overload_warpper__(action)
2248        for i in self:
2249            action(i)
2250        return self
2251
2252    @overload
2253    def parallel_on_each(
2254        self,
2255        action: Callable[[T], None],
2256        max_workers: Optional[int] = None,
2257        chunksize: int = 1,
2258        executor: "ParallelMappingTransform.Executor" = "Thread",
2259    ) -> Sequence[T]: ...
2260    @overload
2261    def parallel_on_each(
2262        self,
2263        action: Callable[[T, int], None],
2264        max_workers: Optional[int] = None,
2265        chunksize: int = 1,
2266        executor: "ParallelMappingTransform.Executor" = "Thread",
2267    ) -> Sequence[T]: ...
2268    @overload
2269    def parallel_on_each(
2270        self,
2271        action: Callable[[T, int, Sequence[T]], None],
2272        max_workers: Optional[int] = None,
2273        chunksize: int = 1,
2274        executor: "ParallelMappingTransform.Executor" = "Thread",
2275    ) -> Sequence[T]: ...
2276    def parallel_on_each(
2277        self,
2278        action: Callable[..., None],
2279        max_workers: Optional[int] = None,
2280        chunksize: int = 1,
2281        executor: "ParallelMappingTransform.Executor" = "Thread",
2282    ) -> Sequence[T]:
2283        """
2284        Invokes [action] function on each element of the given Sequence.
2285
2286        Example 1:
2287        >>> lst = ['a', 'b', 'c']
2288        >>> it(lst).parallel_on_each(lambda x: print(x)) and None
2289        a
2290        b
2291        c
2292
2293        Example 2:
2294        >>> lst = ['a', 'b', 'c']
2295        >>> it(lst).parallel_on_each(lambda x: print(x), max_workers=2) and None
2296        a
2297        b
2298        c
2299        """
2300        from .parallel_mapping import ParallelMappingTransform
2301
2302        action = self.__callback_overload_warpper__(action)
2303        for _ in ParallelMappingTransform(self, action, max_workers, chunksize, executor):
2304            pass
2305        return self
2306
2307    @overload
2308    def zip(self, other: Iterable[U]) -> Sequence[Tuple[T, U]]: ...
2309    @overload
2310    def zip(self, other: Iterable[U], transform: Callable[[T, U], V]) -> Sequence[V]: ...
2311    def zip(
2312        self,
2313        other: Iterable[Any],
2314        transform: Optional[Callable[..., V]] = None,  # type: ignore
2315    ) -> Sequence[Any]:
2316        """
2317        Returns a new Sequence of tuples, where each tuple contains two elements.
2318
2319        Example 1:
2320        >>> lst1 = ['a', 'b', 'c']
2321        >>> lst2 = [1, 2, 3]
2322        >>> it(lst1).zip(lst2).to_list()
2323        [('a', 1), ('b', 2), ('c', 3)]
2324
2325        Example 2:
2326        >>> lst1 = ['a', 'b', 'c']
2327        >>> lst2 = [1, 2, 3]
2328        >>> it(lst1).zip(lst2, lambda x, y: x + '__' +str( y)).to_list()
2329        ['a__1', 'b__2', 'c__3']
2330        """
2331        if transform is None:
2332
2333            def transform(*x: Any) -> Tuple[Any, ...]:
2334                return (*x,)
2335
2336        from .merging import MergingTransform
2337
2338        return it(MergingTransform(self, other, transform))
2339
2340    @overload
2341    def zip_with_next(self) -> Sequence[Tuple[T, T]]: ...
2342    @overload
2343    def zip_with_next(self, transform: Callable[[T, T], V]) -> Sequence[V]: ...
2344    def zip_with_next(self, transform: Optional[Callable[[T, T], Any]] = None) -> Sequence[Any]:
2345        """
2346        Returns a sequence containing the results of applying the given [transform] function
2347        to an each pair of two adjacent elements in this sequence.
2348
2349        Example 1:
2350        >>> lst = ['a', 'b', 'c']
2351        >>> it(lst).zip_with_next(lambda x, y: x + '__' + y).to_list()
2352        ['a__b', 'b__c']
2353
2354        Example 2:
2355        >>> lst = ['a', 'b', 'c']
2356        >>> it(lst).zip_with_next().to_list()
2357        [('a', 'b'), ('b', 'c')]
2358        """
2359        from .merging_with_next import MergingWithNextTransform
2360
2361        return it(MergingWithNextTransform(self, transform or (lambda a, b: (a, b))))
2362
2363    @overload
2364    def unzip(self: Sequence[Tuple[U, V]]) -> "Tuple[ListLike[U], ListLike[V]]": ...
2365    @overload
2366    def unzip(self, transform: Callable[[T], Tuple[U, V]]) -> "Tuple[ListLike[U], ListLike[V]]": ...
2367    @overload
2368    def unzip(
2369        self, transform: Callable[[T, int], Tuple[U, V]]
2370    ) -> "Tuple[ListLike[U], ListLike[V]]": ...
2371    @overload
2372    def unzip(
2373        self, transform: Callable[[T, int, Sequence[T]], Tuple[U, V]]
2374    ) -> "Tuple[ListLike[U], ListLike[V]]": ...
2375    def unzip(  # type: ignore
2376        self: Sequence[Tuple[U, V]],
2377        transform: Union[Optional[Callable[..., Tuple[Any, Any]]], bool] = None,
2378    ) -> "Tuple[ListLike[U], ListLike[V]]":
2379        """
2380        Returns a pair of lists, where first list is built from the first values of each pair from this array, second list is built from the second values of each pair from this array.
2381
2382        Example 1:
2383        >>> lst = [{'name': 'a', 'age': 11}, {'name': 'b', 'age': 12}, {'name': 'c', 'age': 13}]
2384        >>> a, b = it(lst).unzip(lambda x: (x['name'], x['age']))
2385        >>> a
2386        ['a', 'b', 'c']
2387        >>> b
2388        [11, 12, 13]
2389
2390        Example 1:
2391        >>> lst = [('a', 11), ('b', 12), ('c', 13)]
2392        >>> a, b = it(lst).unzip()
2393        >>> a
2394        ['a', 'b', 'c']
2395        >>> b
2396        [11, 12, 13]
2397        """
2398        from .list_like import ListLike
2399
2400        it = self
2401        if isinstance(transform, bool):
2402            transform = None
2403
2404        if transform is not None:
2405            transform = self.__callback_overload_warpper__(transform)
2406            it = it.map(transform)
2407
2408        a = it.map(lambda x: x[0])  # type: ignore
2409        b = it.map(lambda x: x[1])  # type: ignore
2410
2411        return ListLike(a), ListLike(b)
2412
2413    def with_index(self):
2414        """
2415        Returns a sequence containing the elements of this sequence and their indexes.
2416
2417        Example 1:
2418        >>> lst = ['a', 'b', 'c']
2419        >>> it(lst).with_index().to_list()
2420        [IndexedValue(0, a), IndexedValue(1, b), IndexedValue(2, c)]
2421        """
2422        return self.indexed()
2423
2424    @overload
2425    def shuffled(self) -> Sequence[T]: ...
2426    @overload
2427    def shuffled(self, seed: int) -> Sequence[T]: ...
2428    @overload
2429    def shuffled(self, seed: str) -> Sequence[T]: ...
2430    @overload
2431    def shuffled(self, random: "Random") -> Sequence[T]: ...
2432    def shuffled(  # type: ignore
2433        self, random: Optional[Union["Random", int, str]] = None
2434    ) -> Sequence[T]:
2435        """
2436        Returns a sequence that yields elements of this sequence randomly shuffled
2437        using the specified [random] instance as the source of randomness.
2438
2439        Example 1:
2440        >>> lst = ['a', 'b', 'c']
2441        >>> it(lst).shuffled('123').to_list()
2442        ['b', 'a', 'c']
2443
2444        Example 2:
2445        >>> from random import Random
2446        >>> lst = ['a', 'b', 'c']
2447        >>> it(lst).shuffled(Random('123')).to_list()
2448        ['b', 'a', 'c']
2449
2450        Example 3:
2451        >>> lst = ['a', 'b', 'c']
2452        >>> it(lst).shuffled(123).to_list()
2453        ['c', 'b', 'a']
2454        """
2455        from .shuffling import ShufflingTransform
2456
2457        return it(ShufflingTransform(self, random))
2458
2459    @overload
2460    def partition(self, predicate: Callable[[T], bool]) -> "Tuple[ListLike[T], ListLike[T]]": ...
2461    @overload
2462    def partition(
2463        self, predicate: Callable[[T, int], bool]
2464    ) -> "Tuple[ListLike[T], ListLike[T]]": ...
2465    @overload
2466    def partition(
2467        self, predicate: Callable[[T, int, Sequence[T]], bool]
2468    ) -> "Tuple[ListLike[T], ListLike[T]]": ...
2469    def partition(self, predicate: Callable[..., bool]) -> "Tuple[ListLike[T], ListLike[T]]":
2470        """
2471        Partitions the elements of the given Sequence into two groups,
2472        the first group containing the elements for which the predicate returns true,
2473        and the second containing the rest.
2474
2475        Example 1:
2476        >>> lst = ['a', 'b', 'c', '2']
2477        >>> it(lst).partition(lambda x: x.isalpha())
2478        (['a', 'b', 'c'], ['2'])
2479
2480        Example 2:
2481        >>> lst = ['a', 'b', 'c', '2']
2482        >>> it(lst).partition(lambda _, i: i % 2 == 0)
2483        (['a', 'c'], ['b', '2'])
2484        """
2485        from .list_like import ListLike
2486
2487        predicate_a = self.__callback_overload_warpper__(predicate)
2488        predicate_b = self.__callback_overload_warpper__(predicate)
2489        part_a = self.filter(predicate_a)
2490        part_b = self.filter(lambda x: not predicate_b(x))
2491        return ListLike(part_a), ListLike(part_b)
2492
2493    def indexed(self) -> Sequence[IndexedValue[T]]:
2494        return self.map(lambda x, i: IndexedValue(x, i))
2495
2496    @overload
2497    def combinations(self, n: Literal[2]) -> Sequence[Tuple[T, T]]: ...
2498    @overload
2499    def combinations(self, n: Literal[3]) -> Sequence[Tuple[T, T, T]]: ...
2500    @overload
2501    def combinations(self, n: Literal[4]) -> Sequence[Tuple[T, T, T, T]]: ...
2502    @overload
2503    def combinations(self, n: Literal[5]) -> Sequence[Tuple[T, T, T, T, T]]: ...
2504    def combinations(self, n: int) -> Sequence[Tuple[T, ...]]:
2505        """
2506        Returns a Sequence of all possible combinations of size [n] from the given Sequence.
2507
2508        Example 1:
2509        >>> lst = ['a', 'b', 'c']
2510        >>> it(lst).combinations(2).to_list()
2511        [('a', 'b'), ('a', 'c'), ('b', 'c')]
2512        """
2513        from .combination import CombinationTransform
2514
2515        return it(CombinationTransform(self, n))
2516
2517    def nth(self, n: int) -> T:
2518        """
2519        Returns the nth element of the given Sequence.
2520
2521        Example 1:
2522        >>> lst = ['a', 'b', 'c']
2523        >>> it(lst).nth(2)
2524        'c'
2525        """
2526        return self.skip(n).first()
2527
2528    def windowed(self, size: int, step: int = 1, partialWindows: bool = False) -> Sequence[List[T]]:
2529        """
2530         Returns a Sequence of all possible sliding windows of size [size] from the given Sequence.
2531
2532        Example 1:
2533        >>> lst = ['a', 'b', 'c', 'd', 'e']
2534        >>> it(lst).windowed(3).to_list()
2535        [['a', 'b', 'c'], ['b', 'c', 'd'], ['c', 'd', 'e']]
2536
2537        Example 2:
2538        >>> lst = ['a', 'b', 'c', 'd', 'e']
2539        >>> it(lst).windowed(3, 2).to_list()
2540        [['a', 'b', 'c'], ['c', 'd', 'e']]
2541
2542        Example 3:
2543        >>> lst = ['a', 'b', 'c', 'd', 'e', 'f']
2544        >>> it(lst).windowed(3, 2, True).to_list()
2545        [['a', 'b', 'c'], ['c', 'd', 'e'], ['e', 'f']]
2546        """
2547        from .windowed import WindowedTransform
2548
2549        return it(WindowedTransform(self, size, step, partialWindows))
2550
2551    def chunked(self, size: int) -> Sequence[List[T]]:
2552        """
2553        Returns a Sequence of all possible chunks of size [size] from the given Sequence.
2554
2555        Example 1:
2556        >>> lst = ['a', 'b', 'c', 'd', 'e']
2557        >>> it(lst).chunked(3).to_list()
2558        [['a', 'b', 'c'], ['d', 'e']]
2559
2560
2561        Example 2:
2562        >>> lst = ['a', 'b', 'c', 'd', 'e', 'f']
2563        >>> it(lst).chunked(3).to_list()
2564        [['a', 'b', 'c'], ['d', 'e', 'f']]
2565        """
2566        return self.windowed(size, size, True)
2567
2568    def repeat(self, n: int) -> Sequence[T]:
2569        """
2570        Returns a Sequence containing this sequence repeated n times.
2571
2572        Example 1:
2573        >>> lst = ['a', 'b']
2574        >>> it(lst).repeat(3).to_list()
2575        ['a', 'b', 'a', 'b', 'a', 'b']
2576        """
2577        from .concat import ConcatTransform
2578
2579        return it(ConcatTransform([self] * n))
2580
2581    def concat(self, *other: Sequence[T]) -> Sequence[T]:
2582        """
2583        Returns a Sequence of all elements of the given Sequence, followed by all elements of the given Sequence.
2584
2585        Example 1:
2586        >>> lst1 = ['a', 'b', 'c']
2587        >>> lst2 = [1, 2, 3]
2588        >>> it(lst1).concat(lst2).to_list()
2589        ['a', 'b', 'c', 1, 2, 3]
2590
2591        Example 2:
2592        >>> lst1 = ['a', 'b', 'c']
2593        >>> lst2 = [1, 2, 3]
2594        >>> lst3 = [4, 5, 6]
2595        >>> it(lst1).concat(lst2, lst3).to_list()
2596        ['a', 'b', 'c', 1, 2, 3, 4, 5, 6]
2597        """
2598        from .concat import ConcatTransform
2599
2600        return it(ConcatTransform([self, *other]))
2601
2602    def intersect(self, *other: Sequence[T]) -> Sequence[T]:
2603        """
2604        Returns a set containing all elements that are contained by both this collection and the specified collection.
2605
2606        The returned set preserves the element iteration order of the original collection.
2607
2608        To get a set containing all elements that are contained at least in one of these collections use union.
2609
2610        Example 1:
2611        >>> lst1 = ['a', 'b', 'c']
2612        >>> lst2 = ['a2', 'b2', 'c']
2613        >>> it(lst1).intersect(lst2).to_list()
2614        ['c']
2615
2616        Example 2:
2617        >>> lst1 = ['a', 'b', 'c']
2618        >>> lst2 = ['a2', 'b', 'c']
2619        >>> lst3 = ['a3', 'b', 'c3']
2620        >>> it(lst1).intersect(lst2, lst3).to_list()
2621        ['b']
2622
2623
2624        Example 1:
2625        >>> lst1 = ['a', 'a', 'c']
2626        >>> lst2 = ['a2', 'b2', 'a']
2627        >>> it(lst1).intersect(lst2).to_list()
2628        ['a']
2629        """
2630        from .intersection import IntersectionTransform
2631
2632        return it(IntersectionTransform([self, *other]))
2633
2634    def union(self, *other: Sequence[T]) -> Sequence[T]:
2635        """
2636        Returns a set containing all distinct elements from both collections.
2637
2638        The returned set preserves the element iteration order of the original collection. Those elements of the other collection that are unique are iterated in the end in the order of the other collection.
2639
2640        To get a set containing all elements that are contained in both collections use intersect.
2641
2642        Example 1:
2643        >>> lst1 = ['a', 'b', 'c']
2644        >>> lst2 = ['a2', 'b2', 'c']
2645        >>> it(lst1).union(lst2).to_list()
2646        ['a', 'b', 'c', 'a2', 'b2']
2647
2648        Example 2:
2649        >>> lst1 = ['a', 'b', 'c']
2650        >>> lst2 = ['a2', 'b', 'c']
2651        >>> lst3 = ['a3', 'b', 'c3']
2652        >>> it(lst1).union(lst2, lst3).to_list()
2653        ['a', 'b', 'c', 'a2', 'a3', 'c3']
2654
2655
2656        Example 1:
2657        >>> lst1 = ['a', 'a', 'c']
2658        >>> lst2 = ['a2', 'b2', 'a']
2659        >>> it(lst1).union(lst2).to_list()
2660        ['a', 'c', 'a2', 'b2']
2661        """
2662        return self.concat(*other).distinct()
2663
2664    def join(self: Sequence[str], separator: str = " ") -> str:
2665        """
2666        Joins the elements of the given Sequence into a string.
2667
2668        Example 1:
2669        >>> lst = ['a', 'b', 'c']
2670        >>> it(lst).join(', ')
2671        'a, b, c'
2672        """
2673        return separator.join(self)
2674
2675    @overload
2676    def progress(self) -> Sequence[T]: ...
2677    @overload
2678    def progress(
2679        self, progress_func: Union[Literal["tqdm"], Literal["tqdm_rich"]]
2680    ) -> Sequence[T]: ...
2681    @overload
2682    def progress(self, progress_func: Callable[[Iterable[T]], Iterable[T]]) -> Sequence[T]: ...
2683    def progress(
2684        self,
2685        progress_func: Union[
2686            Callable[[Iterable[T]], Iterable[T]],
2687            Literal["tqdm"],
2688            Literal["tqdm_rich"],
2689            None,
2690        ] = None,
2691    ) -> Sequence[T]:
2692        """
2693        Returns a Sequence that enable a progress bar for the given Sequence.
2694
2695        Example 1:
2696        >>> from tqdm import tqdm
2697        >>> from time import sleep
2698        >>> it(range(10)).progress(lambda x: tqdm(x, total=len(x))).parallel_map(lambda x: sleep(0.), max_workers=5).to_list() and None
2699        >>> for _ in it(list(range(10))).progress(lambda x: tqdm(x, total=len(x))).to_list(): pass
2700        """
2701        if progress_func is not None and callable(progress_func):
2702            from .progress import ProgressTransform
2703
2704            return it(ProgressTransform(self, progress_func))
2705
2706        def import_tqdm():
2707            if progress_func == "tqdm_rich":
2708                from tqdm.rich import tqdm
2709            else:
2710                from tqdm import tqdm
2711            return tqdm
2712
2713        try:
2714            tqdm = import_tqdm()
2715        except ImportError:
2716            from pip import main as pip
2717
2718            pip(["install", "tqdm"])
2719            tqdm = import_tqdm()
2720
2721        return it(tqdm(self, total=len(self)))
2722
2723    def typing_as(self, typ: Type[U]) -> Sequence[U]:
2724        """
2725        Cast the element as specific Type to gain code completion base on type annotations.
2726        """
2727        el = self.first_not_none_of_or_none()
2728        if el is None or isinstance(el, typ) or not isinstance(el, dict):
2729            return self  # type: ignore
2730
2731        class AttrDict(Dict[str, Any]):
2732            def __init__(self, value: Dict[str, Any]) -> None:
2733                super().__init__(**value)
2734                setattr(self, "__dict__", value)
2735                self.__getattr__ = value.__getitem__
2736                self.__setattr__ = value.__setattr__  # type: ignore
2737
2738        return self.map(AttrDict)  # type: ignore  # use https://github.com/cdgriffith/Box ?
2739
2740    def to_set(self) -> Set[T]:
2741        """
2742        Returns a set containing all elements of this Sequence.
2743
2744        Example 1:
2745        >>> it(['a', 'b', 'c', 'c']).to_set() == {'a', 'b', 'c'}
2746        True
2747        """
2748        return set(self)
2749
2750    @overload
2751    def to_dict(self: Sequence[Tuple[K, V]]) -> Dict[K, V]: ...
2752    @overload
2753    def to_dict(self, transform: Callable[[T], Tuple[K, V]]) -> Dict[K, V]: ...
2754    @overload
2755    def to_dict(self, transform: Callable[[T, int], Tuple[K, V]]) -> Dict[K, V]: ...
2756    @overload
2757    def to_dict(self, transform: Callable[[T, int, Sequence[T]], Tuple[K, V]]) -> Dict[K, V]: ...
2758    def to_dict(self, transform: Optional[Callable[..., Tuple[K, V]]] = None) -> Dict[K, V]:
2759        """
2760        Returns a [Dict] containing key-value Tuple provided by [transform] function
2761        applied to elements of the given Sequence.
2762
2763        Example 1:
2764        >>> lst = ['1', '2', '3']
2765        >>> it(lst).to_dict(lambda x: (int(x), x))
2766        {1: '1', 2: '2', 3: '3'}
2767
2768        Example 2:
2769        >>> lst = [(1, '1'), (2, '2'), (3, '3')]
2770        >>> it(lst).to_dict()
2771        {1: '1', 2: '2', 3: '3'}
2772        """
2773        return self.associate(transform or (lambda x: x))  # type: ignore
2774
2775    def to_list(self) -> List[T]:
2776        """
2777        Returns a list with elements of the given Sequence.
2778
2779        Example 1:
2780        >>> it(['b', 'c', 'a']).to_list()
2781        ['b', 'c', 'a']
2782        """
2783        if self.__transform__.cache is not None:
2784            return self.__transform__.cache.copy()
2785        return [s for s in self]
2786
2787    async def to_list_async(self: Iterable[Awaitable[T]]) -> List[T]:
2788        """
2789        Returns a list with elements of the given Sequence.
2790
2791        Example 1:
2792        >>> it(['b', 'c', 'a']).to_list()
2793        ['b', 'c', 'a']
2794        """
2795        from asyncio import gather
2796
2797        return await gather(*self)  # type: ignore
2798
2799    def let(self, block: Callable[[Sequence[T]], U]) -> U:
2800        """
2801        Calls the specified function [block] with `self` value as its argument and returns its result.
2802
2803        Example 1:
2804        >>> it(['a', 'b', 'c']).let(lambda x: x.map(lambda y: y + '!')).to_list()
2805        ['a!', 'b!', 'c!']
2806        """
2807        return block(self)
2808
2809    def also(self, block: Callable[[Sequence[T]], Any]) -> Sequence[T]:
2810        """
2811        Calls the specified function [block] with `self` value as its argument and returns `self` value.
2812
2813        Example 1:
2814        >>> it(['a', 'b', 'c']).also(lambda x: x.map(lambda y: y + '!')).to_list()
2815        ['a', 'b', 'c']
2816        """
2817        block(self)
2818        return self
2819
2820    @property
2821    def size(self) -> int:
2822        """
2823        Returns the size of the given Sequence.
2824        """
2825        return len(self.data)
2826
2827    def is_empty(self) -> bool:
2828        """
2829        Returns True if the Sequence is empty, False otherwise.
2830
2831        Example 1:
2832        >>> it(['a', 'b', 'c']).is_empty()
2833        False
2834
2835        Example 2:
2836        >>> it([None]).is_empty()
2837        False
2838
2839        Example 3:
2840        >>> it([]).is_empty()
2841        True
2842        """
2843        return id(self.first_or_default(self)) == id(self)
2844
2845    def __iter__(self) -> Iterator[T]:
2846        return self.__do_iter__()
2847
2848    def iter(self) -> Iterator[T]:
2849        return self.__do_iter__()
2850
2851    def __do_iter__(self) -> Iterator[T]:
2852        yield from self.__transform__
2853
2854    def __len__(self):
2855        return len(self.__transform__)
2856
2857    def __repr__(self):
2858        if self.__transform__.cache is None:
2859            return "[...]"
2860        return repr(self.to_list())
2861
2862    def __getitem__(self, key: int):
2863        """
2864        Returns the element at the specified [index] in the Sequence.
2865
2866        Example 1:
2867        >>> lst = [1, 2, 3]
2868        >>> it(lst)[1]
2869        2
2870
2871        Example 2:
2872        >>> lst = [1, 2, 3]
2873        >>> it(lst)[3]
2874        Traceback (most recent call last):
2875        ...
2876        IndexError: Index 3 out of range
2877        """
2878        return self.element_at(key)
2879
2880    @overload
2881    def __callback_overload_warpper__(self, callback: Callable[[T], U]) -> Callable[[T], U]: ...
2882    @overload
2883    def __callback_overload_warpper__(
2884        self, callback: Callable[[T, int], U]
2885    ) -> Callable[[T], U]: ...
2886    @overload
2887    def __callback_overload_warpper__(
2888        self, callback: Callable[[T, int, Sequence[T]], U]
2889    ) -> Callable[[T], U]: ...
2890    def __callback_overload_warpper__(self, callback: Callable[..., U]) -> Callable[[T], U]:
2891        if hasattr(callback, "__code__"):
2892            if callback.__code__.co_argcount == 2:
2893                index = AutoIncrementIndex()
2894                return lambda x: callback(x, index())
2895            if callback.__code__.co_argcount == 3:
2896                index = AutoIncrementIndex()
2897                return lambda x: callback(x, index(), self)
2898        return callback

Given an [iterator] function constructs a [Sequence] that returns values through the [Iterator] provided by that function.

The values are evaluated lazily, and the sequence is potentially infinite.

Sequence(iterable: Union[Iterable[~T], pyiter.transform.Transform[Any, ~T]])
60    def __init__(self, iterable: Union[Iterable[T], Transform[Any, T]]) -> None:
61        super().__init__()
62
63        self.__transform__ = new_transform(iterable)
transforms
data: List[~T]
def dedup(self) -> pyiter.sequence.Sequence[~T]:
77    def dedup(self) -> Sequence[T]:
78        """
79        Removes consecutive repeated elements in the sequence.
80
81        If the sequence is sorted, this removes all duplicates.
82
83        Example 1:
84        >>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
85        >>> it(lst).dedup().to_list()
86        ['a1', 'b2', 'a2', 'a1']
87
88        Example 1:
89        >>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
90        >>> it(lst).sorted().dedup().to_list()
91        ['a1', 'a2', 'b2']
92        """
93        return self.dedup_by(lambda x: x)

Removes consecutive repeated elements in the sequence.

If the sequence is sorted, this removes all duplicates.

Example 1:

>>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
>>> it(lst).dedup().to_list()
['a1', 'b2', 'a2', 'a1']

Example 1:

>>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
>>> it(lst).sorted().dedup().to_list()
['a1', 'a2', 'b2']
def dedup_by(self, key_selector: Callable[..., Any]) -> pyiter.sequence.Sequence[~T]:
101    def dedup_by(self, key_selector: Callable[..., Any]) -> Sequence[T]:
102        """
103        Removes all but the first of consecutive elements in the sequence that resolve to the same key.
104        """
105        return self.dedup_into_group_by(key_selector).map(lambda x: x[0])

Removes all but the first of consecutive elements in the sequence that resolve to the same key.

def dedup_with_count_by( self, key_selector: Callable[..., Any]) -> pyiter.sequence.Sequence[typing.Tuple[~T, int]]:
117    def dedup_with_count_by(self, key_selector: Callable[..., Any]) -> Sequence[Tuple[T, int]]:
118        """
119        Removes all but the first of consecutive elements and its count that resolve to the same key.
120
121        Example 1:
122        >>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
123        >>> it(lst).dedup_with_count_by(lambda x: x).to_list()
124        [('a1', 2), ('b2', 1), ('a2', 1), ('a1', 1)]
125
126        Example 1:
127        >>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
128        >>> it(lst).sorted().dedup_with_count_by(lambda x: x).to_list()
129        [('a1', 3), ('a2', 1), ('b2', 1)]
130        """
131        return self.dedup_into_group_by(key_selector).map(lambda x: (x[0], len(x)))

Removes all but the first of consecutive elements and its count that resolve to the same key.

Example 1:

>>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
>>> it(lst).dedup_with_count_by(lambda x: x).to_list()
[('a1', 2), ('b2', 1), ('a2', 1), ('a1', 1)]

Example 1:

>>> lst = [ 'a1', 'a1', 'b2', 'a2', 'a1']
>>> it(lst).sorted().dedup_with_count_by(lambda x: x).to_list()
[('a1', 3), ('a2', 1), ('b2', 1)]
def dedup_into_group_by( self, key_selector: Callable[..., Any]) -> pyiter.sequence.Sequence[typing.List[~T]]:
141    def dedup_into_group_by(self, key_selector: Callable[..., Any]) -> Sequence[List[T]]:
142        from .dedup import DedupTransform
143
144        return it(DedupTransform(self, key_selector))
def filter(self, predicate: Callable[..., bool]) -> pyiter.sequence.Sequence[~T]:
152    def filter(self, predicate: Callable[..., bool]) -> Sequence[T]:
153        """
154        Returns a Sequence containing only elements matching the given [predicate].
155
156        Example 1:
157        >>> lst = [ 'a1', 'b1', 'b2', 'a2']
158        >>> it(lst).filter(lambda x: x.startswith('a')).to_list()
159        ['a1', 'a2']
160
161        Example 2:
162        >>> lst = [ 'a1', 'b1', 'b2', 'a2']
163        >>> it(lst).filter(lambda x, i: x.startswith('a') or i % 2 == 0 ).to_list()
164        ['a1', 'b2', 'a2']
165        """
166        from .filtering import FilteringTransform
167
168        return it(FilteringTransform(self, self.__callback_overload_warpper__(predicate)))

Returns a Sequence containing only elements matching the given [predicate].

Example 1:

>>> lst = [ 'a1', 'b1', 'b2', 'a2']
>>> it(lst).filter(lambda x: x.startswith('a')).to_list()
['a1', 'a2']

Example 2:

>>> lst = [ 'a1', 'b1', 'b2', 'a2']
>>> it(lst).filter(lambda x, i: x.startswith('a') or i % 2 == 0 ).to_list()
['a1', 'b2', 'a2']
def filter_is_instance(self, typ: Type[~U]) -> pyiter.sequence.Sequence[~U]:
170    def filter_is_instance(self, typ: Type[U]) -> Sequence[U]:
171        """
172        Returns a Sequence containing all elements that are instances of specified type parameter typ.
173
174        Example 1:
175        >>> lst = [ 'a1', 1, 'b2', 3]
176        >>> it(lst).filter_is_instance(int).to_list()
177        [1, 3]
178
179        """
180        return self.filter(lambda x: isinstance(x, typ))  # type: ignore

Returns a Sequence containing all elements that are instances of specified type parameter typ.

Example 1:

>>> lst = [ 'a1', 1, 'b2', 3]
>>> it(lst).filter_is_instance(int).to_list()
[1, 3]
def filter_not(self, predicate: Callable[..., bool]) -> pyiter.sequence.Sequence[~T]:
188    def filter_not(self, predicate: Callable[..., bool]) -> Sequence[T]:
189        """
190        Returns a Sequence containing all elements not matching the given [predicate].
191
192        Example 1:
193        >>> lst = [ 'a1', 'b1', 'b2', 'a2']
194        >>> it(lst).filter_not(lambda x: x.startswith('a')).to_list()
195        ['b1', 'b2']
196
197        Example 2:
198        >>> lst = [ 'a1', 'a2', 'b1', 'b2']
199        >>> it(lst).filter_not(lambda x, i: x.startswith('a') and i % 2 == 0 ).to_list()
200        ['a2', 'b1', 'b2']
201        """
202        predicate = self.__callback_overload_warpper__(predicate)
203        return self.filter(lambda x: not predicate(x))

Returns a Sequence containing all elements not matching the given [predicate].

Example 1:

>>> lst = [ 'a1', 'b1', 'b2', 'a2']
>>> it(lst).filter_not(lambda x: x.startswith('a')).to_list()
['b1', 'b2']

Example 2:

>>> lst = [ 'a1', 'a2', 'b1', 'b2']
>>> it(lst).filter_not(lambda x, i: x.startswith('a') and i % 2 == 0 ).to_list()
['a2', 'b1', 'b2']
def filter_not_none( self: pyiter.sequence.Sequence[typing.Optional[~U]]) -> pyiter.sequence.Sequence[~U]:
209    def filter_not_none(self: Sequence[Optional[U]]) -> Sequence[U]:
210        """
211        Returns a Sequence containing all elements that are not `None`.
212
213        Example 1:
214        >>> lst = [ 'a', None, 'b']
215        >>> it(lst).filter_not_none().to_list()
216        ['a', 'b']
217        """
218        return self.filter(lambda x: x is not None)  # type: ignore

Returns a Sequence containing all elements that are not None.

Example 1:

>>> lst = [ 'a', None, 'b']
>>> it(lst).filter_not_none().to_list()
['a', 'b']
def map(self, transform: Callable[..., ~U]) -> pyiter.sequence.Sequence[~U]:
226    def map(self, transform: Callable[..., U]) -> Sequence[U]:
227        """
228        Returns a Sequence containing the results of applying the given [transform] function
229        to each element in the original Sequence.
230
231        Example 1:
232        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
233        >>> it(lst).map(lambda x: x['age']).to_list()
234        [12, 13]
235
236        Example 2:
237        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
238        >>> it(lst).map(lambda x, i: x['name'] + str(i)).to_list()
239        ['A0', 'B1']
240
241        Example 3:
242        >>> lst = ['hi', 'abc']
243        >>> it(lst).map(len).to_list()
244        [2, 3]
245        """
246        from .mapping import MappingTransform
247
248        return it(MappingTransform(self, self.__callback_overload_warpper__(transform)))

Returns a Sequence containing the results of applying the given [transform] function to each element in the original Sequence.

Example 1:

>>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
>>> it(lst).map(lambda x: x['age']).to_list()
[12, 13]

Example 2:

>>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
>>> it(lst).map(lambda x, i: x['name'] + str(i)).to_list()
['A0', 'B1']

Example 3:

>>> lst = ['hi', 'abc']
>>> it(lst).map(len).to_list()
[2, 3]
async def map_async( self, transform: Callable[..., Awaitable[~U]], return_exceptions: bool = False):
264    async def map_async(
265        self, transform: Callable[..., Awaitable[U]], return_exceptions: bool = False
266    ):
267        """
268        Similar to `.map()` but you can input a async transform then await it.
269        """
270        from asyncio import gather
271
272        if return_exceptions:
273            return it(await gather(*self.map(transform), return_exceptions=True))
274        return it(await gather(*self.map(transform)))

Similar to .map() but you can input a async transform then await it.

def map_not_none( self, transform: Callable[..., Optional[~U]]) -> pyiter.sequence.Sequence[~U]:
284    def map_not_none(self, transform: Callable[..., Optional[U]]) -> Sequence[U]:
285        """
286        Returns a Sequence containing only the non-none results of applying the given [transform] function
287        to each element in the original collection.
288
289        Example 1:
290        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': None}]
291        >>> it(lst).map_not_none(lambda x: x['age']).to_list()
292        [12]
293        """
294        return self.map(transform).filter_not_none()  # type: ignore

Returns a Sequence containing only the non-none results of applying the given [transform] function to each element in the original collection.

Example 1:

>>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': None}]
>>> it(lst).map_not_none(lambda x: x['age']).to_list()
[12]
def parallel_map( self, transform: Callable[..., ~U], max_workers: Optional[int] = None, chunksize: int = 1, executor: 'ParallelMappingTransform.Executor' = 'Thread') -> pyiter.sequence.Sequence[~U]:
320    def parallel_map(
321        self,
322        transform: Callable[..., U],
323        max_workers: Optional[int] = None,
324        chunksize: int = 1,
325        executor: ParallelMappingTransform.Executor = "Thread",
326    ) -> Sequence[U]:
327        """
328        Returns a Sequence containing the results of applying the given [transform] function
329        to each element in the original Sequence.
330
331        Example 1:
332        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
333        >>> it(lst).parallel_map(lambda x: x['age']).to_list()
334        [12, 13]
335
336        Example 2:
337        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
338        >>> it(lst).parallel_map(lambda x: x['age'], max_workers=2).to_list()
339        [12, 13]
340
341        Example 3:
342        >>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
343        >>> it(lst).parallel_map(lambda x, i: x['age'] + i, max_workers=2).to_list()
344        [12, 14]
345        """
346        from .parallel_mapping import ParallelMappingTransform
347
348        return it(
349            ParallelMappingTransform(
350                self,
351                self.__callback_overload_warpper__(transform),
352                max_workers,
353                chunksize,
354                executor,
355            )
356        )

Returns a Sequence containing the results of applying the given [transform] function to each element in the original Sequence.

Example 1:

>>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
>>> it(lst).parallel_map(lambda x: x['age']).to_list()
[12, 13]

Example 2:

>>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
>>> it(lst).parallel_map(lambda x: x['age'], max_workers=2).to_list()
[12, 13]

Example 3:

>>> lst = [{ 'name': 'A', 'age': 12}, { 'name': 'B', 'age': 13}]
>>> it(lst).parallel_map(lambda x, i: x['age'] + i, max_workers=2).to_list()
[12, 14]
def find(self, predicate: Callable[..., bool]) -> Optional[~T]:
364    def find(self, predicate: Callable[..., bool]) -> Optional[T]:
365        """
366        Returns the first element matching the given [predicate], or `None` if no such element was found.
367
368        Example 1:
369        >>> lst = ['a', 'b', 'c']
370        >>> it(lst).find(lambda x: x == 'b')
371        'b'
372        """
373        return self.first_or_none(predicate)

Returns the first element matching the given [predicate], or None if no such element was found.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).find(lambda x: x == 'b')
'b'
def find_last(self, predicate: Callable[[~T], bool]) -> Optional[~T]:
375    def find_last(self, predicate: Callable[[T], bool]) -> Optional[T]:
376        """
377        Returns the last element matching the given [predicate], or `None` if no such element was found.
378
379        Example 1:
380        >>> lst = ['a', 'b', 'c']
381        >>> it(lst).find_last(lambda x: x == 'b')
382        'b'
383        """
384        return self.last_or_none(predicate)

Returns the last element matching the given [predicate], or None if no such element was found.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).find_last(lambda x: x == 'b')
'b'
def first(self, predicate: Optional[Callable[..., bool]] = None) -> ~T:
394    def first(self, predicate: Optional[Callable[..., bool]] = None) -> T:
395        """
396        Returns first element.
397
398        Example 1:
399        >>> lst = ['a', 'b', 'c']
400        >>> it(lst).first()
401        'a'
402
403        Example 2:
404        >>> lst = []
405        >>> it(lst).first()
406        Traceback (most recent call last):
407        ...
408        ValueError: Sequence is empty.
409
410        Example 3:
411        >>> lst = ['a', 'b', 'c']
412        >>> it(lst).first(lambda x: x == 'b')
413        'b'
414
415        Example 4:
416        >>> lst = ['a', 'b', 'c']
417        >>> it(lst).first(lambda x: x == 'd')
418        Traceback (most recent call last):
419        ...
420        ValueError: Sequence is empty.
421
422        Example 5:
423        >>> lst = [None]
424        >>> it(lst).first() is None
425        True
426        """
427        for e in self:
428            if predicate is None or predicate(e):
429                return e
430        raise ValueError("Sequence is empty.")

Returns first element.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).first()
'a'

Example 2:

>>> lst = []
>>> it(lst).first()
Traceback (most recent call last):
...
ValueError: Sequence is empty.

Example 3:

>>> lst = ['a', 'b', 'c']
>>> it(lst).first(lambda x: x == 'b')
'b'

Example 4:

>>> lst = ['a', 'b', 'c']
>>> it(lst).first(lambda x: x == 'd')
Traceback (most recent call last):
...
ValueError: Sequence is empty.

Example 5:

>>> lst = [None]
>>> it(lst).first() is None
True
def first_not_none_of( self: pyiter.sequence.Sequence[typing.Optional[~U]], transform: Optional[Callable[..., Optional[~U]]] = None) -> ~U:
448    def first_not_none_of(
449        self: Sequence[Optional[U]],
450        transform: Optional[Callable[..., Optional[U]]] = None,
451    ) -> U:
452        """
453        Returns the first non-`None` result of applying the given [transform] function to each element in the original collection.
454
455        Example 1:
456        >>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': 12}]
457        >>> it(lst).first_not_none_of(lambda x: x['age'])
458        12
459
460        Example 2:
461        >>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': None}]
462        >>> it(lst).first_not_none_of(lambda x: x['age'])
463        Traceback (most recent call last):
464        ...
465        ValueError: No element of the Sequence was transformed to a non-none value.
466        """
467
468        v = (
469            self.first_not_none_of_or_none()
470            if transform is None
471            else self.first_not_none_of_or_none(transform)
472        )
473        if v is None:
474            raise ValueError("No element of the Sequence was transformed to a non-none value.")
475        return v

Returns the first non-None result of applying the given [transform] function to each element in the original collection.

Example 1:

>>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': 12}]
>>> it(lst).first_not_none_of(lambda x: x['age'])
12

Example 2:

>>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': None}]
>>> it(lst).first_not_none_of(lambda x: x['age'])
Traceback (most recent call last):
...
ValueError: No element of the Sequence was transformed to a non-none value.
def first_not_none_of_or_none(self, transform: Optional[Callable[..., ~T]] = None) -> ~T:
485    def first_not_none_of_or_none(self, transform: Optional[Callable[..., T]] = None) -> T:
486        """
487        Returns the first non-`None` result of applying the given [transform] function to each element in the original collection.
488
489        Example 1:
490        >>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': 12}]
491        >>> it(lst).first_not_none_of_or_none(lambda x: x['age'])
492        12
493
494        Example 2:
495        >>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': None}]
496        >>> it(lst).first_not_none_of_or_none(lambda x: x['age']) is None
497        True
498        """
499        if transform is None:
500            return self.first_or_none()
501        return self.map_not_none(transform).first_or_none()

Returns the first non-None result of applying the given [transform] function to each element in the original collection.

Example 1:

>>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': 12}]
>>> it(lst).first_not_none_of_or_none(lambda x: x['age'])
12

Example 2:

>>> lst = [{ 'name': 'A', 'age': None}, { 'name': 'B', 'age': None}]
>>> it(lst).first_not_none_of_or_none(lambda x: x['age']) is None
True
def first_or_none(self, predicate: Optional[Callable[..., bool]] = None) -> Optional[~T]:
511    def first_or_none(self, predicate: Optional[Callable[..., bool]] = None) -> Optional[T]:
512        """
513        Returns the first element, or `None` if the Sequence is empty.
514
515        Example 1:
516        >>> lst = []
517        >>> it(lst).first_or_none() is None
518        True
519
520        Example 2:
521        >>> lst = ['a', 'b', 'c']
522        >>> it(lst).first_or_none()
523        'a'
524
525        Example 2:
526        >>> lst = ['a', 'b', 'c']
527        >>> it(lst).first_or_none(lambda x: x == 'b')
528        'b'
529        """
530        if predicate is not None:
531            return self.first_or_default(predicate, None)
532        else:
533            return self.first_or_default(None)

Returns the first element, or None if the Sequence is empty.

Example 1:

>>> lst = []
>>> it(lst).first_or_none() is None
True

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).first_or_none()
'a'

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).first_or_none(lambda x: x == 'b')
'b'
def first_or_default( self, predicate: Union[Callable[..., bool], ~U], default: Optional[~U] = None) -> Union[~T, ~U, NoneType]:
545    def first_or_default(  # type: ignore
546        self, predicate: Union[Callable[..., bool], U], default: Optional[U] = None
547    ) -> Union[T, U, None]:
548        """
549        Returns the first element, or the given [default] if the Sequence is empty.
550
551        Example 1:
552        >>> lst = []
553        >>> it(lst).first_or_default('a')
554        'a'
555
556        Example 2:
557        >>> lst = ['b']
558        >>> it(lst).first_or_default('a')
559        'b'
560
561        Example 3:
562        >>> lst = ['a', 'b', 'c']
563        >>> it(lst).first_or_default(lambda x: x == 'b', 'd')
564        'b'
565
566        Example 4:
567        >>> lst = []
568        >>> it(lst).first_or_default(lambda x: x == 'b', 'd')
569        'd'
570        """
571        seq = self
572        if isinstance(predicate, Callable):
573            seq = self.filter(predicate)  # type: ignore
574        else:
575            default = predicate
576        return next(iter(seq), default)

Returns the first element, or the given [default] if the Sequence is empty.

Example 1:

>>> lst = []
>>> it(lst).first_or_default('a')
'a'

Example 2:

>>> lst = ['b']
>>> it(lst).first_or_default('a')
'b'

Example 3:

>>> lst = ['a', 'b', 'c']
>>> it(lst).first_or_default(lambda x: x == 'b', 'd')
'b'

Example 4:

>>> lst = []
>>> it(lst).first_or_default(lambda x: x == 'b', 'd')
'd'
def last(self, predicate: Optional[Callable[..., bool]] = None) -> ~T:
586    def last(self, predicate: Optional[Callable[..., bool]] = None) -> T:
587        """
588        Returns last element.
589
590        Example 1:
591        >>> lst = ['a', 'b', 'c']
592        >>> it(lst).last()
593        'c'
594
595        Example 2:
596        >>> lst = []
597        >>> it(lst).last()
598        Traceback (most recent call last):
599        ...
600        ValueError: Sequence is empty.
601        """
602        v = self.last_or_none(predicate) if predicate is not None else self.last_or_none()
603        if v is None:
604            raise ValueError("Sequence is empty.")
605        return v

Returns last element.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).last()
'c'

Example 2:

>>> lst = []
>>> it(lst).last()
Traceback (most recent call last):
...
ValueError: Sequence is empty.
def last_or_none(self, predicate: Optional[Callable[..., bool]] = None) -> Optional[~T]:
615    def last_or_none(self, predicate: Optional[Callable[..., bool]] = None) -> Optional[T]:
616        """
617        Returns the last element matching the given [predicate], or `None` if no such element was found.
618
619        Exmaple 1:
620        >>> lst = ['a', 'b', 'c']
621        >>> it(lst).last_or_none()
622        'c'
623
624        Exmaple 2:
625        >>> lst = ['a', 'b', 'c']
626        >>> it(lst).last_or_none(lambda x: x != 'c')
627        'b'
628
629        Exmaple 3:
630        >>> lst = []
631        >>> it(lst).last_or_none(lambda x: x != 'c') is None
632        True
633        """
634        last: Optional[T] = None
635        for i in self if predicate is None else self.filter(predicate):
636            last = i
637        return last

Returns the last element matching the given [predicate], or None if no such element was found.

Exmaple 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).last_or_none()
'c'

Exmaple 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).last_or_none(lambda x: x != 'c')
'b'

Exmaple 3:

>>> lst = []
>>> it(lst).last_or_none(lambda x: x != 'c') is None
True
def index_of_or_none(self, element: ~T) -> Optional[int]:
639    def index_of_or_none(self, element: T) -> Optional[int]:
640        """
641        Returns first index of [element], or None if the collection does not contain element.
642
643        Example 1:
644        >>> lst = ['a', 'b', 'c']
645        >>> it(lst).index_of_or_none('b')
646        1
647
648        Example 2:
649        >>> lst = ['a', 'b', 'c']
650        >>> it(lst).index_of_or_none('d')
651        """
652        for i, x in enumerate(self):
653            if x == element:
654                return i
655        return None

Returns first index of [element], or None if the collection does not contain element.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_or_none('b')
1

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_or_none('d')
def index_of(self, element: ~T) -> int:
657    def index_of(self, element: T) -> int:
658        """
659        Returns first index of [element], or -1 if the collection does not contain element.
660
661        Example 1:
662        >>> lst = ['a', 'b', 'c']
663        >>> it(lst).index_of('b')
664        1
665
666        Example 2:
667        >>> lst = ['a', 'b', 'c']
668        >>> it(lst).index_of('d')
669        -1
670        """
671        return none_or(self.index_of_or_none(element), -1)

Returns first index of [element], or -1 if the collection does not contain element.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of('b')
1

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of('d')
-1
def index_of_or(self, element: ~T, default: int) -> int:
673    def index_of_or(self, element: T, default: int) -> int:
674        """
675        Returns first index of [element], or default value if the collection does not contain element.
676
677        Example 1:
678        >>> lst = ['a', 'b', 'c']
679        >>> it(lst).index_of_or('b', 1)
680        1
681
682        Example 2:
683        >>> lst = ['a', 'b', 'c']
684        >>> it(lst).index_of_or('d', 0)
685        0
686        """
687        return none_or(self.index_of_or_none(element), default)

Returns first index of [element], or default value if the collection does not contain element.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_or('b', 1)
1

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_or('d', 0)
0
def index_of_or_else(self, element: ~T, f: Callable[[], int]) -> int:
689    def index_of_or_else(self, element: T, f: Callable[[], int]) -> int:
690        """
691        Returns first index of [element], or computes the value from a callback if the collection does not contain element.
692
693        Example 1:
694        >>> lst = ['a', 'b', 'c']
695        >>> it(lst).index_of_or_else('b', lambda: 2)
696        1
697
698        Example 2:
699        >>> lst = ['a', 'b', 'c']
700        >>> it(lst).index_of_or_else('d', lambda: 0)
701        0
702        """
703        return none_or_else(self.index_of_or_none(element), f)

Returns first index of [element], or computes the value from a callback if the collection does not contain element.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_or_else('b', lambda: 2)
1

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_or_else('d', lambda: 0)
0
def last_index_of_or_none(self, element: ~T) -> Optional[int]:
705    def last_index_of_or_none(self, element: T) -> Optional[int]:
706        """
707         Returns last index of [element], or None if the collection does not contain element.
708
709        Example 1:
710        >>> lst = ['a', 'b', 'c', 'b']
711        >>> it(lst).last_index_of_or_none('b')
712        3
713
714        Example 2:
715        >>> lst = ['a', 'b', 'c']
716        >>> it(lst).last_index_of_or_none('d')
717        """
718        seq = self.reversed()
719        last_idx = len(seq) - 1
720        for i, x in enumerate(seq):
721            if x == element:
722                return last_idx - i
723        return None

Returns last index of [element], or None if the collection does not contain element.

Example 1:

>>> lst = ['a', 'b', 'c', 'b']
>>> it(lst).last_index_of_or_none('b')
3

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).last_index_of_or_none('d')
def last_index_of(self, element: ~T) -> int:
725    def last_index_of(self, element: T) -> int:
726        """
727         Returns last index of [element], or -1 if the collection does not contain element.
728
729        Example 1:
730        >>> lst = ['a', 'b', 'c', 'b']
731        >>> it(lst).last_index_of('b')
732        3
733
734        Example 2:
735        >>> lst = ['a', 'b', 'c']
736        >>> it(lst).last_index_of('d')
737        -1
738        """
739        return none_or(self.last_index_of_or_none(element), -1)

Returns last index of [element], or -1 if the collection does not contain element.

Example 1:

>>> lst = ['a', 'b', 'c', 'b']
>>> it(lst).last_index_of('b')
3

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).last_index_of('d')
-1
def last_index_of_or(self, element: ~T, default: int) -> int:
741    def last_index_of_or(self, element: T, default: int) -> int:
742        """
743         Returns last index of [element], or default value if the collection does not contain element.
744
745        Example 1:
746        >>> lst = ['a', 'b', 'c', 'b']
747        >>> it(lst).last_index_of_or('b', 0)
748        3
749
750        Example 2:
751        >>> lst = ['a', 'b', 'c']
752        >>> it(lst).last_index_of_or('d', len(lst))
753        3
754        """
755        return none_or(self.last_index_of_or_none(element), default)

Returns last index of [element], or default value if the collection does not contain element.

Example 1:

>>> lst = ['a', 'b', 'c', 'b']
>>> it(lst).last_index_of_or('b', 0)
3

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).last_index_of_or('d', len(lst))
3
def last_index_of_or_else(self, element: ~T, f: Callable[[], int]) -> int:
757    def last_index_of_or_else(self, element: T, f: Callable[[], int]) -> int:
758        """
759         Returns last index of [element], or computes the value from a callback if the collection does not contain element.
760
761        Example 1:
762        >>> lst = ['a', 'b', 'c', 'b']
763        >>> it(lst).last_index_of_or_else('b', lambda: 0)
764        3
765
766        Example 2:
767        >>> lst = ['a', 'b', 'c']
768        >>> it(lst).last_index_of_or_else('d', lambda: len(lst))
769        3
770        """
771        return none_or_else(self.last_index_of_or_none(element), f)

Returns last index of [element], or computes the value from a callback if the collection does not contain element.

Example 1:

>>> lst = ['a', 'b', 'c', 'b']
>>> it(lst).last_index_of_or_else('b', lambda: 0)
3

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).last_index_of_or_else('d', lambda: len(lst))
3
def index_of_first_or_none(self, predicate: Callable[..., bool]) -> Optional[int]:
781    def index_of_first_or_none(self, predicate: Callable[..., bool]) -> Optional[int]:
782        """
783        Returns first index of element matching the given [predicate], or None if no such element was found.
784
785        Example 1:
786        >>> lst = ['a', 'b', 'c']
787        >>> it(lst).index_of_first_or_none(lambda x: x == 'b')
788        1
789
790        Example 2:
791        >>> lst = ['a', 'b', 'c']
792        >>> it(lst).index_of_first_or_none(lambda x: x == 'd')
793        """
794        predicate = self.__callback_overload_warpper__(predicate)
795        for i, x in enumerate(self):
796            if predicate(x):
797                return i
798        return None

Returns first index of element matching the given [predicate], or None if no such element was found.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_first_or_none(lambda x: x == 'b')
1

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_first_or_none(lambda x: x == 'd')
def index_of_first(self, predicate: Callable[..., bool]) -> int:
806    def index_of_first(self, predicate: Callable[..., bool]) -> int:
807        """
808        Returns first index of element matching the given [predicate], or -1 if no such element was found.
809
810        Example 1:
811        >>> lst = ['a', 'b', 'c']
812        >>> it(lst).index_of_first(lambda x: x == 'b')
813        1
814
815        Example 2:
816        >>> lst = ['a', 'b', 'c']
817        >>> it(lst).index_of_first(lambda x: x == 'd')
818        -1
819
820        Example 3:
821        >>> lst = ['a', 'b', 'c']
822        >>> it(lst).index_of_first(lambda x: x == 'a')
823        0
824        """
825        return none_or(self.index_of_first_or_none(predicate), -1)

Returns first index of element matching the given [predicate], or -1 if no such element was found.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_first(lambda x: x == 'b')
1

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_first(lambda x: x == 'd')
-1

Example 3:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_first(lambda x: x == 'a')
0
def index_of_first_or(self, predicate: Callable[..., bool], default: int) -> int:
835    def index_of_first_or(self, predicate: Callable[..., bool], default: int) -> int:
836        """
837        Returns first index of element matching the given [predicate], or default value if no such element was found.
838
839        Example 1:
840        >>> lst = ['a', 'b', 'c']
841        >>> it(lst).index_of_first_or(lambda x: x == 'b', 0)
842        1
843
844        Example 2:
845        >>> lst = ['a', 'b', 'c']
846        >>> it(lst).index_of_first_or(lambda x: x == 'd', 0)
847        0
848
849        Example 3:
850        >>> lst = ['a', 'b', 'c']
851        >>> it(lst).index_of_first_or(lambda x: x == 'a', 0)
852        0
853        """
854        return none_or(self.index_of_first_or_none(predicate), default)

Returns first index of element matching the given [predicate], or default value if no such element was found.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_first_or(lambda x: x == 'b', 0)
1

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_first_or(lambda x: x == 'd', 0)
0

Example 3:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_first_or(lambda x: x == 'a', 0)
0
def index_of_first_or_else(self, predicate: Callable[..., bool], f: Callable[[], int]) -> int:
868    def index_of_first_or_else(self, predicate: Callable[..., bool], f: Callable[[], int]) -> int:
869        """
870        Returns first index of element matching the given [predicate], or computes the value from a callback if no such element was found.
871
872        Example 1:
873        >>> lst = ['a', 'b', 'c']
874        >>> it(lst).index_of_first_or_else(lambda x: x == 'b', lambda: len(lst))
875        1
876
877        Example 2:
878        >>> lst = ['a', 'b', 'c']
879        >>> it(lst).index_of_first_or_else(lambda x: x == 'd', lambda: len(lst))
880        3
881
882        Example 3:
883        >>> lst = ['a', 'b', 'c']
884        >>> it(lst).index_of_first_or_else(lambda x: x == 'a', lambda: len(lst))
885        0
886        """
887        return none_or_else(self.index_of_first_or_none(predicate), f)

Returns first index of element matching the given [predicate], or computes the value from a callback if no such element was found.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_first_or_else(lambda x: x == 'b', lambda: len(lst))
1

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_first_or_else(lambda x: x == 'd', lambda: len(lst))
3

Example 3:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_first_or_else(lambda x: x == 'a', lambda: len(lst))
0
def index_of_last_or_none(self, predicate: Callable[..., bool]) -> Optional[int]:
897    def index_of_last_or_none(self, predicate: Callable[..., bool]) -> Optional[int]:
898        """
899        Returns last index of element matching the given [predicate], or -1 if no such element was found.
900
901        Example 1:
902        >>> lst = ['a', 'b', 'c', 'b']
903        >>> it(lst).index_of_last_or_none(lambda x: x == 'b')
904        3
905
906        Example 2:
907        >>> lst = ['a', 'b', 'c']
908        >>> it(lst).index_of_last_or_none(lambda x: x == 'd')
909        """
910        seq = self.reversed()
911        last_idx = len(seq) - 1
912        predicate = self.__callback_overload_warpper__(predicate)
913        for i, x in enumerate(seq):
914            if predicate(x):
915                return last_idx - i
916        return None

Returns last index of element matching the given [predicate], or -1 if no such element was found.

Example 1:

>>> lst = ['a', 'b', 'c', 'b']
>>> it(lst).index_of_last_or_none(lambda x: x == 'b')
3

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_last_or_none(lambda x: x == 'd')
def index_of_last(self, predicate: Callable[..., bool]) -> int:
924    def index_of_last(self, predicate: Callable[..., bool]) -> int:
925        """
926        Returns last index of element matching the given [predicate], or -1 if no such element was found.
927
928        Example 1:
929        >>> lst = ['a', 'b', 'c', 'b']
930        >>> it(lst).index_of_last(lambda x: x == 'b')
931        3
932
933        Example 2:
934        >>> lst = ['a', 'b', 'c']
935        >>> it(lst).index_of_last(lambda x: x == 'd')
936        -1
937
938        Example 3:
939        >>> lst = ['a', 'b', 'c']
940        >>> it(lst).index_of_last(lambda x: x == 'a')
941        0
942        """
943        return none_or(self.index_of_last_or_none(predicate), -1)

Returns last index of element matching the given [predicate], or -1 if no such element was found.

Example 1:

>>> lst = ['a', 'b', 'c', 'b']
>>> it(lst).index_of_last(lambda x: x == 'b')
3

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_last(lambda x: x == 'd')
-1

Example 3:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_last(lambda x: x == 'a')
0
def index_of_last_or(self, predicate: Callable[..., bool], default: int) -> int:
953    def index_of_last_or(self, predicate: Callable[..., bool], default: int) -> int:
954        """
955        Returns last index of element matching the given [predicate], or default value if no such element was found.
956
957        Example 1:
958        >>> lst = ['a', 'b', 'c', 'b']
959        >>> it(lst).index_of_last_or(lambda x: x == 'b', 0)
960        3
961
962        Example 2:
963        >>> lst = ['a', 'b', 'c']
964        >>> it(lst).index_of_last_or(lambda x: x == 'd', -99)
965        -99
966
967        Example 3:
968        >>> lst = ['a', 'b', 'c']
969        >>> it(lst).index_of_last_or(lambda x: x == 'a', 0)
970        0
971        """
972        return none_or(self.index_of_last_or_none(predicate), default)

Returns last index of element matching the given [predicate], or default value if no such element was found.

Example 1:

>>> lst = ['a', 'b', 'c', 'b']
>>> it(lst).index_of_last_or(lambda x: x == 'b', 0)
3

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_last_or(lambda x: x == 'd', -99)
-99

Example 3:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_last_or(lambda x: x == 'a', 0)
0
def index_of_last_o_else(self, predicate: Callable[..., bool], f: Callable[[], int]) -> int:
 984    def index_of_last_o_else(self, predicate: Callable[..., bool], f: Callable[[], int]) -> int:
 985        """
 986        Returns last index of element matching the given [predicate], or default value if no such element was found.
 987
 988        Example 1:
 989        >>> lst = ['a', 'b', 'c', 'b']
 990        >>> it(lst).index_of_last_o_else(lambda x: x == 'b', lambda: -len(lst))
 991        3
 992
 993        Example 2:
 994        >>> lst = ['a', 'b', 'c']
 995        >>> it(lst).index_of_last_o_else(lambda x: x == 'd', lambda: -len(lst))
 996        -3
 997
 998        Example 3:
 999        >>> lst = ['a', 'b', 'c']
1000        >>> it(lst).index_of_last_o_else(lambda x: x == 'a', lambda: -len(lst))
1001        0
1002        """
1003        return none_or_else(self.index_of_last_or_none(predicate), f)

Returns last index of element matching the given [predicate], or default value if no such element was found.

Example 1:

>>> lst = ['a', 'b', 'c', 'b']
>>> it(lst).index_of_last_o_else(lambda x: x == 'b', lambda: -len(lst))
3

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_last_o_else(lambda x: x == 'd', lambda: -len(lst))
-3

Example 3:

>>> lst = ['a', 'b', 'c']
>>> it(lst).index_of_last_o_else(lambda x: x == 'a', lambda: -len(lst))
0
def single(self, predicate: Optional[Callable[..., bool]] = None) -> ~T:
1013    def single(self, predicate: Optional[Callable[..., bool]] = None) -> T:
1014        """
1015        Returns the single element matching the given [predicate], or throws exception if there is no
1016        or more than one matching element.
1017
1018        Exmaple 1:
1019        >>> lst = ['a']
1020        >>> it(lst).single()
1021        'a'
1022
1023        Exmaple 2:
1024        >>> lst = []
1025        >>> it(lst).single() is None
1026        Traceback (most recent call last):
1027        ...
1028        ValueError: Sequence contains no element matching the predicate.
1029
1030        Exmaple 2:
1031        >>> lst = ['a', 'b']
1032        >>> it(lst).single() is None
1033        Traceback (most recent call last):
1034        ...
1035        ValueError: Sequence contains more than one matching element.
1036        """
1037        single: Optional[T] = None
1038        found = False
1039        for i in self if predicate is None else self.filter(predicate):
1040            if found:
1041                raise ValueError("Sequence contains more than one matching element.")
1042            single = i
1043            found = True
1044        if single is None:
1045            raise ValueError("Sequence contains no element matching the predicate.")
1046        return single

Returns the single element matching the given [predicate], or throws exception if there is no or more than one matching element.

Exmaple 1:

>>> lst = ['a']
>>> it(lst).single()
'a'

Exmaple 2:

>>> lst = []
>>> it(lst).single() is None
Traceback (most recent call last):
...
ValueError: Sequence contains no element matching the predicate.

Exmaple 2:

>>> lst = ['a', 'b']
>>> it(lst).single() is None
Traceback (most recent call last):
...
ValueError: Sequence contains more than one matching element.
def single_or_none(self, predicate: Optional[Callable[..., bool]] = None) -> Optional[~T]:
1056    def single_or_none(self, predicate: Optional[Callable[..., bool]] = None) -> Optional[T]:
1057        """
1058        Returns the single element matching the given [predicate], or `None` if element was not found
1059        or more than one element was found.
1060
1061        Exmaple 1:
1062        >>> lst = ['a']
1063        >>> it(lst).single_or_none()
1064        'a'
1065
1066        Exmaple 2:
1067        >>> lst = []
1068        >>> it(lst).single_or_none()
1069
1070        Exmaple 2:
1071        >>> lst = ['a', 'b']
1072        >>> it(lst).single_or_none()
1073
1074        """
1075        single: Optional[T] = None
1076        found = False
1077        for i in self if predicate is None else self.filter(predicate):
1078            if found:
1079                return None
1080            single = i
1081            found = True
1082        if not found:
1083            return None
1084        return single

Returns the single element matching the given [predicate], or None if element was not found or more than one element was found.

Exmaple 1:

>>> lst = ['a']
>>> it(lst).single_or_none()
'a'

Exmaple 2:

>>> lst = []
>>> it(lst).single_or_none()

Exmaple 2:

>>> lst = ['a', 'b']
>>> it(lst).single_or_none()
def drop(self, n: int) -> pyiter.sequence.Sequence[~T]:
1087    def drop(self, n: int) -> Sequence[T]:
1088        """
1089        Returns a Sequence containing all elements except first [n] elements.
1090
1091        Example 1:
1092        >>> lst = ['a', 'b', 'c']
1093        >>> it(lst).drop(0).to_list()
1094        ['a', 'b', 'c']
1095
1096        Example 2:
1097        >>> lst = ['a', 'b', 'c']
1098        >>> it(lst).drop(1).to_list()
1099        ['b', 'c']
1100
1101        Example 2:
1102        >>> lst = ['a', 'b', 'c']
1103        >>> it(lst).drop(4).to_list()
1104        []
1105        """
1106        if n < 0:
1107            raise ValueError(f"Requested element count {n} is less than zero.")
1108        if n == 0:
1109            return self
1110
1111        from .drop import DropTransform
1112
1113        return it(DropTransform(self, n))

Returns a Sequence containing all elements except first [n] elements.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).drop(0).to_list()
['a', 'b', 'c']

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).drop(1).to_list()
['b', 'c']

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).drop(4).to_list()
[]
def drop_while(self, predicate: Callable[..., bool]) -> pyiter.sequence.Sequence[~T]:
1122    def drop_while(self, predicate: Callable[..., bool]) -> Sequence[T]:
1123        """
1124        Returns a Sequence containing all elements except first elements that satisfy the given [predicate].
1125
1126        Example 1:
1127        >>> lst = [1, 2, 3, 4, 1]
1128        >>> it(lst).drop_while(lambda x: x < 3 ).to_list()
1129        [3, 4, 1]
1130        """
1131        from .drop_while import DropWhileTransform
1132
1133        return it(DropWhileTransform(self, self.__callback_overload_warpper__(predicate)))

Returns a Sequence containing all elements except first elements that satisfy the given [predicate].

Example 1:

>>> lst = [1, 2, 3, 4, 1]
>>> it(lst).drop_while(lambda x: x < 3 ).to_list()
[3, 4, 1]
def skip(self, n: int) -> pyiter.sequence.Sequence[~T]:
1135    def skip(self, n: int) -> Sequence[T]:
1136        """
1137        Returns a Sequence containing all elements except first [n] elements.
1138
1139        Example 1:
1140        >>> lst = ['a', 'b', 'c']
1141        >>> it(lst).skip(0).to_list()
1142        ['a', 'b', 'c']
1143
1144         Example 2:
1145        >>> lst = ['a', 'b', 'c']
1146        >>> it(lst).skip(1).to_list()
1147        ['b', 'c']
1148
1149        Example 2:
1150        >>> lst = ['a', 'b', 'c']
1151        >>> it(lst).skip(4).to_list()
1152        []
1153        """
1154        return self.drop(n)

Returns a Sequence containing all elements except first [n] elements.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).skip(0).to_list()
['a', 'b', 'c']

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).skip(1).to_list()
['b', 'c']

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).skip(4).to_list()
[]
def skip_while(self, predicate: Callable[..., bool]) -> pyiter.sequence.Sequence[~T]:
1162    def skip_while(self, predicate: Callable[..., bool]) -> Sequence[T]:
1163        """
1164        Returns a Sequence containing all elements except first elements that satisfy the given [predicate].
1165
1166        Example 1:
1167        >>> lst = [1, 2, 3, 4, 1]
1168        >>> it(lst).skip_while(lambda x: x < 3 ).to_list()
1169        [3, 4, 1]
1170        """
1171        return self.drop_while(predicate)

Returns a Sequence containing all elements except first elements that satisfy the given [predicate].

Example 1:

>>> lst = [1, 2, 3, 4, 1]
>>> it(lst).skip_while(lambda x: x < 3 ).to_list()
[3, 4, 1]
def take(self, n: int) -> pyiter.sequence.Sequence[~T]:
1173    def take(self, n: int) -> Sequence[T]:
1174        """
1175        Returns an Sequence containing first [n] elements.
1176
1177        Example 1:
1178        >>> a = ['a', 'b', 'c']
1179        >>> it(a).take(0).to_list()
1180        []
1181
1182        Example 2:
1183        >>> a = ['a', 'b', 'c']
1184        >>> it(a).take(2).to_list()
1185        ['a', 'b']
1186        """
1187        if n < 0:
1188            raise ValueError(f"Requested element count {n} is less than zero.")
1189        if n == 0:
1190            return Sequence([])
1191        from .take import TakeTransform
1192
1193        return it(TakeTransform(self, n))

Returns an Sequence containing first [n] elements.

Example 1:

>>> a = ['a', 'b', 'c']
>>> it(a).take(0).to_list()
[]

Example 2:

>>> a = ['a', 'b', 'c']
>>> it(a).take(2).to_list()
['a', 'b']
def take_while(self, predicate: Callable[..., bool]) -> pyiter.sequence.Sequence[~T]:
1202    def take_while(self, predicate: Callable[..., bool]) -> Sequence[T]:
1203        """
1204        Returns an Sequence containing first elements satisfying the given [predicate].
1205
1206        Example 1:
1207        >>> lst = ['a', 'b', 'c', 'd']
1208        >>> it(lst).take_while(lambda x: x in ['a', 'b']).to_list()
1209        ['a', 'b']
1210        """
1211        from .take_while import TakeWhileTransform
1212
1213        return it(TakeWhileTransform(self, self.__callback_overload_warpper__(predicate)))

Returns an Sequence containing first elements satisfying the given [predicate].

Example 1:

>>> lst = ['a', 'b', 'c', 'd']
>>> it(lst).take_while(lambda x: x in ['a', 'b']).to_list()
['a', 'b']
def take_last(self, n: int) -> pyiter.sequence.Sequence[~T]:
1215    def take_last(self, n: int) -> Sequence[T]:
1216        """
1217        Returns an Sequence containing last [n] elements.
1218
1219        Example 1:
1220        >>> a = ['a', 'b', 'c']
1221        >>> it(a).take_last(0).to_list()
1222        []
1223
1224        Example 2:
1225        >>> a = ['a', 'b', 'c']
1226        >>> it(a).take_last(2).to_list()
1227        ['b', 'c']
1228        """
1229        if n < 0:
1230            raise ValueError(f"Requested element count {n} is less than zero.")
1231        if n == 0:
1232            return Sequence([])
1233
1234        return self.drop(len(self) - n)

Returns an Sequence containing last [n] elements.

Example 1:

>>> a = ['a', 'b', 'c']
>>> it(a).take_last(0).to_list()
[]

Example 2:

>>> a = ['a', 'b', 'c']
>>> it(a).take_last(2).to_list()
['b', 'c']
def sorted(self) -> pyiter.sequence.Sequence[~T]:
1237    def sorted(self) -> Sequence[T]:
1238        """
1239        Returns an Sequence that yields elements of this Sequence sorted according to their natural sort order.
1240
1241        Example 1:
1242        >>> lst = ['b', 'a', 'e', 'c']
1243        >>> it(lst).sorted().to_list()
1244        ['a', 'b', 'c', 'e']
1245
1246         Example 2:
1247        >>> lst = [2, 1, 4, 3]
1248        >>> it(lst).sorted().to_list()
1249        [1, 2, 3, 4]
1250        """
1251        lst = list(self)
1252        lst.sort()  # type: ignore
1253        return it(lst)

Returns an Sequence that yields elements of this Sequence sorted according to their natural sort order.

Example 1:

>>> lst = ['b', 'a', 'e', 'c']
>>> it(lst).sorted().to_list()
['a', 'b', 'c', 'e']

Example 2:

>>> lst = [2, 1, 4, 3]
>>> it(lst).sorted().to_list()
[1, 2, 3, 4]
def sorted_by( self, key_selector: 'Callable[..., SupportsRichComparisonT]') -> pyiter.sequence.Sequence[~T]:
1266    def sorted_by(self, key_selector: Callable[..., SupportsRichComparisonT]) -> Sequence[T]:
1267        """
1268        Returns a sequence that yields elements of this sequence sorted according to natural sort
1269        order of the value returned by specified [key_selector] function.
1270
1271        Example 1:
1272        >>> lst = [ {'name': 'A', 'age': 12 }, {'name': 'C', 'age': 10 }, {'name': 'B', 'age': 11 } ]
1273        >>> it(lst).sorted_by(lambda x: x['name']).to_list()
1274        [{'name': 'A', 'age': 12}, {'name': 'B', 'age': 11}, {'name': 'C', 'age': 10}]
1275        >>> it(lst).sorted_by(lambda x: x['age']).to_list()
1276        [{'name': 'C', 'age': 10}, {'name': 'B', 'age': 11}, {'name': 'A', 'age': 12}]
1277        """
1278        lst = list(self)
1279        lst.sort(key=self.__callback_overload_warpper__(key_selector))
1280        return it(lst)

Returns a sequence that yields elements of this sequence sorted according to natural sort order of the value returned by specified [key_selector] function.

Example 1:

>>> lst = [ {'name': 'A', 'age': 12 }, {'name': 'C', 'age': 10 }, {'name': 'B', 'age': 11 } ]
>>> it(lst).sorted_by(lambda x: x['name']).to_list()
[{'name': 'A', 'age': 12}, {'name': 'B', 'age': 11}, {'name': 'C', 'age': 10}]
>>> it(lst).sorted_by(lambda x: x['age']).to_list()
[{'name': 'C', 'age': 10}, {'name': 'B', 'age': 11}, {'name': 'A', 'age': 12}]
def sorted_descending(self) -> pyiter.sequence.Sequence[~T]:
1282    def sorted_descending(self) -> Sequence[T]:
1283        """
1284        Returns a Sequence of all elements sorted descending according to their natural sort order.
1285
1286        Example 1:
1287        >>> lst = ['b', 'c', 'a']
1288        >>> it(lst).sorted_descending().to_list()
1289        ['c', 'b', 'a']
1290        """
1291        return self.sorted().reversed()

Returns a Sequence of all elements sorted descending according to their natural sort order.

Example 1:

>>> lst = ['b', 'c', 'a']
>>> it(lst).sorted_descending().to_list()
['c', 'b', 'a']
def sorted_by_descending( self, key_selector: 'Callable[..., SupportsRichComparisonT]') -> pyiter.sequence.Sequence[~T]:
1305    def sorted_by_descending(
1306        self, key_selector: Callable[..., SupportsRichComparisonT]
1307    ) -> Sequence[T]:
1308        """
1309        Returns a sequence that yields elements of this sequence sorted descending according
1310        to natural sort order of the value returned by specified [key_selector] function.
1311
1312        Example 1:
1313        >>> lst = [ {'name': 'A', 'age': 12 }, {'name': 'C', 'age': 10 }, {'name': 'B', 'age': 11 } ]
1314        >>> it(lst).sorted_by_descending(lambda x: x['name']).to_list()
1315        [{'name': 'C', 'age': 10}, {'name': 'B', 'age': 11}, {'name': 'A', 'age': 12}]
1316        >>> it(lst).sorted_by_descending(lambda x: x['age']).to_list()
1317        [{'name': 'A', 'age': 12}, {'name': 'B', 'age': 11}, {'name': 'C', 'age': 10}]
1318        """
1319        return self.sorted_by(key_selector).reversed()

Returns a sequence that yields elements of this sequence sorted descending according to natural sort order of the value returned by specified [key_selector] function.

Example 1:

>>> lst = [ {'name': 'A', 'age': 12 }, {'name': 'C', 'age': 10 }, {'name': 'B', 'age': 11 } ]
>>> it(lst).sorted_by_descending(lambda x: x['name']).to_list()
[{'name': 'C', 'age': 10}, {'name': 'B', 'age': 11}, {'name': 'A', 'age': 12}]
>>> it(lst).sorted_by_descending(lambda x: x['age']).to_list()
[{'name': 'A', 'age': 12}, {'name': 'B', 'age': 11}, {'name': 'C', 'age': 10}]
def sorted_with( self, comparator: Callable[[~T, ~T], int]) -> pyiter.sequence.Sequence[~T]:
1322    def sorted_with(self, comparator: Callable[[T, T], int]) -> Sequence[T]:
1323        """
1324        Returns a sequence that yields elements of this sequence sorted according to the specified [comparator].
1325
1326        Example 1:
1327        >>> lst = ['aa', 'bbb', 'c']
1328        >>> it(lst).sorted_with(lambda a, b: len(a)-len(b)).to_list()
1329        ['c', 'aa', 'bbb']
1330        """
1331        from functools import cmp_to_key
1332
1333        lst = list(self)
1334        lst.sort(key=cmp_to_key(comparator))
1335        return it(lst)

Returns a sequence that yields elements of this sequence sorted according to the specified [comparator].

Example 1:

>>> lst = ['aa', 'bbb', 'c']
>>> it(lst).sorted_with(lambda a, b: len(a)-len(b)).to_list()
['c', 'aa', 'bbb']
def associate(self, transform: Callable[..., Tuple[~K, ~O]]) -> Dict[~K, ~O]:
1343    def associate(self, transform: Callable[..., Tuple[K, V]]) -> Dict[K, V]:
1344        """
1345        Returns a [Dict] containing key-value Tuple provided by [transform] function
1346        applied to elements of the given Sequence.
1347
1348        Example 1:
1349        >>> lst = ['1', '2', '3']
1350        >>> it(lst).associate(lambda x: (int(x), x))
1351        {1: '1', 2: '2', 3: '3'}
1352        """
1353        transform = self.__callback_overload_warpper__(transform)
1354        dic: Dict[K, V] = dict()
1355        for i in self:
1356            k, v = transform(i)
1357            dic[k] = v
1358        return dic

Returns a [Dict] containing key-value Tuple provided by [transform] function applied to elements of the given Sequence.

Example 1:

>>> lst = ['1', '2', '3']
>>> it(lst).associate(lambda x: (int(x), x))
{1: '1', 2: '2', 3: '3'}
def associate_by( self, key_selector: Callable[..., ~K], value_transform: Optional[Callable[[~T], ~O]] = None) -> Union[Dict[~K, ~T], Dict[~K, ~O]]:
1370    def associate_by(
1371        self,
1372        key_selector: Callable[..., K],
1373        value_transform: Optional[Callable[[T], V]] = None,
1374    ) -> Union[Dict[K, T], Dict[K, V]]:
1375        """
1376        Returns a [Dict] containing key-value Tuple provided by [transform] function
1377        applied to elements of the given Sequence.
1378
1379        Example 1:
1380        >>> lst = ['1', '2', '3']
1381        >>> it(lst).associate_by(lambda x: int(x))
1382        {1: '1', 2: '2', 3: '3'}
1383
1384        Example 2:
1385        >>> lst = ['1', '2', '3']
1386        >>> it(lst).associate_by(lambda x: int(x), lambda x: x+x)
1387        {1: '11', 2: '22', 3: '33'}
1388
1389        """
1390        key_selector = self.__callback_overload_warpper__(key_selector)
1391
1392        dic: Dict[K, Any] = dict()
1393        for i in self:
1394            k = key_selector(i)
1395            dic[k] = i if value_transform is None else value_transform(i)
1396        return dic

Returns a [Dict] containing key-value Tuple provided by [transform] function applied to elements of the given Sequence.

Example 1:

>>> lst = ['1', '2', '3']
>>> it(lst).associate_by(lambda x: int(x))
{1: '1', 2: '2', 3: '3'}

Example 2:

>>> lst = ['1', '2', '3']
>>> it(lst).associate_by(lambda x: int(x), lambda x: x+x)
{1: '11', 2: '22', 3: '33'}
def associate_by_to( self, destination: Dict[~K, Any], key_selector: Callable[[~T], ~K], value_transform: Optional[Callable[[~T], Any]] = None) -> Dict[~K, Any]:
1409    def associate_by_to(
1410        self,
1411        destination: Dict[K, Any],
1412        key_selector: Callable[[T], K],
1413        value_transform: Optional[Callable[[T], Any]] = None,
1414    ) -> Dict[K, Any]:
1415        """
1416        Returns a [Dict] containing key-value Tuple provided by [transform] function
1417        applied to elements of the given Sequence.
1418
1419        Example 1:
1420        >>> lst = ['1', '2', '3']
1421        >>> it(lst).associate_by_to({}, lambda x: int(x))
1422        {1: '1', 2: '2', 3: '3'}
1423
1424        Example 2:
1425        >>> lst = ['1', '2', '3']
1426        >>> it(lst).associate_by_to({}, lambda x: int(x), lambda x: x+'!' )
1427        {1: '1!', 2: '2!', 3: '3!'}
1428
1429        """
1430        for i in self:
1431            k = key_selector(i)
1432            destination[k] = i if value_transform is None else value_transform(i)
1433        return destination

Returns a [Dict] containing key-value Tuple provided by [transform] function applied to elements of the given Sequence.

Example 1:

>>> lst = ['1', '2', '3']
>>> it(lst).associate_by_to({}, lambda x: int(x))
{1: '1', 2: '2', 3: '3'}

Example 2:

>>> lst = ['1', '2', '3']
>>> it(lst).associate_by_to({}, lambda x: int(x), lambda x: x+'!' )
{1: '1!', 2: '2!', 3: '3!'}
def all(self, predicate: Callable[..., bool]) -> bool:
1441    def all(self, predicate: Callable[..., bool]) -> bool:
1442        """
1443        Returns True if all elements of the Sequence satisfy the specified [predicate] function.
1444
1445        Example 1:
1446        >>> lst = [1, 2, 3]
1447        >>> it(lst).all(lambda x: x > 0)
1448        True
1449        >>> it(lst).all(lambda x: x > 1)
1450        False
1451        """
1452        predicate = self.__callback_overload_warpper__(predicate)
1453        for i in self:
1454            if not predicate(i):
1455                return False
1456        return True

Returns True if all elements of the Sequence satisfy the specified [predicate] function.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).all(lambda x: x > 0)
True
>>> it(lst).all(lambda x: x > 1)
False
def any(self, predicate: Callable[..., bool]) -> bool:
1464    def any(self, predicate: Callable[..., bool]) -> bool:
1465        """
1466        Returns True if any elements of the Sequence satisfy the specified [predicate] function.
1467
1468        Example 1:
1469        >>> lst = [1, 2, 3]
1470        >>> it(lst).any(lambda x: x > 0)
1471        True
1472        >>> it(lst).any(lambda x: x > 3)
1473        False
1474        """
1475        predicate = self.__callback_overload_warpper__(predicate)
1476        for i in self:
1477            if predicate(i):
1478                return True
1479        return False

Returns True if any elements of the Sequence satisfy the specified [predicate] function.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).any(lambda x: x > 0)
True
>>> it(lst).any(lambda x: x > 3)
False
def count(self, predicate: Optional[Callable[..., bool]] = None) -> int:
1489    def count(self, predicate: Optional[Callable[..., bool]] = None) -> int:
1490        """
1491        Returns the number of elements in the Sequence that satisfy the specified [predicate] function.
1492
1493        Example 1:
1494        >>> lst = [1, 2, 3]
1495        >>> it(lst).count()
1496        3
1497        >>> it(lst).count(lambda x: x > 0)
1498        3
1499        >>> it(lst).count(lambda x: x > 2)
1500        1
1501        """
1502        if predicate is None:
1503            return len(self)
1504        predicate = self.__callback_overload_warpper__(predicate)
1505        return sum(1 for i in self if predicate(i))

Returns the number of elements in the Sequence that satisfy the specified [predicate] function.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).count()
3
>>> it(lst).count(lambda x: x > 0)
3
>>> it(lst).count(lambda x: x > 2)
1
def contains(self, value: ~T) -> bool:
1507    def contains(self, value: T) -> bool:
1508        """
1509        Returns True if the Sequence contains the specified [value].
1510
1511        Example 1:
1512        >>> lst = [1, 2, 3]
1513        >>> it(lst).contains(1)
1514        True
1515        >>> it(lst).contains(4)
1516        False
1517        """
1518        return value in self

Returns True if the Sequence contains the specified [value].

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).contains(1)
True
>>> it(lst).contains(4)
False
def element_at(self, index: int) -> ~T:
1520    def element_at(self, index: int) -> T:
1521        """
1522        Returns the element at the specified [index] in the Sequence.
1523
1524        Example 1:
1525        >>> lst = [1, 2, 3]
1526        >>> it(lst).element_at(1)
1527        2
1528
1529        Example 2:
1530        >>> lst = [1, 2, 3]
1531        >>> it(lst).element_at(3)
1532        Traceback (most recent call last):
1533        ...
1534        IndexError: Index 3 out of range
1535        """
1536        return self.element_at_or_else(
1537            index, lambda index: throw(IndexError(f"Index {index} out of range"))
1538        )

Returns the element at the specified [index] in the Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).element_at(1)
2

Example 2:

>>> lst = [1, 2, 3]
>>> it(lst).element_at(3)
Traceback (most recent call last):
...
IndexError: Index 3 out of range
def element_at_or_else( self, index: int, default: Union[Callable[[int], ~T], ~T, NoneType] = None) -> Optional[~T]:
1558    def element_at_or_else(
1559        self, index: int, default: Union[Callable[[int], T], T, None] = None
1560    ) -> Optional[T]:
1561        """
1562        Returns the element at the specified [index] in the Sequence or the [default] value if the index is out of bounds.
1563
1564        Example 1:
1565        >>> lst = [1, 2, 3]
1566        >>> it(lst).element_at_or_else(1, lambda x: 'default')
1567        2
1568        >>> it(lst).element_at_or_else(4, lambda x: 'default')
1569        'default'
1570
1571        """
1572        if index >= 0:
1573            if (
1574                isinstance(self.__transform__, NonTransform)
1575                and isinstance(self.__transform__.iter, list)
1576                and index < len(self.__transform__.iter)
1577            ):
1578                return self.__transform__.iter[index]
1579            for i, e in enumerate(self):
1580                if i == index:
1581                    return e
1582        return default(index) if callable(default) else default  # type: ignore

Returns the element at the specified [index] in the Sequence or the [default] value if the index is out of bounds.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).element_at_or_else(1, lambda x: 'default')
2
>>> it(lst).element_at_or_else(4, lambda x: 'default')
'default'
def element_at_or_default(self, index: int, default: ~T) -> ~T:
1584    def element_at_or_default(self, index: int, default: T) -> T:
1585        """
1586        Returns the element at the specified [index] in the Sequence or the [default] value if the index is out of bounds.
1587
1588        Example 1:
1589        >>> lst = [1, 2, 3]
1590        >>> it(lst).element_at_or_default(1, 'default')
1591        2
1592        >>> it(lst).element_at_or_default(4, 'default')
1593        'default'
1594
1595        """
1596        return self.element_at_or_else(index, default)

Returns the element at the specified [index] in the Sequence or the [default] value if the index is out of bounds.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).element_at_or_default(1, 'default')
2
>>> it(lst).element_at_or_default(4, 'default')
'default'
def element_at_or_none(self, index: int) -> Optional[~T]:
1598    def element_at_or_none(self, index: int) -> Optional[T]:
1599        """
1600        Returns the element at the specified [index] in the Sequence or None if the index is out of bounds.
1601
1602        Example 1:
1603        >>> lst = [1, 2, 3]
1604        >>> it(lst).element_at_or_none(1)
1605        2
1606        >>> it(lst).element_at_or_none(4) is None
1607        True
1608        """
1609        return self.element_at_or_else(index)

Returns the element at the specified [index] in the Sequence or None if the index is out of bounds.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).element_at_or_none(1)
2
>>> it(lst).element_at_or_none(4) is None
True
def distinct(self) -> pyiter.sequence.Sequence[~T]:
1611    def distinct(self) -> Sequence[T]:
1612        """
1613        Returns a new Sequence containing the distinct elements of the given Sequence.
1614
1615        Example 1:
1616        >>> lst = [1, 2, 3, 1, 2, 3]
1617        >>> it(lst).distinct().to_list()
1618        [1, 2, 3]
1619
1620        Example 2:
1621        >>> lst = [(1, 'A'), (1, 'A'), (1, 'A'), (2, 'A'), (3, 'C'), (3, 'D')]
1622        >>> it(lst).distinct().sorted().to_list()
1623        [(1, 'A'), (2, 'A'), (3, 'C'), (3, 'D')]
1624
1625        """
1626        from .distinct import DistinctTransform
1627
1628        return it(DistinctTransform(self))

Returns a new Sequence containing the distinct elements of the given Sequence.

Example 1:

>>> lst = [1, 2, 3, 1, 2, 3]
>>> it(lst).distinct().to_list()
[1, 2, 3]

Example 2:

>>> lst = [(1, 'A'), (1, 'A'), (1, 'A'), (2, 'A'), (3, 'C'), (3, 'D')]
>>> it(lst).distinct().sorted().to_list()
[(1, 'A'), (2, 'A'), (3, 'C'), (3, 'D')]
def distinct_by(self, key_selector: Callable[..., Any]) -> pyiter.sequence.Sequence[~T]:
1636    def distinct_by(self, key_selector: Callable[..., Any]) -> Sequence[T]:
1637        """
1638        Returns a new Sequence containing the distinct elements of the given Sequence.
1639
1640        Example 1:
1641        >>> lst = [1, 2, 3, 1, 2, 3]
1642        >>> it(lst).distinct_by(lambda x: x%2).to_list()
1643        [1, 2]
1644        """
1645        from .distinct import DistinctTransform
1646
1647        return it(DistinctTransform(self, self.__callback_overload_warpper__(key_selector)))

Returns a new Sequence containing the distinct elements of the given Sequence.

Example 1:

>>> lst = [1, 2, 3, 1, 2, 3]
>>> it(lst).distinct_by(lambda x: x%2).to_list()
[1, 2]
def reduce( self, accumulator: Callable[..., ~U], initial: Optional[~U] = None) -> Optional[~U]:
1653    def reduce(self, accumulator: Callable[..., U], initial: Optional[U] = None) -> Optional[U]:
1654        """
1655        Returns the result of applying the specified [accumulator] function to the given Sequence's elements.
1656
1657        Example 1:
1658        >>> lst = [1, 2, 3]
1659        >>> it(lst).reduce(lambda x, y: x+y)
1660        6
1661        """
1662        result: Optional[U] = initial
1663        for i, e in enumerate(self):
1664            if i == 0 and initial is None:
1665                result = e  # type: ignore
1666                continue
1667
1668            result = accumulator(result, e)
1669        return result

Returns the result of applying the specified [accumulator] function to the given Sequence's elements.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).reduce(lambda x, y: x+y)
6
def fold(self, initial: ~U, accumulator: Callable[[~U, ~T], ~U]) -> ~U:
1671    def fold(self, initial: U, accumulator: Callable[[U, T], U]) -> U:
1672        """
1673        Returns the result of applying the specified [accumulator] function to the given Sequence's elements.
1674
1675        Example 1:
1676        >>> lst = [1, 2, 3]
1677        >>> it(lst).fold(0, lambda x, y: x+y)
1678        6
1679        """
1680        return self.reduce(accumulator, initial)

Returns the result of applying the specified [accumulator] function to the given Sequence's elements.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).fold(0, lambda x, y: x+y)
6
def sum_of(self, selector: Callable[[~T], Union[int, float]]) -> Union[int, float]:
1686    def sum_of(self, selector: Callable[[T], Union[int, float]]) -> Union[int, float]:
1687        """
1688        Returns the sum of the elements of the given Sequence.
1689
1690        Example 1:
1691        >>> lst = [1, 2, 3]
1692        >>> it(lst).sum_of(lambda x: x)
1693        6
1694        """
1695        return sum(selector(i) for i in self)

Returns the sum of the elements of the given Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).sum_of(lambda x: x)
6
def max_of(self, selector: Callable[[~T], Union[int, float]]) -> Union[int, float]:
1701    def max_of(self, selector: Callable[[T], Union[int, float]]) -> Union[int, float]:
1702        """
1703        Returns the maximum element of the given Sequence.
1704
1705        Example 1:
1706        >>> lst = [1, 2, 3]
1707        >>> it(lst).max_of(lambda x: x)
1708        3
1709        """
1710        return max(selector(i) for i in self)

Returns the maximum element of the given Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).max_of(lambda x: x)
3
def max_by_or_none(self, selector: Callable[[~T], Union[int, float]]) -> Optional[~T]:
1716    def max_by_or_none(self, selector: Callable[[T], Union[float, int]]) -> Optional[T]:
1717        """
1718        Returns the first element yielding the largest value of the given function
1719        or `none` if there are no elements.
1720
1721        Example 1:
1722        >>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
1723        >>> it(lst).max_by_or_none(lambda x: x["num"])
1724        {'name': 'B', 'num': 200}
1725
1726        Example 2:
1727        >>> lst = []
1728        >>> it(lst).max_by_or_none(lambda x: x["num"])
1729        """
1730
1731        max_item = None
1732        max_val = None
1733
1734        for item in self:
1735            val = selector(item)
1736            if max_val is None or val > max_val:
1737                max_item = item
1738                max_val = val
1739
1740        return max_item

Returns the first element yielding the largest value of the given function or none if there are no elements.

Example 1:

>>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
>>> it(lst).max_by_or_none(lambda x: x["num"])
{'name': 'B', 'num': 200}

Example 2:

>>> lst = []
>>> it(lst).max_by_or_none(lambda x: x["num"])
def max_by(self, selector: Callable[[~T], Union[int, float]]) -> ~T:
1746    def max_by(self, selector: Callable[[T], Union[float, int]]) -> T:
1747        """
1748        Returns the first element yielding the largest value of the given function.
1749
1750        Example 1:
1751        >>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
1752        >>> it(lst).max_by(lambda x: x["num"])
1753        {'name': 'B', 'num': 200}
1754
1755        Exmaple 2:
1756        >>> lst = []
1757        >>> it(lst).max_by(lambda x: x["num"])
1758        Traceback (most recent call last):
1759        ...
1760        ValueError: Sequence is empty.
1761        """
1762        max_item = self.max_by_or_none(selector)
1763        if max_item is None:
1764            raise ValueError("Sequence is empty.")
1765        return max_item

Returns the first element yielding the largest value of the given function.

Example 1:

>>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
>>> it(lst).max_by(lambda x: x["num"])
{'name': 'B', 'num': 200}

Exmaple 2:

>>> lst = []
>>> it(lst).max_by(lambda x: x["num"])
Traceback (most recent call last):
...
ValueError: Sequence is empty.
def min_of(self, selector: Callable[[~T], Union[int, float]]) -> Union[int, float]:
1781    def min_of(self, selector: Callable[[T], Union[int, float]]) -> Union[int, float]:
1782        return min(selector(i) for i in self)

Returns the minimum element of the given Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).min_of(lambda x: x)
1
def min_by_or_none(self, selector: Callable[[~T], float]) -> Optional[~T]:
1788    def min_by_or_none(self, selector: Callable[[T], float]) -> Optional[T]:
1789        """
1790        Returns the first element yielding the smallest value of the given function
1791        or `none` if there are no elements.
1792
1793        Example 1:
1794        >>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
1795        >>> it(lst).min_by_or_none(lambda x: x["num"])
1796        {'name': 'A', 'num': 100}
1797
1798        Exmaple 2:
1799        >>> lst = []
1800        >>> it(lst).min_by_or_none(lambda x: x["num"])
1801        """
1802        min_item = None
1803        min_val = None
1804
1805        for item in self:
1806            val = selector(item)
1807            if min_val is None or val < min_val:
1808                min_item = item
1809                min_val = val
1810
1811        return min_item

Returns the first element yielding the smallest value of the given function or none if there are no elements.

Example 1:

>>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
>>> it(lst).min_by_or_none(lambda x: x["num"])
{'name': 'A', 'num': 100}

Exmaple 2:

>>> lst = []
>>> it(lst).min_by_or_none(lambda x: x["num"])
def min_by(self, selector: Callable[[~T], float]) -> ~T:
1817    def min_by(self, selector: Callable[[T], float]) -> T:
1818        """
1819        Returns the first element yielding the smallest value of the given function.
1820
1821        Example 1:
1822        >>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
1823        >>> it(lst).min_by(lambda x: x["num"])
1824        {'name': 'A', 'num': 100}
1825
1826        Exmaple 2:
1827        >>> lst = []
1828        >>> it(lst).min_by(lambda x: x["num"])
1829        Traceback (most recent call last):
1830        ...
1831        ValueError: Sequence is empty.
1832        """
1833        min_item = self.min_by_or_none(selector)
1834        if min_item is None:
1835            raise ValueError("Sequence is empty.")
1836
1837        return min_item

Returns the first element yielding the smallest value of the given function.

Example 1:

>>> lst = [ { "name": "A", "num": 100 }, { "name": "B", "num": 200 }]
>>> it(lst).min_by(lambda x: x["num"])
{'name': 'A', 'num': 100}

Exmaple 2:

>>> lst = []
>>> it(lst).min_by(lambda x: x["num"])
Traceback (most recent call last):
...
ValueError: Sequence is empty.
def mean_of(self, selector: Callable[[~T], Union[int, float]]) -> Union[int, float]:
1839    def mean_of(self, selector: Callable[[T], Union[int, float]]) -> Union[int, float]:
1840        """
1841        Returns the mean of the elements of the given Sequence.
1842
1843        Example 1:
1844        >>> lst = [1, 2, 3]
1845        >>> it(lst).mean_of(lambda x: x)
1846        2.0
1847        """
1848        return self.sum_of(selector) / len(self)

Returns the mean of the elements of the given Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).mean_of(lambda x: x)
2.0
def sum( self: Union[pyiter.sequence.Sequence[int], pyiter.sequence.Sequence[float]]) -> Union[float, int]:
1864    def sum(self: Union[Sequence[int], Sequence[float]]) -> Union[float, int]:
1865        """
1866        Returns the sum of the elements of the given Sequence.
1867
1868        Example 1:
1869        >>> lst = [1, 2, 3]
1870        >>> it(lst).sum()
1871        6
1872        """
1873        return sum(self)

Returns the sum of the elements of the given Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).sum()
6
def max( self: Union[pyiter.sequence.Sequence[int], pyiter.sequence.Sequence[float]]) -> Union[float, int]:
1879    def max(self: Union[Sequence[int], Sequence[float]]) -> Union[float, int]:
1880        """
1881        Returns the maximum element of the given Sequence.
1882
1883        Example 1:
1884        >>> lst = [1, 2, 3]
1885        >>> it(lst).max()
1886        3
1887        """
1888        return max(self)

Returns the maximum element of the given Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).max()
3
def max_or_default( self: Union[pyiter.sequence.Sequence[int], pyiter.sequence.Sequence[float]], default: Optional[~O] = None) -> Union[float, int, ~O, NoneType]:
1898    def max_or_default(
1899        self: Union[Sequence[int], Sequence[float]], default: Optional[V] = None
1900    ) -> Union[float, int, V, None]:
1901        """
1902        Returns the maximum element of the given Sequence.
1903
1904        Example 1:
1905        >>> lst = [1, 2, 3]
1906        >>> it(lst).max_or_default()
1907        3
1908
1909        Example 2:
1910        >>> lst = []
1911        >>> it(lst).max_or_default() is None
1912        True
1913
1914        Example 3:
1915        >>> lst = []
1916        >>> it(lst).max_or_default(9)
1917        9
1918        """
1919        if self.is_empty():
1920            return default
1921        return max(self)

Returns the maximum element of the given Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).max_or_default()
3

Example 2:

>>> lst = []
>>> it(lst).max_or_default() is None
True

Example 3:

>>> lst = []
>>> it(lst).max_or_default(9)
9
def max_or_none( self: Union[pyiter.sequence.Sequence[int], pyiter.sequence.Sequence[float]]) -> Union[float, int, NoneType]:
1927    def max_or_none(
1928        self: Union[Sequence[int], Sequence[float]],
1929    ) -> Union[float, int, None]:
1930        """
1931        Returns the maximum element of the given Sequence.
1932
1933        Example 1:
1934        >>> lst = [1, 2, 3]
1935        >>> it(lst).max_or_none()
1936        3
1937
1938        Example 2:
1939        >>> lst = []
1940        >>> it(lst).max_or_none() is None
1941        True
1942        """
1943        return self.max_or_default(None)

Returns the maximum element of the given Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).max_or_none()
3

Example 2:

>>> lst = []
>>> it(lst).max_or_none() is None
True
def min( self: Union[pyiter.sequence.Sequence[int], pyiter.sequence.Sequence[float]]) -> Union[float, int]:
1959    def min(self: Union[Sequence[int], Sequence[float]]) -> Union[float, int]:
1960        """
1961        Returns the minimum element of the given Sequence.
1962
1963        Example 1:
1964        >>> lst = [1, 2, 3]
1965        >>> it(lst).min()
1966        1
1967        """
1968        return min(self)

Returns the minimum element of the given Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).min()
1
def min_or_none( self: Union[pyiter.sequence.Sequence[int], pyiter.sequence.Sequence[float]]) -> Union[float, int, NoneType]:
1984    def min_or_none(
1985        self: Union[Sequence[int], Sequence[float]],
1986    ) -> Union[float, int, None]:
1987        """
1988        Returns the minimum element of the given Sequence.
1989
1990        Example 1:
1991        >>> lst = [1, 2, 3]
1992        >>> it(lst).min_or_none()
1993        1
1994        """
1995        return self.min_or_default(None)

Returns the minimum element of the given Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).min_or_none()
1
def min_or_default( self: Union[pyiter.sequence.Sequence[int], pyiter.sequence.Sequence[float]], default: Optional[~O] = None) -> Union[float, int, ~O, NoneType]:
2015    def min_or_default(
2016        self: Union[Sequence[int], Sequence[float]], default: Optional[V] = None
2017    ) -> Union[float, int, V, None]:
2018        """
2019        Returns the minimum element of the given Sequence.
2020
2021        Example 1:
2022        >>> lst = [1, 2, 3]
2023        >>> it(lst).min_or_default()
2024        1
2025
2026        Example 2:
2027        >>> lst = []
2028        >>> it(lst).min_or_default(9)
2029        9
2030        """
2031        if self.is_empty():
2032            return default
2033        return min(self)

Returns the minimum element of the given Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).min_or_default()
1

Example 2:

>>> lst = []
>>> it(lst).min_or_default(9)
9
def mean( self: Union[pyiter.sequence.Sequence[int], pyiter.sequence.Sequence[float]]) -> float:
2049    def mean(self: Union[Sequence[int], Sequence[float]]) -> float:
2050        """
2051        Returns the mean of the elements of the given Sequence.
2052
2053        Example 1:
2054        >>> lst = [1, 2, 3]
2055        >>> it(lst).mean()
2056        2.0
2057        """
2058        return self.sum() / len(self)

Returns the mean of the elements of the given Sequence.

Example 1:

>>> lst = [1, 2, 3]
>>> it(lst).mean()
2.0
def reversed(self) -> pyiter.sequence.Sequence[~T]:
2061    def reversed(self) -> Sequence[T]:
2062        """
2063        Returns a list with elements in reversed order.
2064
2065        Example 1:
2066        >>> lst = ['b', 'c', 'a']
2067        >>> it(lst).reversed().to_list()
2068        ['a', 'c', 'b']
2069        """
2070        lst = list(self)
2071        lst.reverse()
2072        return it(lst)

Returns a list with elements in reversed order.

Example 1:

>>> lst = ['b', 'c', 'a']
>>> it(lst).reversed().to_list()
['a', 'c', 'b']
def flat_map( self, transform: Callable[..., Iterable[~U]]) -> pyiter.sequence.Sequence[~U]:
2080    def flat_map(self, transform: Callable[..., Iterable[U]]) -> Sequence[U]:
2081        """
2082        Returns a single list of all elements yielded from results of [transform]
2083        function being invoked on each element of original collection.
2084
2085        Example 1:
2086        >>> lst = [['a', 'b'], ['c'], ['d', 'e']]
2087        >>> it(lst).flat_map(lambda x: x).to_list()
2088        ['a', 'b', 'c', 'd', 'e']
2089        """
2090        return self.map(transform).flatten()

Returns a single list of all elements yielded from results of [transform] function being invoked on each element of original collection.

Example 1:

>>> lst = [['a', 'b'], ['c'], ['d', 'e']]
>>> it(lst).flat_map(lambda x: x).to_list()
['a', 'b', 'c', 'd', 'e']
def flatten(self: Iterable[Iterable[~U]]) -> pyiter.sequence.Sequence[~U]:
2092    def flatten(self: Iterable[Iterable[U]]) -> Sequence[U]:
2093        """
2094        Returns a sequence of all elements from all sequences in this sequence.
2095
2096        Example 1:
2097        >>> lst = [['a', 'b'], ['c'], ['d', 'e']]
2098        >>> it(lst).flatten().to_list()
2099        ['a', 'b', 'c', 'd', 'e']
2100        """
2101        from .flattening import FlatteningTransform
2102
2103        return it(FlatteningTransform(self))

Returns a sequence of all elements from all sequences in this sequence.

Example 1:

>>> lst = [['a', 'b'], ['c'], ['d', 'e']]
>>> it(lst).flatten().to_list()
['a', 'b', 'c', 'd', 'e']
def group_by(self, key_selector: Callable[..., ~K]) -> 'Sequence[Grouping[K, T]]':
2113    def group_by(self, key_selector: Callable[..., K]) -> Sequence[Grouping[K, T]]:
2114        """
2115        Returns a dictionary with keys being the result of [key_selector] function being invoked on each element of original collection
2116        and values being the corresponding elements of original collection.
2117
2118        Example 1:
2119        >>> lst = [1, 2, 3, 4, 5]
2120        >>> it(lst).group_by(lambda x: x%2).map(lambda x: (x.key, x.values.to_list())).to_list()
2121        [(1, [1, 3, 5]), (0, [2, 4])]
2122        """
2123        from .grouping import GroupingTransform
2124
2125        return it(GroupingTransform(self, self.__callback_overload_warpper__(key_selector)))

Returns a dictionary with keys being the result of [key_selector] function being invoked on each element of original collection and values being the corresponding elements of original collection.

Example 1:

>>> lst = [1, 2, 3, 4, 5]
>>> it(lst).group_by(lambda x: x%2).map(lambda x: (x.key, x.values.to_list())).to_list()
[(1, [1, 3, 5]), (0, [2, 4])]
def group_by_to( self, destination: Dict[~K, List[~T]], key_selector: Callable[..., ~K]) -> Dict[~K, List[~T]]:
2141    def group_by_to(
2142        self, destination: Dict[K, List[T]], key_selector: Callable[..., K]
2143    ) -> Dict[K, List[T]]:
2144        """
2145        Returns a dictionary with keys being the result of [key_selector] function being invoked on each element of original collection
2146        and values being the corresponding elements of original collection.
2147
2148        Example 1:
2149        >>> lst = [1, 2, 3, 4, 5]
2150        >>> it(lst).group_by_to({}, lambda x: x%2)
2151        {1: [1, 3, 5], 0: [2, 4]}
2152        """
2153        key_selector = self.__callback_overload_warpper__(key_selector)
2154        for e in self:
2155            k = key_selector(e)
2156            if k not in destination:
2157                destination[k] = []
2158            destination[k].append(e)
2159        return destination

Returns a dictionary with keys being the result of [key_selector] function being invoked on each element of original collection and values being the corresponding elements of original collection.

Example 1:

>>> lst = [1, 2, 3, 4, 5]
>>> it(lst).group_by_to({}, lambda x: x%2)
{1: [1, 3, 5], 0: [2, 4]}
def for_each(self, action: Callable[..., NoneType]) -> None:
2167    def for_each(self, action: Callable[..., None]) -> None:
2168        """
2169        Invokes [action] function on each element of the given Sequence.
2170
2171        Example 1:
2172        >>> lst = ['a', 'b', 'c']
2173        >>> it(lst).for_each(lambda x: print(x))
2174        a
2175        b
2176        c
2177
2178        Example 2:
2179        >>> lst = ['a', 'b', 'c']
2180        >>> it(lst).for_each(lambda x, i: print(x, i))
2181        a 0
2182        b 1
2183        c 2
2184        """
2185        self.on_each(action)

Invokes [action] function on each element of the given Sequence.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).for_each(lambda x: print(x))
a
b
c

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).for_each(lambda x, i: print(x, i))
a 0
b 1
c 2
def parallel_for_each( self, action: Callable[..., NoneType], max_workers: Optional[int] = None) -> None:
2201    def parallel_for_each(
2202        self, action: Callable[..., None], max_workers: Optional[int] = None
2203    ) -> None:
2204        """
2205        Invokes [action] function on each element of the given Sequence in parallel.
2206
2207        Example 1:
2208        >>> lst = ['a', 'b', 'c']
2209        >>> it(lst).parallel_for_each(lambda x: print(x))
2210        a
2211        b
2212        c
2213
2214        Example 2:
2215        >>> lst = ['a', 'b', 'c']
2216        >>> it(lst).parallel_for_each(lambda x: print(x), max_workers=2)
2217        a
2218        b
2219        c
2220        """
2221        self.parallel_on_each(action, max_workers)

Invokes [action] function on each element of the given Sequence in parallel.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).parallel_for_each(lambda x: print(x))
a
b
c

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).parallel_for_each(lambda x: print(x), max_workers=2)
a
b
c
def on_each(self, action: Callable[..., NoneType]) -> pyiter.sequence.Sequence[~T]:
2229    def on_each(self, action: Callable[..., None]) -> Sequence[T]:
2230        """
2231        Invokes [action] function on each element of the given Sequence.
2232
2233        Example 1:
2234        >>> lst = ['a', 'b', 'c']
2235        >>> it(lst).on_each(lambda x: print(x)) and None
2236        a
2237        b
2238        c
2239
2240        Example 2:
2241        >>> lst = ['a', 'b', 'c']
2242        >>> it(lst).on_each(lambda x, i: print(x, i)) and None
2243        a 0
2244        b 1
2245        c 2
2246        """
2247        action = self.__callback_overload_warpper__(action)
2248        for i in self:
2249            action(i)
2250        return self

Invokes [action] function on each element of the given Sequence.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).on_each(lambda x: print(x)) and None
a
b
c

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).on_each(lambda x, i: print(x, i)) and None
a 0
b 1
c 2
def parallel_on_each( self, action: Callable[..., NoneType], max_workers: Optional[int] = None, chunksize: int = 1, executor: "'ParallelMappingTransform.Executor'" = 'Thread') -> pyiter.sequence.Sequence[~T]:
2276    def parallel_on_each(
2277        self,
2278        action: Callable[..., None],
2279        max_workers: Optional[int] = None,
2280        chunksize: int = 1,
2281        executor: "ParallelMappingTransform.Executor" = "Thread",
2282    ) -> Sequence[T]:
2283        """
2284        Invokes [action] function on each element of the given Sequence.
2285
2286        Example 1:
2287        >>> lst = ['a', 'b', 'c']
2288        >>> it(lst).parallel_on_each(lambda x: print(x)) and None
2289        a
2290        b
2291        c
2292
2293        Example 2:
2294        >>> lst = ['a', 'b', 'c']
2295        >>> it(lst).parallel_on_each(lambda x: print(x), max_workers=2) and None
2296        a
2297        b
2298        c
2299        """
2300        from .parallel_mapping import ParallelMappingTransform
2301
2302        action = self.__callback_overload_warpper__(action)
2303        for _ in ParallelMappingTransform(self, action, max_workers, chunksize, executor):
2304            pass
2305        return self

Invokes [action] function on each element of the given Sequence.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).parallel_on_each(lambda x: print(x)) and None
a
b
c

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).parallel_on_each(lambda x: print(x), max_workers=2) and None
a
b
c
def zip( self, other: Iterable[Any], transform: Optional[Callable[..., ~O]] = None) -> pyiter.sequence.Sequence[typing.Any]:
2311    def zip(
2312        self,
2313        other: Iterable[Any],
2314        transform: Optional[Callable[..., V]] = None,  # type: ignore
2315    ) -> Sequence[Any]:
2316        """
2317        Returns a new Sequence of tuples, where each tuple contains two elements.
2318
2319        Example 1:
2320        >>> lst1 = ['a', 'b', 'c']
2321        >>> lst2 = [1, 2, 3]
2322        >>> it(lst1).zip(lst2).to_list()
2323        [('a', 1), ('b', 2), ('c', 3)]
2324
2325        Example 2:
2326        >>> lst1 = ['a', 'b', 'c']
2327        >>> lst2 = [1, 2, 3]
2328        >>> it(lst1).zip(lst2, lambda x, y: x + '__' +str( y)).to_list()
2329        ['a__1', 'b__2', 'c__3']
2330        """
2331        if transform is None:
2332
2333            def transform(*x: Any) -> Tuple[Any, ...]:
2334                return (*x,)
2335
2336        from .merging import MergingTransform
2337
2338        return it(MergingTransform(self, other, transform))

Returns a new Sequence of tuples, where each tuple contains two elements.

Example 1:

>>> lst1 = ['a', 'b', 'c']
>>> lst2 = [1, 2, 3]
>>> it(lst1).zip(lst2).to_list()
[('a', 1), ('b', 2), ('c', 3)]

Example 2:

>>> lst1 = ['a', 'b', 'c']
>>> lst2 = [1, 2, 3]
>>> it(lst1).zip(lst2, lambda x, y: x + '__' +str( y)).to_list()
['a__1', 'b__2', 'c__3']
def zip_with_next( self, transform: Optional[Callable[[~T, ~T], Any]] = None) -> pyiter.sequence.Sequence[typing.Any]:
2344    def zip_with_next(self, transform: Optional[Callable[[T, T], Any]] = None) -> Sequence[Any]:
2345        """
2346        Returns a sequence containing the results of applying the given [transform] function
2347        to an each pair of two adjacent elements in this sequence.
2348
2349        Example 1:
2350        >>> lst = ['a', 'b', 'c']
2351        >>> it(lst).zip_with_next(lambda x, y: x + '__' + y).to_list()
2352        ['a__b', 'b__c']
2353
2354        Example 2:
2355        >>> lst = ['a', 'b', 'c']
2356        >>> it(lst).zip_with_next().to_list()
2357        [('a', 'b'), ('b', 'c')]
2358        """
2359        from .merging_with_next import MergingWithNextTransform
2360
2361        return it(MergingWithNextTransform(self, transform or (lambda a, b: (a, b))))

Returns a sequence containing the results of applying the given [transform] function to an each pair of two adjacent elements in this sequence.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).zip_with_next(lambda x, y: x + '__' + y).to_list()
['a__b', 'b__c']

Example 2:

>>> lst = ['a', 'b', 'c']
>>> it(lst).zip_with_next().to_list()
[('a', 'b'), ('b', 'c')]
def unzip( self: pyiter.sequence.Sequence[typing.Tuple[~U, ~O]], transform: Union[Callable[..., Tuple[Any, Any]], NoneType, bool] = None) -> "'Tuple[ListLike[U], ListLike[V]]'":
2375    def unzip(  # type: ignore
2376        self: Sequence[Tuple[U, V]],
2377        transform: Union[Optional[Callable[..., Tuple[Any, Any]]], bool] = None,
2378    ) -> "Tuple[ListLike[U], ListLike[V]]":
2379        """
2380        Returns a pair of lists, where first list is built from the first values of each pair from this array, second list is built from the second values of each pair from this array.
2381
2382        Example 1:
2383        >>> lst = [{'name': 'a', 'age': 11}, {'name': 'b', 'age': 12}, {'name': 'c', 'age': 13}]
2384        >>> a, b = it(lst).unzip(lambda x: (x['name'], x['age']))
2385        >>> a
2386        ['a', 'b', 'c']
2387        >>> b
2388        [11, 12, 13]
2389
2390        Example 1:
2391        >>> lst = [('a', 11), ('b', 12), ('c', 13)]
2392        >>> a, b = it(lst).unzip()
2393        >>> a
2394        ['a', 'b', 'c']
2395        >>> b
2396        [11, 12, 13]
2397        """
2398        from .list_like import ListLike
2399
2400        it = self
2401        if isinstance(transform, bool):
2402            transform = None
2403
2404        if transform is not None:
2405            transform = self.__callback_overload_warpper__(transform)
2406            it = it.map(transform)
2407
2408        a = it.map(lambda x: x[0])  # type: ignore
2409        b = it.map(lambda x: x[1])  # type: ignore
2410
2411        return ListLike(a), ListLike(b)

Returns a pair of lists, where first list is built from the first values of each pair from this array, second list is built from the second values of each pair from this array.

Example 1:

>>> lst = [{'name': 'a', 'age': 11}, {'name': 'b', 'age': 12}, {'name': 'c', 'age': 13}]
>>> a, b = it(lst).unzip(lambda x: (x['name'], x['age']))
>>> a
['a', 'b', 'c']
>>> b
[11, 12, 13]

Example 1:

>>> lst = [('a', 11), ('b', 12), ('c', 13)]
>>> a, b = it(lst).unzip()
>>> a
['a', 'b', 'c']
>>> b
[11, 12, 13]
def with_index(self):
2413    def with_index(self):
2414        """
2415        Returns a sequence containing the elements of this sequence and their indexes.
2416
2417        Example 1:
2418        >>> lst = ['a', 'b', 'c']
2419        >>> it(lst).with_index().to_list()
2420        [IndexedValue(0, a), IndexedValue(1, b), IndexedValue(2, c)]
2421        """
2422        return self.indexed()

Returns a sequence containing the elements of this sequence and their indexes.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).with_index().to_list()
[IndexedValue(0, a), IndexedValue(1, b), IndexedValue(2, c)]
def shuffled( self, random: "Optional[Union['Random', int, str]]" = None) -> pyiter.sequence.Sequence[~T]:
2432    def shuffled(  # type: ignore
2433        self, random: Optional[Union["Random", int, str]] = None
2434    ) -> Sequence[T]:
2435        """
2436        Returns a sequence that yields elements of this sequence randomly shuffled
2437        using the specified [random] instance as the source of randomness.
2438
2439        Example 1:
2440        >>> lst = ['a', 'b', 'c']
2441        >>> it(lst).shuffled('123').to_list()
2442        ['b', 'a', 'c']
2443
2444        Example 2:
2445        >>> from random import Random
2446        >>> lst = ['a', 'b', 'c']
2447        >>> it(lst).shuffled(Random('123')).to_list()
2448        ['b', 'a', 'c']
2449
2450        Example 3:
2451        >>> lst = ['a', 'b', 'c']
2452        >>> it(lst).shuffled(123).to_list()
2453        ['c', 'b', 'a']
2454        """
2455        from .shuffling import ShufflingTransform
2456
2457        return it(ShufflingTransform(self, random))

Returns a sequence that yields elements of this sequence randomly shuffled using the specified [random] instance as the source of randomness.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).shuffled('123').to_list()
['b', 'a', 'c']

Example 2:

>>> from random import Random
>>> lst = ['a', 'b', 'c']
>>> it(lst).shuffled(Random('123')).to_list()
['b', 'a', 'c']

Example 3:

>>> lst = ['a', 'b', 'c']
>>> it(lst).shuffled(123).to_list()
['c', 'b', 'a']
def partition( self, predicate: Callable[..., bool]) -> "'Tuple[ListLike[T], ListLike[T]]'":
2469    def partition(self, predicate: Callable[..., bool]) -> "Tuple[ListLike[T], ListLike[T]]":
2470        """
2471        Partitions the elements of the given Sequence into two groups,
2472        the first group containing the elements for which the predicate returns true,
2473        and the second containing the rest.
2474
2475        Example 1:
2476        >>> lst = ['a', 'b', 'c', '2']
2477        >>> it(lst).partition(lambda x: x.isalpha())
2478        (['a', 'b', 'c'], ['2'])
2479
2480        Example 2:
2481        >>> lst = ['a', 'b', 'c', '2']
2482        >>> it(lst).partition(lambda _, i: i % 2 == 0)
2483        (['a', 'c'], ['b', '2'])
2484        """
2485        from .list_like import ListLike
2486
2487        predicate_a = self.__callback_overload_warpper__(predicate)
2488        predicate_b = self.__callback_overload_warpper__(predicate)
2489        part_a = self.filter(predicate_a)
2490        part_b = self.filter(lambda x: not predicate_b(x))
2491        return ListLike(part_a), ListLike(part_b)

Partitions the elements of the given Sequence into two groups, the first group containing the elements for which the predicate returns true, and the second containing the rest.

Example 1:

>>> lst = ['a', 'b', 'c', '2']
>>> it(lst).partition(lambda x: x.isalpha())
(['a', 'b', 'c'], ['2'])

Example 2:

>>> lst = ['a', 'b', 'c', '2']
>>> it(lst).partition(lambda _, i: i % 2 == 0)
(['a', 'c'], ['b', '2'])
def indexed(self) -> pyiter.sequence.Sequence[pyiter.sequence.IndexedValue[~T]]:
2493    def indexed(self) -> Sequence[IndexedValue[T]]:
2494        return self.map(lambda x, i: IndexedValue(x, i))
def combinations(self, n: int) -> pyiter.sequence.Sequence[typing.Tuple[~T, ...]]:
2504    def combinations(self, n: int) -> Sequence[Tuple[T, ...]]:
2505        """
2506        Returns a Sequence of all possible combinations of size [n] from the given Sequence.
2507
2508        Example 1:
2509        >>> lst = ['a', 'b', 'c']
2510        >>> it(lst).combinations(2).to_list()
2511        [('a', 'b'), ('a', 'c'), ('b', 'c')]
2512        """
2513        from .combination import CombinationTransform
2514
2515        return it(CombinationTransform(self, n))

Returns a Sequence of all possible combinations of size [n] from the given Sequence.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).combinations(2).to_list()
[('a', 'b'), ('a', 'c'), ('b', 'c')]
def nth(self, n: int) -> ~T:
2517    def nth(self, n: int) -> T:
2518        """
2519        Returns the nth element of the given Sequence.
2520
2521        Example 1:
2522        >>> lst = ['a', 'b', 'c']
2523        >>> it(lst).nth(2)
2524        'c'
2525        """
2526        return self.skip(n).first()

Returns the nth element of the given Sequence.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).nth(2)
'c'
def windowed( self, size: int, step: int = 1, partialWindows: bool = False) -> pyiter.sequence.Sequence[typing.List[~T]]:
2528    def windowed(self, size: int, step: int = 1, partialWindows: bool = False) -> Sequence[List[T]]:
2529        """
2530         Returns a Sequence of all possible sliding windows of size [size] from the given Sequence.
2531
2532        Example 1:
2533        >>> lst = ['a', 'b', 'c', 'd', 'e']
2534        >>> it(lst).windowed(3).to_list()
2535        [['a', 'b', 'c'], ['b', 'c', 'd'], ['c', 'd', 'e']]
2536
2537        Example 2:
2538        >>> lst = ['a', 'b', 'c', 'd', 'e']
2539        >>> it(lst).windowed(3, 2).to_list()
2540        [['a', 'b', 'c'], ['c', 'd', 'e']]
2541
2542        Example 3:
2543        >>> lst = ['a', 'b', 'c', 'd', 'e', 'f']
2544        >>> it(lst).windowed(3, 2, True).to_list()
2545        [['a', 'b', 'c'], ['c', 'd', 'e'], ['e', 'f']]
2546        """
2547        from .windowed import WindowedTransform
2548
2549        return it(WindowedTransform(self, size, step, partialWindows))

Returns a Sequence of all possible sliding windows of size [size] from the given Sequence.

Example 1:

>>> lst = ['a', 'b', 'c', 'd', 'e']
>>> it(lst).windowed(3).to_list()
[['a', 'b', 'c'], ['b', 'c', 'd'], ['c', 'd', 'e']]

Example 2:

>>> lst = ['a', 'b', 'c', 'd', 'e']
>>> it(lst).windowed(3, 2).to_list()
[['a', 'b', 'c'], ['c', 'd', 'e']]

Example 3:

>>> lst = ['a', 'b', 'c', 'd', 'e', 'f']
>>> it(lst).windowed(3, 2, True).to_list()
[['a', 'b', 'c'], ['c', 'd', 'e'], ['e', 'f']]
def chunked(self, size: int) -> pyiter.sequence.Sequence[typing.List[~T]]:
2551    def chunked(self, size: int) -> Sequence[List[T]]:
2552        """
2553        Returns a Sequence of all possible chunks of size [size] from the given Sequence.
2554
2555        Example 1:
2556        >>> lst = ['a', 'b', 'c', 'd', 'e']
2557        >>> it(lst).chunked(3).to_list()
2558        [['a', 'b', 'c'], ['d', 'e']]
2559
2560
2561        Example 2:
2562        >>> lst = ['a', 'b', 'c', 'd', 'e', 'f']
2563        >>> it(lst).chunked(3).to_list()
2564        [['a', 'b', 'c'], ['d', 'e', 'f']]
2565        """
2566        return self.windowed(size, size, True)

Returns a Sequence of all possible chunks of size [size] from the given Sequence.

Example 1:

>>> lst = ['a', 'b', 'c', 'd', 'e']
>>> it(lst).chunked(3).to_list()
[['a', 'b', 'c'], ['d', 'e']]

Example 2:

>>> lst = ['a', 'b', 'c', 'd', 'e', 'f']
>>> it(lst).chunked(3).to_list()
[['a', 'b', 'c'], ['d', 'e', 'f']]
def repeat(self, n: int) -> pyiter.sequence.Sequence[~T]:
2568    def repeat(self, n: int) -> Sequence[T]:
2569        """
2570        Returns a Sequence containing this sequence repeated n times.
2571
2572        Example 1:
2573        >>> lst = ['a', 'b']
2574        >>> it(lst).repeat(3).to_list()
2575        ['a', 'b', 'a', 'b', 'a', 'b']
2576        """
2577        from .concat import ConcatTransform
2578
2579        return it(ConcatTransform([self] * n))

Returns a Sequence containing this sequence repeated n times.

Example 1:

>>> lst = ['a', 'b']
>>> it(lst).repeat(3).to_list()
['a', 'b', 'a', 'b', 'a', 'b']
def concat( self, *other: pyiter.sequence.Sequence[~T]) -> pyiter.sequence.Sequence[~T]:
2581    def concat(self, *other: Sequence[T]) -> Sequence[T]:
2582        """
2583        Returns a Sequence of all elements of the given Sequence, followed by all elements of the given Sequence.
2584
2585        Example 1:
2586        >>> lst1 = ['a', 'b', 'c']
2587        >>> lst2 = [1, 2, 3]
2588        >>> it(lst1).concat(lst2).to_list()
2589        ['a', 'b', 'c', 1, 2, 3]
2590
2591        Example 2:
2592        >>> lst1 = ['a', 'b', 'c']
2593        >>> lst2 = [1, 2, 3]
2594        >>> lst3 = [4, 5, 6]
2595        >>> it(lst1).concat(lst2, lst3).to_list()
2596        ['a', 'b', 'c', 1, 2, 3, 4, 5, 6]
2597        """
2598        from .concat import ConcatTransform
2599
2600        return it(ConcatTransform([self, *other]))

Returns a Sequence of all elements of the given Sequence, followed by all elements of the given Sequence.

Example 1:

>>> lst1 = ['a', 'b', 'c']
>>> lst2 = [1, 2, 3]
>>> it(lst1).concat(lst2).to_list()
['a', 'b', 'c', 1, 2, 3]

Example 2:

>>> lst1 = ['a', 'b', 'c']
>>> lst2 = [1, 2, 3]
>>> lst3 = [4, 5, 6]
>>> it(lst1).concat(lst2, lst3).to_list()
['a', 'b', 'c', 1, 2, 3, 4, 5, 6]
def intersect( self, *other: pyiter.sequence.Sequence[~T]) -> pyiter.sequence.Sequence[~T]:
2602    def intersect(self, *other: Sequence[T]) -> Sequence[T]:
2603        """
2604        Returns a set containing all elements that are contained by both this collection and the specified collection.
2605
2606        The returned set preserves the element iteration order of the original collection.
2607
2608        To get a set containing all elements that are contained at least in one of these collections use union.
2609
2610        Example 1:
2611        >>> lst1 = ['a', 'b', 'c']
2612        >>> lst2 = ['a2', 'b2', 'c']
2613        >>> it(lst1).intersect(lst2).to_list()
2614        ['c']
2615
2616        Example 2:
2617        >>> lst1 = ['a', 'b', 'c']
2618        >>> lst2 = ['a2', 'b', 'c']
2619        >>> lst3 = ['a3', 'b', 'c3']
2620        >>> it(lst1).intersect(lst2, lst3).to_list()
2621        ['b']
2622
2623
2624        Example 1:
2625        >>> lst1 = ['a', 'a', 'c']
2626        >>> lst2 = ['a2', 'b2', 'a']
2627        >>> it(lst1).intersect(lst2).to_list()
2628        ['a']
2629        """
2630        from .intersection import IntersectionTransform
2631
2632        return it(IntersectionTransform([self, *other]))

Returns a set containing all elements that are contained by both this collection and the specified collection.

The returned set preserves the element iteration order of the original collection.

To get a set containing all elements that are contained at least in one of these collections use union.

Example 1:

>>> lst1 = ['a', 'b', 'c']
>>> lst2 = ['a2', 'b2', 'c']
>>> it(lst1).intersect(lst2).to_list()
['c']

Example 2:

>>> lst1 = ['a', 'b', 'c']
>>> lst2 = ['a2', 'b', 'c']
>>> lst3 = ['a3', 'b', 'c3']
>>> it(lst1).intersect(lst2, lst3).to_list()
['b']

Example 1:

>>> lst1 = ['a', 'a', 'c']
>>> lst2 = ['a2', 'b2', 'a']
>>> it(lst1).intersect(lst2).to_list()
['a']
def union( self, *other: pyiter.sequence.Sequence[~T]) -> pyiter.sequence.Sequence[~T]:
2634    def union(self, *other: Sequence[T]) -> Sequence[T]:
2635        """
2636        Returns a set containing all distinct elements from both collections.
2637
2638        The returned set preserves the element iteration order of the original collection. Those elements of the other collection that are unique are iterated in the end in the order of the other collection.
2639
2640        To get a set containing all elements that are contained in both collections use intersect.
2641
2642        Example 1:
2643        >>> lst1 = ['a', 'b', 'c']
2644        >>> lst2 = ['a2', 'b2', 'c']
2645        >>> it(lst1).union(lst2).to_list()
2646        ['a', 'b', 'c', 'a2', 'b2']
2647
2648        Example 2:
2649        >>> lst1 = ['a', 'b', 'c']
2650        >>> lst2 = ['a2', 'b', 'c']
2651        >>> lst3 = ['a3', 'b', 'c3']
2652        >>> it(lst1).union(lst2, lst3).to_list()
2653        ['a', 'b', 'c', 'a2', 'a3', 'c3']
2654
2655
2656        Example 1:
2657        >>> lst1 = ['a', 'a', 'c']
2658        >>> lst2 = ['a2', 'b2', 'a']
2659        >>> it(lst1).union(lst2).to_list()
2660        ['a', 'c', 'a2', 'b2']
2661        """
2662        return self.concat(*other).distinct()

Returns a set containing all distinct elements from both collections.

The returned set preserves the element iteration order of the original collection. Those elements of the other collection that are unique are iterated in the end in the order of the other collection.

To get a set containing all elements that are contained in both collections use intersect.

Example 1:

>>> lst1 = ['a', 'b', 'c']
>>> lst2 = ['a2', 'b2', 'c']
>>> it(lst1).union(lst2).to_list()
['a', 'b', 'c', 'a2', 'b2']

Example 2:

>>> lst1 = ['a', 'b', 'c']
>>> lst2 = ['a2', 'b', 'c']
>>> lst3 = ['a3', 'b', 'c3']
>>> it(lst1).union(lst2, lst3).to_list()
['a', 'b', 'c', 'a2', 'a3', 'c3']

Example 1:

>>> lst1 = ['a', 'a', 'c']
>>> lst2 = ['a2', 'b2', 'a']
>>> it(lst1).union(lst2).to_list()
['a', 'c', 'a2', 'b2']
def join(self: pyiter.sequence.Sequence[str], separator: str = ' ') -> str:
2664    def join(self: Sequence[str], separator: str = " ") -> str:
2665        """
2666        Joins the elements of the given Sequence into a string.
2667
2668        Example 1:
2669        >>> lst = ['a', 'b', 'c']
2670        >>> it(lst).join(', ')
2671        'a, b, c'
2672        """
2673        return separator.join(self)

Joins the elements of the given Sequence into a string.

Example 1:

>>> lst = ['a', 'b', 'c']
>>> it(lst).join(', ')
'a, b, c'
def progress( self, progress_func: Union[Callable[[Iterable[~T]], Iterable[~T]], Literal['tqdm'], Literal['tqdm_rich'], NoneType] = None) -> pyiter.sequence.Sequence[~T]:
2683    def progress(
2684        self,
2685        progress_func: Union[
2686            Callable[[Iterable[T]], Iterable[T]],
2687            Literal["tqdm"],
2688            Literal["tqdm_rich"],
2689            None,
2690        ] = None,
2691    ) -> Sequence[T]:
2692        """
2693        Returns a Sequence that enable a progress bar for the given Sequence.
2694
2695        Example 1:
2696        >>> from tqdm import tqdm
2697        >>> from time import sleep
2698        >>> it(range(10)).progress(lambda x: tqdm(x, total=len(x))).parallel_map(lambda x: sleep(0.), max_workers=5).to_list() and None
2699        >>> for _ in it(list(range(10))).progress(lambda x: tqdm(x, total=len(x))).to_list(): pass
2700        """
2701        if progress_func is not None and callable(progress_func):
2702            from .progress import ProgressTransform
2703
2704            return it(ProgressTransform(self, progress_func))
2705
2706        def import_tqdm():
2707            if progress_func == "tqdm_rich":
2708                from tqdm.rich import tqdm
2709            else:
2710                from tqdm import tqdm
2711            return tqdm
2712
2713        try:
2714            tqdm = import_tqdm()
2715        except ImportError:
2716            from pip import main as pip
2717
2718            pip(["install", "tqdm"])
2719            tqdm = import_tqdm()
2720
2721        return it(tqdm(self, total=len(self)))

Returns a Sequence that enable a progress bar for the given Sequence.

Example 1:

>>> from tqdm import tqdm
>>> from time import sleep
>>> it(range(10)).progress(lambda x: tqdm(x, total=len(x))).parallel_map(lambda x: sleep(0.), max_workers=5).to_list() and None
>>> for _ in it(list(range(10))).progress(lambda x: tqdm(x, total=len(x))).to_list(): pass
def typing_as(self, typ: Type[~U]) -> pyiter.sequence.Sequence[~U]:
2723    def typing_as(self, typ: Type[U]) -> Sequence[U]:
2724        """
2725        Cast the element as specific Type to gain code completion base on type annotations.
2726        """
2727        el = self.first_not_none_of_or_none()
2728        if el is None or isinstance(el, typ) or not isinstance(el, dict):
2729            return self  # type: ignore
2730
2731        class AttrDict(Dict[str, Any]):
2732            def __init__(self, value: Dict[str, Any]) -> None:
2733                super().__init__(**value)
2734                setattr(self, "__dict__", value)
2735                self.__getattr__ = value.__getitem__
2736                self.__setattr__ = value.__setattr__  # type: ignore
2737
2738        return self.map(AttrDict)  # type: ignore  # use https://github.com/cdgriffith/Box ?

Cast the element as specific Type to gain code completion base on type annotations.

def to_set(self) -> Set[~T]:
2740    def to_set(self) -> Set[T]:
2741        """
2742        Returns a set containing all elements of this Sequence.
2743
2744        Example 1:
2745        >>> it(['a', 'b', 'c', 'c']).to_set() == {'a', 'b', 'c'}
2746        True
2747        """
2748        return set(self)

Returns a set containing all elements of this Sequence.

Example 1:

>>> it(['a', 'b', 'c', 'c']).to_set() == {'a', 'b', 'c'}
True
def to_dict( self, transform: Optional[Callable[..., Tuple[~K, ~O]]] = None) -> Dict[~K, ~O]:
2758    def to_dict(self, transform: Optional[Callable[..., Tuple[K, V]]] = None) -> Dict[K, V]:
2759        """
2760        Returns a [Dict] containing key-value Tuple provided by [transform] function
2761        applied to elements of the given Sequence.
2762
2763        Example 1:
2764        >>> lst = ['1', '2', '3']
2765        >>> it(lst).to_dict(lambda x: (int(x), x))
2766        {1: '1', 2: '2', 3: '3'}
2767
2768        Example 2:
2769        >>> lst = [(1, '1'), (2, '2'), (3, '3')]
2770        >>> it(lst).to_dict()
2771        {1: '1', 2: '2', 3: '3'}
2772        """
2773        return self.associate(transform or (lambda x: x))  # type: ignore

Returns a [Dict] containing key-value Tuple provided by [transform] function applied to elements of the given Sequence.

Example 1:

>>> lst = ['1', '2', '3']
>>> it(lst).to_dict(lambda x: (int(x), x))
{1: '1', 2: '2', 3: '3'}

Example 2:

>>> lst = [(1, '1'), (2, '2'), (3, '3')]
>>> it(lst).to_dict()
{1: '1', 2: '2', 3: '3'}
def to_list(self) -> List[~T]:
2775    def to_list(self) -> List[T]:
2776        """
2777        Returns a list with elements of the given Sequence.
2778
2779        Example 1:
2780        >>> it(['b', 'c', 'a']).to_list()
2781        ['b', 'c', 'a']
2782        """
2783        if self.__transform__.cache is not None:
2784            return self.__transform__.cache.copy()
2785        return [s for s in self]

Returns a list with elements of the given Sequence.

Example 1:

>>> it(['b', 'c', 'a']).to_list()
['b', 'c', 'a']
async def to_list_async(self: Iterable[Awaitable[~T]]) -> List[~T]:
2787    async def to_list_async(self: Iterable[Awaitable[T]]) -> List[T]:
2788        """
2789        Returns a list with elements of the given Sequence.
2790
2791        Example 1:
2792        >>> it(['b', 'c', 'a']).to_list()
2793        ['b', 'c', 'a']
2794        """
2795        from asyncio import gather
2796
2797        return await gather(*self)  # type: ignore

Returns a list with elements of the given Sequence.

Example 1:

>>> it(['b', 'c', 'a']).to_list()
['b', 'c', 'a']
def let(self, block: Callable[[pyiter.sequence.Sequence[~T]], ~U]) -> ~U:
2799    def let(self, block: Callable[[Sequence[T]], U]) -> U:
2800        """
2801        Calls the specified function [block] with `self` value as its argument and returns its result.
2802
2803        Example 1:
2804        >>> it(['a', 'b', 'c']).let(lambda x: x.map(lambda y: y + '!')).to_list()
2805        ['a!', 'b!', 'c!']
2806        """
2807        return block(self)

Calls the specified function [block] with self value as its argument and returns its result.

Example 1:

>>> it(['a', 'b', 'c']).let(lambda x: x.map(lambda y: y + '!')).to_list()
['a!', 'b!', 'c!']
def also( self, block: Callable[[pyiter.sequence.Sequence[~T]], Any]) -> pyiter.sequence.Sequence[~T]:
2809    def also(self, block: Callable[[Sequence[T]], Any]) -> Sequence[T]:
2810        """
2811        Calls the specified function [block] with `self` value as its argument and returns `self` value.
2812
2813        Example 1:
2814        >>> it(['a', 'b', 'c']).also(lambda x: x.map(lambda y: y + '!')).to_list()
2815        ['a', 'b', 'c']
2816        """
2817        block(self)
2818        return self

Calls the specified function [block] with self value as its argument and returns self value.

Example 1:

>>> it(['a', 'b', 'c']).also(lambda x: x.map(lambda y: y + '!')).to_list()
['a', 'b', 'c']
size: int

Returns the size of the given Sequence.

def is_empty(self) -> bool:
2827    def is_empty(self) -> bool:
2828        """
2829        Returns True if the Sequence is empty, False otherwise.
2830
2831        Example 1:
2832        >>> it(['a', 'b', 'c']).is_empty()
2833        False
2834
2835        Example 2:
2836        >>> it([None]).is_empty()
2837        False
2838
2839        Example 3:
2840        >>> it([]).is_empty()
2841        True
2842        """
2843        return id(self.first_or_default(self)) == id(self)

Returns True if the Sequence is empty, False otherwise.

Example 1:

>>> it(['a', 'b', 'c']).is_empty()
False

Example 2:

>>> it([None]).is_empty()
False

Example 3:

>>> it([]).is_empty()
True
def iter(self) -> Iterator[~T]:
2848    def iter(self) -> Iterator[T]:
2849        return self.__do_iter__()
class AutoIncrementIndex:
2901class AutoIncrementIndex:
2902    idx = 0
2903
2904    def __call__(self) -> int:
2905        val = self.idx
2906        self.idx += 1
2907        return val
idx = 0
class IndexedValue(typing.NamedTuple, typing.Generic[~T]):
2910class IndexedValue(NamedTuple, Generic[T]):
2911    val: T
2912    idx: int
2913
2914    def __repr__(self) -> str:
2915        return f"IndexedValue({self.idx}, {self.val})"

IndexedValue(val, idx)

IndexedValue(val: ForwardRef('T'), idx: int)

Create new instance of IndexedValue(val, idx)

val: ~T

Alias for field number 0

idx: int

Alias for field number 1

Inherited Members
builtins.tuple
index
count
def throw(exception: Exception) -> Any:
2918def throw(exception: Exception) -> Any:
2919    raise exception
def none_or(value: Optional[~T], default: ~T) -> ~T:
2922def none_or(value: Optional[T], default: T) -> T:
2923    return value if value is not None else default
def none_or_else(value: Optional[~T], f: Callable[[], ~T]) -> ~T:
2926def none_or_else(value: Optional[T], f: Callable[[], T]) -> T:
2927    return value if value is not None else f()
def is_debugging() -> bool:
2930def is_debugging() -> bool:
2931    from inspect import currentframe
2932    from traceback import walk_stack
2933
2934    return (
2935        it(walk_stack(currentframe()))
2936        .take(20)
2937        .map(lambda s: s[0])
2938        .any(
2939            lambda s: s.f_code.co_name == "get_contents_debug_adapter_protocol"
2940            and "pydevd_resolver.py" in s.f_code.co_filename
2941        )
2942    )
class SequenceProducer:
2945class SequenceProducer:
2946    @overload
2947    def __call__(self, elements: List[T]) -> Sequence[T]: ...
2948    @overload
2949    def __call__(self, elements: Iterable[T]) -> Sequence[T]: ...
2950    @overload
2951    def __call__(self, *elements: T) -> Sequence[T]: ...
2952    def __call__(self, *iterable: Union[Iterable[T], List[T], T]) -> Sequence[T]:  # type: ignore
2953        if len(iterable) == 1:
2954            iter = iterable[0]
2955            if isinstance(iter, Sequence):
2956                return iter  # type: ignore
2957            if isinstance(iter, Iterable) and not isinstance(iter, str):
2958                return Sequence(iter)  # type: ignore
2959        return Sequence(iterable)  # type: ignore
2960
2961    def json(self, filepath: str, **kwargs: Dict[str, Any]) -> Sequence[Any]:
2962        """
2963        Reads and parses the input of a json file.
2964        """
2965        import json
2966
2967        with open(filepath, "r") as f:
2968            data = json.load(f, **kwargs)  # type: ignore
2969            return self(data)
2970
2971    def csv(self, filepath: str):
2972        """
2973        Reads and parses the input of a csv file.
2974        """
2975        return self.read_csv(filepath)
2976
2977    def read_csv(self, filepath: str, header: Optional[int] = 0):
2978        """
2979        Reads and parses the input of a csv file.
2980
2981        Example 1:
2982        >>> it.read_csv('tests/data/a.csv').to_list()
2983        [{'a': 'a1', 'b': '1'}, {'a': 'a2', 'b': '2'}]
2984        """
2985        import csv
2986
2987        it = self
2988        with open(filepath) as f:
2989            reader = csv.reader(f)
2990            iter = it(*reader)
2991            if header is None or header < 0:
2992                return iter
2993
2994            headers = iter.element_at_or_none(header)
2995            if headers is not None:
2996                if header == 0:
2997                    iter = iter.skip(1)
2998                else:
2999                    iter = iter.filter(lambda _, i: i != header)
3000
3001                return iter.map(
3002                    lambda row: it(row).associate_by(
3003                        lambda _, ordinal: headers[ordinal]
3004                        if ordinal < len(headers)
3005                        else f"undefined_{ordinal}"
3006                    )
3007                )
3008            return iter
3009
3010    def __repr__(self) -> str:
3011        return __package__ or self.__class__.__name__
def json( self, filepath: str, **kwargs: Dict[str, Any]) -> pyiter.sequence.Sequence[typing.Any]:
2961    def json(self, filepath: str, **kwargs: Dict[str, Any]) -> Sequence[Any]:
2962        """
2963        Reads and parses the input of a json file.
2964        """
2965        import json
2966
2967        with open(filepath, "r") as f:
2968            data = json.load(f, **kwargs)  # type: ignore
2969            return self(data)

Reads and parses the input of a json file.

def csv(self, filepath: str):
2971    def csv(self, filepath: str):
2972        """
2973        Reads and parses the input of a csv file.
2974        """
2975        return self.read_csv(filepath)

Reads and parses the input of a csv file.

def read_csv(self, filepath: str, header: Optional[int] = 0):
2977    def read_csv(self, filepath: str, header: Optional[int] = 0):
2978        """
2979        Reads and parses the input of a csv file.
2980
2981        Example 1:
2982        >>> it.read_csv('tests/data/a.csv').to_list()
2983        [{'a': 'a1', 'b': '1'}, {'a': 'a2', 'b': '2'}]
2984        """
2985        import csv
2986
2987        it = self
2988        with open(filepath) as f:
2989            reader = csv.reader(f)
2990            iter = it(*reader)
2991            if header is None or header < 0:
2992                return iter
2993
2994            headers = iter.element_at_or_none(header)
2995            if headers is not None:
2996                if header == 0:
2997                    iter = iter.skip(1)
2998                else:
2999                    iter = iter.filter(lambda _, i: i != header)
3000
3001                return iter.map(
3002                    lambda row: it(row).associate_by(
3003                        lambda _, ordinal: headers[ordinal]
3004                        if ordinal < len(headers)
3005                        else f"undefined_{ordinal}"
3006                    )
3007                )
3008            return iter

Reads and parses the input of a csv file.

Example 1:

>>> it.read_csv('tests/data/a.csv').to_list()
[{'a': 'a1', 'b': '1'}, {'a': 'a2', 'b': '2'}]
sequence = pyiter

Creates an iterator from a list of elements or given Iterable.

Example 1:
>>> sequence('hello', 'world').map(lambda x: x.upper()).to_list()
['HELLO', 'WORLD']
Example 2:
>>> sequence(['hello', 'world']).map(lambda x: x.upper()).to_list()
['HELLO', 'WORLD']
Example 3:
>>> sequence(range(10)).map(lambda x: x*x).to_list()
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
seq = pyiter

Creates an iterator from a list of elements or given Iterable.

Example 1:
>>> seq('hello', 'world').map(lambda x: x.upper()).to_list()
['HELLO', 'WORLD']
Example 2:
>>> seq(['hello', 'world']).map(lambda x: x.upper()).to_list()
['HELLO', 'WORLD']
Example 3:
>>> seq(range(10)).map(lambda x: x*x).to_list()
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
it = pyiter

Creates an iterator from a list of elements or given Iterable.

Example 1:
>>> it('hello', 'world').map(lambda x: x.upper()).to_list()
['HELLO', 'WORLD']
Example 2:
>>> it(['hello', 'world']).map(lambda x: x.upper()).to_list()
['HELLO', 'WORLD']
Example 3:
>>> it(range(10)).map(lambda x: x*x).to_list()
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]