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 +373 -0
- iterquarry/augment.py +130 -0
- iterquarry/combine.py +231 -0
- iterquarry/combo.py +353 -0
- iterquarry/concurrency.py +65 -0
- iterquarry/grouping.py +366 -0
- iterquarry/lookahead.py +166 -0
- iterquarry/numeric.py +253 -0
- iterquarry/other.py +209 -0
- iterquarry/recipes.py +599 -0
- iterquarry/select.py +381 -0
- iterquarry/summarize.py +292 -0
- iterquarry/windowing.py +105 -0
- iterquarry/wrapping.py +196 -0
- iterquarry-2.1.1.dist-info/METADATA +482 -0
- iterquarry-2.1.1.dist-info/RECORD +19 -0
- iterquarry-2.1.1.dist-info/WHEEL +5 -0
- iterquarry-2.1.1.dist-info/licenses/LICENSE +21 -0
- iterquarry-2.1.1.dist-info/top_level.txt +1 -0
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)
|