python-iterutils 0.1.0__tar.gz → 0.1.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_iterutils-0.1.0 → python_iterutils-0.1.2}/PKG-INFO +1 -1
- {python_iterutils-0.1.0 → python_iterutils-0.1.2}/iterutils/__init__.py +96 -5
- {python_iterutils-0.1.0 → python_iterutils-0.1.2}/pyproject.toml +1 -1
- {python_iterutils-0.1.0 → python_iterutils-0.1.2}/LICENSE +0 -0
- {python_iterutils-0.1.0 → python_iterutils-0.1.2}/iterutils/py.typed +0 -0
- {python_iterutils-0.1.0 → python_iterutils-0.1.2}/readme.md +0 -0
|
@@ -2,19 +2,21 @@
|
|
|
2
2
|
# encoding: utf-8
|
|
3
3
|
|
|
4
4
|
__author__ = "ChenyangGao <https://chenyanggao.github.io>"
|
|
5
|
-
__version__ = (0, 1,
|
|
5
|
+
__version__ = (0, 1, 2)
|
|
6
6
|
__all__ = [
|
|
7
|
-
"
|
|
8
|
-
"
|
|
9
|
-
"
|
|
7
|
+
"Return", "Yield", "YieldFrom", "iterable", "async_iterable", "foreach", "async_foreach",
|
|
8
|
+
"through", "async_through", "flatten", "async_flatten", "iter_unique", "async_iter_unique",
|
|
9
|
+
"chunked", "wrap_iter", "wrap_aiter", "acc_step", "cut_iter", "run_gen_step",
|
|
10
|
+
"run_gen_step_iter", "bfs_gen",
|
|
10
11
|
]
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
from abc import ABC, abstractmethod
|
|
14
15
|
from asyncio import to_thread
|
|
16
|
+
from collections import deque
|
|
15
17
|
from collections.abc import (
|
|
16
18
|
AsyncIterable, AsyncIterator, Buffer, Callable, Generator,
|
|
17
|
-
Iterable, Iterator, Sequence,
|
|
19
|
+
Iterable, Iterator, MutableSet, Sequence,
|
|
18
20
|
)
|
|
19
21
|
from dataclasses import dataclass
|
|
20
22
|
from itertools import batched, pairwise
|
|
@@ -174,6 +176,53 @@ async def async_flatten(
|
|
|
174
176
|
yield e
|
|
175
177
|
|
|
176
178
|
|
|
179
|
+
@overload
|
|
180
|
+
def iter_unique[T](
|
|
181
|
+
iterable: Iterable[T],
|
|
182
|
+
/,
|
|
183
|
+
seen: None | MutableSet = None,
|
|
184
|
+
) -> Iterator[T]:
|
|
185
|
+
...
|
|
186
|
+
@overload
|
|
187
|
+
def iter_unique[T](
|
|
188
|
+
iterable: AsyncIterable[T],
|
|
189
|
+
/,
|
|
190
|
+
seen: None | MutableSet = None,
|
|
191
|
+
) -> AsyncIterator[T]:
|
|
192
|
+
...
|
|
193
|
+
def iter_unique[T](
|
|
194
|
+
iterable: Iterable[T] | AsyncIterable[T],
|
|
195
|
+
/,
|
|
196
|
+
seen: None | MutableSet = None,
|
|
197
|
+
) -> Iterator[T] | AsyncIterator[T]:
|
|
198
|
+
if not isinstance(iterable, Iterable):
|
|
199
|
+
return async_iter_unique(iterable, seen)
|
|
200
|
+
if seen is None:
|
|
201
|
+
seen = set()
|
|
202
|
+
def gen(iterable):
|
|
203
|
+
add = seen.add
|
|
204
|
+
for e in iterable:
|
|
205
|
+
if e not in seen:
|
|
206
|
+
yield e
|
|
207
|
+
add(e)
|
|
208
|
+
return gen(iterable)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
async def async_iter_unique[T](
|
|
212
|
+
iterable: Iterable[T] | AsyncIterable[T],
|
|
213
|
+
/,
|
|
214
|
+
seen: None | MutableSet = None,
|
|
215
|
+
threaded: bool = False,
|
|
216
|
+
) -> AsyncIterator[T]:
|
|
217
|
+
if seen is None:
|
|
218
|
+
seen = set()
|
|
219
|
+
add = seen.add
|
|
220
|
+
async for e in ensure_aiter(iterable, threaded=threaded):
|
|
221
|
+
if e not in seen:
|
|
222
|
+
yield e
|
|
223
|
+
add(e)
|
|
224
|
+
|
|
225
|
+
|
|
177
226
|
@overload
|
|
178
227
|
def chunked[T](
|
|
179
228
|
iterable: Iterable[T],
|
|
@@ -565,3 +614,45 @@ def run_gen_step_iter(
|
|
|
565
614
|
close()
|
|
566
615
|
return process()
|
|
567
616
|
|
|
617
|
+
|
|
618
|
+
@overload
|
|
619
|
+
def bfs_gen[T](
|
|
620
|
+
initial: T,
|
|
621
|
+
/,
|
|
622
|
+
unpack_iterator: Literal[False] = False,
|
|
623
|
+
) -> Generator[T, T | None, None]:
|
|
624
|
+
...
|
|
625
|
+
@overload
|
|
626
|
+
def bfs_gen[T](
|
|
627
|
+
initial: T | Iterator[T],
|
|
628
|
+
/,
|
|
629
|
+
unpack_iterator: Literal[True],
|
|
630
|
+
) -> Generator[T, T | None, None]:
|
|
631
|
+
...
|
|
632
|
+
def bfs_gen[T](
|
|
633
|
+
initial: T | Iterator[T],
|
|
634
|
+
/,
|
|
635
|
+
unpack_iterator: bool = False,
|
|
636
|
+
) -> Generator[T, T | None, None]:
|
|
637
|
+
"""辅助函数,返回生成器,用来简化广度优先遍历
|
|
638
|
+
"""
|
|
639
|
+
dq: deque[T] = deque()
|
|
640
|
+
push, pushmany, pop = dq.append, dq.extend, dq.popleft
|
|
641
|
+
if isinstance(initial, Iterator) and unpack_iterator:
|
|
642
|
+
pushmany(initial)
|
|
643
|
+
else:
|
|
644
|
+
push(initial) # type: ignore
|
|
645
|
+
while dq:
|
|
646
|
+
args: None | T = yield (val := pop())
|
|
647
|
+
if unpack_iterator:
|
|
648
|
+
while args is not None:
|
|
649
|
+
if isinstance(args, Iterator):
|
|
650
|
+
pushmany(args)
|
|
651
|
+
else:
|
|
652
|
+
push(args)
|
|
653
|
+
args = yield val
|
|
654
|
+
else:
|
|
655
|
+
while args is not None:
|
|
656
|
+
push(args)
|
|
657
|
+
args = yield val
|
|
658
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|