Skip to content

Commit

Permalink
✨ add unzip
Browse files Browse the repository at this point in the history
  • Loading branch information
mokeyish committed Aug 17, 2023
1 parent aa277a7 commit 394b980
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 4 deletions.
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@

setup(
name='pyiter',
version='0.2.7',
version='0.3.2',
keywords=('linq', 'iterator', 'typing', 'lazy evaluation', 'type inference'),
description='PyIter is a Python package for iterative operations inspired by the Kotlin、CSharp(linq)、TypeSrcipt '
'and Rust . Enables strong typing and type inference for iterative operations.',
long_description=long_description,
long_description_content_type="text/markdown",
author='YISH',
author_email="mokeyish@hotmail.com",
url= 'https://github.com/mokeyish/pyiter',
package_dir={'': 'src'},
packages=find_packages(where='src'),
license='MIT',
Expand Down
94 changes: 91 additions & 3 deletions src/pyiter/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -1500,6 +1500,55 @@ def zip_with_next(self, transform: Optional[Callable[[T, T], V]]=None) -> Tuple[
"""
return MergingWithNextSequence(self, transform or (lambda a, b: (a, b)))


@overload
def unzip(self: Sequence[Tuple[R, V]], as_sequence: Literal[True]) -> Tuple[Sequence[R], Sequence[V]] :
...
@overload
def unzip(self: Sequence[Tuple[R, V]]) -> Tuple[List[R], List[V]]:
...
@overload
def unzip(self, transform: Optional[Callable[[T], Tuple[R, V]]], as_sequence: Literal[True]) -> Tuple[Sequence[R], Sequence[V]]:
...
@overload
def unzip(self, transform: Optional[Callable[[T], Tuple[R, V]]]) -> Tuple[List[R], List[V]]:
...
def unzip(self, transform: Union[Optional[Callable[[T], Tuple[R, V]]], bool]=None, as_sequence: bool=False):
"""
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]
"""
it = self
if type(transform) == bool:
as_sequence = transform
transform = None

if transform is not None:
it = it.map(transform)

a = it.map(lambda x: x[0])
b = it.map(lambda x: x[1])

if not as_sequence:
return a.to_list(), b.to_list()
return a, b


def with_index(self):
"""
Returns a sequence containing the elements of this sequence and their indexes.
Expand Down Expand Up @@ -1564,6 +1613,32 @@ def shuffled(self, random: Optional[Union[Random, str, int]]=None) -> Sequence[T
"""
return ShufflingSequence(self, random)

@overload
def partition(self, predicate: Callable[[T], bool]) -> Tuple[List[T], List[T]]:
"""
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'])
"""
...
@overload
def partition(self, predicate: Callable[[T], bool], as_sequence: Literal[True]) -> Tuple[Sequence[T], Sequence[T]]:
"""
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(), as_sequence=True)
(['a', 'b', 'c'], ['2'])
"""
...
def partition(self, predicate: Callable[[T], bool], as_sequence: bool=False) -> Tuple[Sequence[T], Sequence[T]]:
"""
Partitions the elements of the given Sequence into two groups,
Expand All @@ -1578,8 +1653,7 @@ def partition(self, predicate: Callable[[T], bool], as_sequence: bool=False) ->
part_a = self.filter(predicate)
part_b = self.filter(lambda x: not predicate(x))
if not as_sequence:
part_a = part_a.to_list()
part_b = part_b.to_list()
return part_a.to_list(), part_b.to_list()
return part_a, part_b


Expand Down Expand Up @@ -1693,6 +1767,7 @@ def join(self, separator: str = ' ') -> str:
"""
return separator.join(self)


def progress(self, progress_func: Callable[[Iterable[T]], Iterable[T]]) -> Sequence[T]:
"""
Returns a Sequence that enable a progress bar for the given Sequence.
Expand All @@ -1705,6 +1780,7 @@ def progress(self, progress_func: Callable[[Iterable[T]], Iterable[T]]) -> Seque
"""
return ProgressSequence(self, progress_func)


def to_set(self) -> Set[T]:
"""
Returns a set containing all elements of this Sequence.
Expand All @@ -1715,18 +1791,30 @@ def to_set(self) -> Set[T]:
"""
return set(self)


@overload
def to_dict(self: Sequence[Tuple[K, V]]) -> Dict[K, V]:
...
@overload
def to_dict(self, transform: Callable[[T], Tuple[K, V]]) -> Dict[K, V]:
...
def to_dict(self, transform: Optional[Callable[[T], Tuple[K, V]]]=None) -> Dict[K, V]:
"""
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'}
"""
return self.associate(transform)
return self.associate(transform or (lambda x: x))

def to_list(self) -> List[T]:
"""
Expand Down

0 comments on commit 394b980

Please sign in to comment.