iterquarry 2.1.1__py3-none-any.whl

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.
iterquarry/__init__.py ADDED
@@ -0,0 +1,373 @@
1
+ """Extra tools for working with iterables."""
2
+
3
+ from iterquarry.augment import (
4
+ adjacent,
5
+ count_cycle,
6
+ groupby_transform,
7
+ intersperse,
8
+ mark_ends,
9
+ padded,
10
+ repeat_each,
11
+ repeat_last,
12
+ )
13
+ from iterquarry.combo import (
14
+ circular_shifts,
15
+ combination_index,
16
+ combination_with_replacement_index,
17
+ derangements,
18
+ distinct_combinations,
19
+ distinct_permutations,
20
+ gray_product,
21
+ nth_combination_with_replacement,
22
+ nth_permutation,
23
+ nth_product,
24
+ outer_product,
25
+ partitions,
26
+ permutation_index,
27
+ powerset_of_sets,
28
+ product_index,
29
+ set_partitions,
30
+ )
31
+ from iterquarry.combine import (
32
+ collapse,
33
+ interleave,
34
+ interleave_evenly,
35
+ interleave_longest,
36
+ interleave_randomly,
37
+ partial_product,
38
+ sort_together,
39
+ value_chain,
40
+ zip_broadcast,
41
+ zip_offset,
42
+ )
43
+ from iterquarry.concurrency import concurrent_tee, serialize, synchronized
44
+ from iterquarry.grouping import (
45
+ batched,
46
+ bucket,
47
+ chunked,
48
+ chunked_even,
49
+ constrained_batches,
50
+ distribute,
51
+ divide,
52
+ ichunked,
53
+ sliced,
54
+ split_after,
55
+ split_at,
56
+ split_before,
57
+ split_into,
58
+ split_when,
59
+ unzip,
60
+ )
61
+ from iterquarry.lookahead import peekable, seekable, spy
62
+ from iterquarry.numeric import (
63
+ Stats,
64
+ dft,
65
+ idft,
66
+ nth_prime,
67
+ numeric_range,
68
+ running_max,
69
+ running_mean,
70
+ running_median,
71
+ running_min,
72
+ running_statistics,
73
+ )
74
+ from iterquarry.other import (
75
+ difference,
76
+ doublestarmap,
77
+ iterate,
78
+ locate,
79
+ make_decorator,
80
+ map_if,
81
+ raise_,
82
+ replace,
83
+ rlocate,
84
+ side_effect,
85
+ time_limited,
86
+ )
87
+ from iterquarry.recipes import (
88
+ all_equal,
89
+ before_and_after,
90
+ consume,
91
+ convolve,
92
+ dotproduct,
93
+ factor,
94
+ first_true,
95
+ flatten,
96
+ grouper,
97
+ is_prime,
98
+ iter_except,
99
+ iter_index,
100
+ loops,
101
+ matmul,
102
+ multinomial,
103
+ ncycles,
104
+ nth,
105
+ nth_combination,
106
+ pad_none,
107
+ padnone,
108
+ pairwise,
109
+ partition,
110
+ polynomial_derivative,
111
+ polynomial_eval,
112
+ polynomial_from_roots,
113
+ powerset,
114
+ prepend,
115
+ quantify,
116
+ random_combination,
117
+ random_combination_with_replacement,
118
+ random_derangement,
119
+ random_permutation,
120
+ random_product,
121
+ repeatfunc,
122
+ reshape,
123
+ roundrobin,
124
+ sieve,
125
+ sliding_window,
126
+ subslices,
127
+ sum_of_squares,
128
+ tabulate,
129
+ tail,
130
+ take,
131
+ totient,
132
+ transpose,
133
+ triplewise,
134
+ unique,
135
+ unique_everseen,
136
+ unique_justseen,
137
+ )
138
+ from iterquarry.select import (
139
+ classify_unique,
140
+ duplicates_everseen,
141
+ duplicates_justseen,
142
+ extract,
143
+ filter_except,
144
+ filter_map,
145
+ first,
146
+ islice_extended,
147
+ iter_suppress,
148
+ last,
149
+ longest_common_prefix,
150
+ lstrip,
151
+ map_except,
152
+ nth_or_last,
153
+ one,
154
+ only,
155
+ rstrip,
156
+ strictly_n,
157
+ strip,
158
+ takewhile_inclusive,
159
+ unique_in_window,
160
+ )
161
+ from iterquarry.summarize import (
162
+ all_unique,
163
+ argmax,
164
+ argmin,
165
+ consecutive_groups,
166
+ exactly_n,
167
+ iequals,
168
+ ilen,
169
+ is_sorted,
170
+ join_mappings,
171
+ map_reduce,
172
+ minmax,
173
+ run_length,
174
+ sample,
175
+ unique_to_each,
176
+ )
177
+ from iterquarry.windowing import (
178
+ stagger,
179
+ substrings,
180
+ substrings_indexes,
181
+ windowed,
182
+ windowed_complete,
183
+ )
184
+ from iterquarry.wrapping import (
185
+ AbortThread,
186
+ SequenceView,
187
+ always_iterable,
188
+ always_reversible,
189
+ callback_iter,
190
+ consumer,
191
+ countable,
192
+ sized_iterator,
193
+ with_iter,
194
+ )
195
+
196
+ __version__ = "2.1.1"
197
+
198
+ __all__ = [
199
+ "AbortThread",
200
+ "SequenceView",
201
+ "Stats",
202
+ "adjacent",
203
+ "all_equal",
204
+ "all_unique",
205
+ "always_iterable",
206
+ "always_reversible",
207
+ "argmax",
208
+ "argmin",
209
+ "batched",
210
+ "before_and_after",
211
+ "bucket",
212
+ "callback_iter",
213
+ "chunked",
214
+ "chunked_even",
215
+ "circular_shifts",
216
+ "classify_unique",
217
+ "collapse",
218
+ "combination_index",
219
+ "combination_with_replacement_index",
220
+ "concurrent_tee",
221
+ "consecutive_groups",
222
+ "constrained_batches",
223
+ "consume",
224
+ "consumer",
225
+ "convolve",
226
+ "count_cycle",
227
+ "countable",
228
+ "derangements",
229
+ "dft",
230
+ "difference",
231
+ "distinct_combinations",
232
+ "distinct_permutations",
233
+ "distribute",
234
+ "divide",
235
+ "dotproduct",
236
+ "doublestarmap",
237
+ "duplicates_everseen",
238
+ "duplicates_justseen",
239
+ "exactly_n",
240
+ "extract",
241
+ "factor",
242
+ "filter_except",
243
+ "filter_map",
244
+ "first",
245
+ "first_true",
246
+ "flatten",
247
+ "gray_product",
248
+ "grouper",
249
+ "groupby_transform",
250
+ "ichunked",
251
+ "idft",
252
+ "iequals",
253
+ "ilen",
254
+ "interleave",
255
+ "interleave_evenly",
256
+ "interleave_longest",
257
+ "interleave_randomly",
258
+ "intersperse",
259
+ "is_prime",
260
+ "is_sorted",
261
+ "islice_extended",
262
+ "iter_except",
263
+ "iter_index",
264
+ "iter_suppress",
265
+ "iterate",
266
+ "join_mappings",
267
+ "last",
268
+ "locate",
269
+ "longest_common_prefix",
270
+ "loops",
271
+ "lstrip",
272
+ "make_decorator",
273
+ "map_except",
274
+ "map_if",
275
+ "map_reduce",
276
+ "mark_ends",
277
+ "matmul",
278
+ "minmax",
279
+ "multinomial",
280
+ "ncycles",
281
+ "nth",
282
+ "nth_combination",
283
+ "nth_combination_with_replacement",
284
+ "nth_or_last",
285
+ "nth_permutation",
286
+ "nth_prime",
287
+ "nth_product",
288
+ "numeric_range",
289
+ "one",
290
+ "only",
291
+ "outer_product",
292
+ "pad_none",
293
+ "padded",
294
+ "padnone",
295
+ "pairwise",
296
+ "partial_product",
297
+ "partition",
298
+ "partitions",
299
+ "peekable",
300
+ "permutation_index",
301
+ "polynomial_derivative",
302
+ "polynomial_eval",
303
+ "polynomial_from_roots",
304
+ "powerset",
305
+ "powerset_of_sets",
306
+ "prepend",
307
+ "product_index",
308
+ "quantify",
309
+ "raise_",
310
+ "random_combination",
311
+ "random_combination_with_replacement",
312
+ "random_derangement",
313
+ "random_permutation",
314
+ "random_product",
315
+ "repeat_each",
316
+ "repeat_last",
317
+ "repeatfunc",
318
+ "replace",
319
+ "reshape",
320
+ "rlocate",
321
+ "roundrobin",
322
+ "rstrip",
323
+ "run_length",
324
+ "running_max",
325
+ "running_mean",
326
+ "running_median",
327
+ "running_min",
328
+ "running_statistics",
329
+ "sample",
330
+ "seekable",
331
+ "serialize",
332
+ "set_partitions",
333
+ "side_effect",
334
+ "sieve",
335
+ "sized_iterator",
336
+ "sliced",
337
+ "sliding_window",
338
+ "sort_together",
339
+ "split_after",
340
+ "split_at",
341
+ "split_before",
342
+ "split_into",
343
+ "split_when",
344
+ "spy",
345
+ "stagger",
346
+ "strictly_n",
347
+ "strip",
348
+ "subslices",
349
+ "substrings",
350
+ "substrings_indexes",
351
+ "sum_of_squares",
352
+ "synchronized",
353
+ "tabulate",
354
+ "tail",
355
+ "take",
356
+ "takewhile_inclusive",
357
+ "time_limited",
358
+ "totient",
359
+ "transpose",
360
+ "triplewise",
361
+ "unique",
362
+ "unique_everseen",
363
+ "unique_in_window",
364
+ "unique_justseen",
365
+ "unique_to_each",
366
+ "unzip",
367
+ "value_chain",
368
+ "windowed",
369
+ "windowed_complete",
370
+ "with_iter",
371
+ "zip_broadcast",
372
+ "zip_offset",
373
+ ]
iterquarry/augment.py ADDED
@@ -0,0 +1,130 @@
1
+ """Add context to the items of an iterable."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from collections import deque
6
+ from collections.abc import Iterable
7
+ from itertools import count, groupby, islice, repeat
8
+
9
+ __all__ = [
10
+ "adjacent",
11
+ "count_cycle",
12
+ "groupby_transform",
13
+ "intersperse",
14
+ "mark_ends",
15
+ "ncycles",
16
+ "pad_none",
17
+ "padded",
18
+ "repeat_each",
19
+ "repeat_last",
20
+ ]
21
+
22
+
23
+ def count_cycle(iterable: Iterable, n: int | None = None):
24
+ """Yield ``(cycle_number, item)`` while cycling through *iterable*."""
25
+ sequence = tuple(iterable)
26
+ if not sequence:
27
+ return
28
+ cycles = count() if n is None else range(n)
29
+ for cycle_number in cycles:
30
+ for item in sequence:
31
+ yield cycle_number, item
32
+
33
+
34
+ def intersperse(e, iterable: Iterable, n: int = 1):
35
+ """Insert *e* between items, leaving *n* items between separators."""
36
+ if n < 1:
37
+ raise ValueError("n must be at least one")
38
+ iterator = iter(iterable)
39
+ try:
40
+ yield next(iterator)
41
+ except StopIteration:
42
+ return
43
+ for index, item in enumerate(iterator, 1):
44
+ if index % n == 0:
45
+ yield e
46
+ yield item
47
+
48
+
49
+ def padded(iterable: Iterable, fillvalue=None, n: int | None = None, next_multiple: bool = False):
50
+ """Yield the items, then *fillvalue* until at least *n* items have been produced."""
51
+ count_emitted = 0
52
+ for item in iterable:
53
+ yield item
54
+ count_emitted += 1
55
+ if n is None:
56
+ yield from repeat(fillvalue)
57
+ return
58
+ if n < 1:
59
+ raise ValueError("n must be at least one")
60
+ if next_multiple:
61
+ target = ((count_emitted + n - 1) // n) * n
62
+ else:
63
+ target = n
64
+ if count_emitted < target:
65
+ yield from repeat(fillvalue, target - count_emitted)
66
+
67
+
68
+ def mark_ends(iterable: Iterable):
69
+ """Yield ``(is_first, is_last, item)``."""
70
+ iterator = iter(iterable)
71
+ try:
72
+ previous = next(iterator)
73
+ except StopIteration:
74
+ return
75
+ first = True
76
+ for item in iterator:
77
+ yield first, False, previous
78
+ first = False
79
+ previous = item
80
+ yield first, True, previous
81
+
82
+
83
+ def repeat_each(iterable: Iterable, n: int = 2):
84
+ """Repeat each item *n* times."""
85
+ if n < 0:
86
+ raise ValueError("n must be >= 0")
87
+ for item in iterable:
88
+ for _ in range(n):
89
+ yield item
90
+
91
+
92
+ def repeat_last(iterable: Iterable, default=None):
93
+ """Yield the items, then repeat the last one forever."""
94
+ item = default
95
+ for item in iterable:
96
+ yield item
97
+ yield from repeat(item)
98
+
99
+
100
+ def adjacent(predicate, iterable: Iterable, distance: int = 1):
101
+ """Yield ``(near_match, item)`` where *near_match* covers *distance* neighbors."""
102
+ if distance < 0:
103
+ raise ValueError("distance must be >= 0")
104
+ iterator = iter(iterable)
105
+ flags = deque([False] * distance, maxlen=distance * 2 + 1)
106
+ items = deque()
107
+ for item in iterator:
108
+ flags.append(bool(predicate(item)))
109
+ items.append(item)
110
+ if len(flags) == distance * 2 + 1:
111
+ yield any(flags), items.popleft()
112
+ for _ in range(distance):
113
+ if not items:
114
+ break
115
+ flags.append(False)
116
+ yield any(flags), items.popleft()
117
+
118
+
119
+ def groupby_transform(iterable: Iterable, keyfunc=None, valuefunc=None, reducefunc=None):
120
+ """Group adjacent items and optionally transform the keys, values, and groups."""
121
+ if keyfunc is None:
122
+ keyfunc = lambda item: item
123
+ if valuefunc is None:
124
+ valuefunc = lambda item: item
125
+ for key, group in groupby(iterable, keyfunc):
126
+ mapped = (valuefunc(item) for item in group)
127
+ if reducefunc is None:
128
+ yield key, mapped
129
+ else:
130
+ yield key, reducefunc(mapped)