iterquarry 2.1.1__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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2016 iterquarry contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,482 @@
1
+ Metadata-Version: 2.4
2
+ Name: iterquarry
3
+ Version: 2.1.1
4
+ Summary: Python iterable tools: pairwise, chunked batches, sliding windows, flatten, sampling, and combinatorics.
5
+ Author: iterquarry contributors
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://pypi.org/project/iterquarry/
8
+ Keywords: iterable,iterator,itertools,pairwise,chunked,sliding window,flatten,windowed,sampling,combinatorics,permutations,batches
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Topic :: Software Development :: Libraries
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Provides-Extra: test
25
+ Requires-Dist: pytest; extra == "test"
26
+ Dynamic: license-file
27
+
28
+ # iterquarry
29
+
30
+ `iterquarry` is a Python library of extra tools for working with iterables. It sits beside the standard-library `itertools` module and covers the jobs that come up once a loop is no longer enough: fixed-size batches, sliding windows, lookahead, flattening nested data, sampling, combinatorics, and small numeric helpers.
31
+
32
+ The public functions are plain callables. Import the names you need:
33
+
34
+ ```python
35
+ from iterquarry import pairwise, chunked, windowed
36
+
37
+ list(pairwise("ABCDE"))
38
+ # [('A', 'B'), ('B', 'C'), ('C', 'D'), ('D', 'E')]
39
+ ```
40
+
41
+ Version 2.1.1 requires Python 3.10 or newer and has no third-party dependencies. The license is MIT.
42
+
43
+ ## Installation
44
+
45
+ Install the release from PyPI:
46
+
47
+ ```bash
48
+ pip install iterquarry
49
+ ```
50
+
51
+ For a local checkout, install the package in editable mode together with the test extra:
52
+
53
+ ```bash
54
+ pip install -e ".[test]"
55
+ ```
56
+
57
+ ## What it is for
58
+
59
+ Most of the library yields values lazily. You can pass a generator, a file, or any other iterable, and work starts only when you iterate the result. A few tools need random access or a known length, and those accept a sequence or build a list internally. Each section below says when that happens.
60
+
61
+ Typical uses:
62
+
63
+ - Walk a sequence in pairs, triples, or fixed-width windows.
64
+ - Split a stream into batches, or split it where a predicate changes.
65
+ - Peek at the next item, or step back through items you have already seen.
66
+ - Flatten, interleave, zip, and sort several iterables together.
67
+ - Keep the first item, the last item, or exactly one item, and fail clearly when the count is wrong.
68
+ - Sample, count, group, and reduce without writing the bookkeeping by hand.
69
+ - Generate combinations, permutations, partitions, and prime-related sequences.
70
+
71
+ ## Quick start
72
+
73
+ ```python
74
+ from iterquarry import chunked, flatten, windowed
75
+
76
+ list(chunked(range(10), 3))
77
+ # [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
78
+
79
+ list(windowed(range(1, 6), 3))
80
+ # [(1, 2, 3), (2, 3, 4), (3, 4, 5)]
81
+
82
+ list(flatten([[0, 1], [2, 3]]))
83
+ # [0, 1, 2, 3]
84
+ ```
85
+
86
+ `chunked` collects each batch into a list. `windowed` yields tuples and pads a short final window when you pass `fillvalue`. `flatten` removes one level of nesting.
87
+
88
+ ## Grouping and splitting
89
+
90
+ `chunked(iterable, n)` cuts an iterable into lists of length `n`. The last list is shorter when the length does not divide evenly. Pass `strict=True` to raise `ValueError` on a short final batch. `chunked(iterable, None)` returns one list of every item.
91
+
92
+ `chunked_even` keeps the batch sizes as close as possible, with the longer batches first:
93
+
94
+ ```python
95
+ from iterquarry import chunked_even
96
+
97
+ list(chunked_even(range(7), 3))
98
+ # [[0, 1, 2], [3, 4], [5, 6]]
99
+ ```
100
+
101
+ `batched` yields tuples and matches the strictness rules of `itertools.batched` on newer Python versions. `grouper` also builds fixed-width tuples. Its `incomplete` argument is `"fill"`, `"ignore"`, or `"strict"`:
102
+
103
+ ```python
104
+ from iterquarry import grouper
105
+
106
+ list(grouper("ABCDEFG", 3, incomplete="fill", fillvalue="x"))
107
+ # [('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'x', 'x')]
108
+ ```
109
+
110
+ `distribute` deals items out one by one, the way you deal cards. `divide` cuts the iterable into contiguous blocks. `divide` reads the whole iterable first.
111
+
112
+ ```python
113
+ from iterquarry import distribute, divide
114
+
115
+ [list(part) for part in distribute(3, range(8))]
116
+ # [[0, 3, 6], [1, 4, 7], [2, 5]]
117
+
118
+ [list(part) for part in divide(3, range(8))]
119
+ # [[0, 1, 2], [3, 4, 5], [6, 7]]
120
+ ```
121
+
122
+ `split_before`, `split_after`, `split_at`, and `split_when` break an iterable wherever a predicate says so. `split_into` uses an explicit list of sizes.
123
+
124
+ ```python
125
+ from iterquarry import split_before
126
+
127
+ [list(group) for group in split_before("abcdef", lambda char: char in "ce")]
128
+ # [['a', 'b'], ['c', 'd'], ['e', 'f']]
129
+ ```
130
+
131
+ `bucket` files each item under a key and lets you read one key at a time:
132
+
133
+ ```python
134
+ from iterquarry import bucket
135
+
136
+ grouped = bucket("AbBa", key=str.lower)
137
+ list(grouped["a"])
138
+ # ['A', 'a']
139
+ list(grouped["b"])
140
+ # ['b', 'B']
141
+ ```
142
+
143
+ `unzip` is the inverse of `zip`: one iterable of tuples becomes one iterator per column.
144
+
145
+ Other grouping tools: `ichunked`, `sliced`, `constrained_batches`, `groupby_transform`, `consecutive_groups`.
146
+
147
+ ## Windows
148
+
149
+ `pairwise` yields overlapping pairs. `triplewise` yields overlapping triples. `sliding_window` is the general form and yields a tuple of length `n` on every step.
150
+
151
+ ```python
152
+ from iterquarry import sliding_window, triplewise
153
+
154
+ list(triplewise(range(5)))
155
+ # [(0, 1, 2), (1, 2, 3), (2, 3, 4)]
156
+
157
+ list(sliding_window(range(5), 3))
158
+ # [(0, 1, 2), (1, 2, 3), (2, 3, 4)]
159
+ ```
160
+
161
+ `windowed` is the padded variant. Set `step` to move ahead by more than one item, and set `fillvalue` when the tail is shorter than the window. `windowed_complete` yields `(before, window, after)` so you can see the items on both sides of each window.
162
+
163
+ `stagger` zips an iterable with offset copies of itself:
164
+
165
+ ```python
166
+ from iterquarry import stagger
167
+
168
+ list(stagger([1, 2, 3, 4, 5], offsets=(-1, 0, 1), longest=True))
169
+ # [(None, 1, 2), (1, 2, 3), (2, 3, 4), (3, 4, 5), (4, 5, None), (5, None, None)]
170
+ ```
171
+
172
+ `substrings` and `subslices` yield every non-empty contiguous slice. `substrings_indexes` yields `(start, end)` pairs for a sequence. `adjacent` marks each item when it, or a neighbor within `distance`, satisfies a predicate.
173
+
174
+ ## Lookahead
175
+
176
+ `spy` copies the first few items and returns both that copy and an iterator that still starts at the beginning:
177
+
178
+ ```python
179
+ from iterquarry import spy
180
+
181
+ head, remaining = spy("abcdef", 2)
182
+ head
183
+ # ['a', 'b']
184
+ list(remaining)
185
+ # ['a', 'b', 'c', 'd', 'e', 'f']
186
+ ```
187
+
188
+ `peekable` wraps an iterator so you can inspect the next item without consuming it, and put items back with `prepend`:
189
+
190
+ ```python
191
+ from iterquarry import peekable
192
+
193
+ items = peekable("abc")
194
+ items.peek()
195
+ # 'a'
196
+ next(items)
197
+ # 'a'
198
+ list(items)
199
+ # ['b', 'c']
200
+ ```
201
+
202
+ Indexing a `peekable` reads ahead as far as the index requires. A negative index reads the rest of the source.
203
+
204
+ `seekable` remembers the items it has produced and can return to an earlier position with `seek`. A `maxlen` limits how far back that cache reaches. `relative_seek` moves from the current position.
205
+
206
+ ## Combining iterables
207
+
208
+ `flatten` removes one level of nesting. `collapse` keeps going into nested iterables. Strings and bytes stay intact unless you change `base_type`. `levels` stops the collapse after a fixed depth.
209
+
210
+ ```python
211
+ from iterquarry import collapse
212
+
213
+ list(collapse([1, [2, [3, [4]]]]))
214
+ # [1, 2, 3, 4]
215
+ ```
216
+
217
+ `interleave` takes one item from each iterable in turn and stops at the shortest. `interleave_longest` continues until every iterable is exhausted. `roundrobin` does the same with a different internal schedule. `interleave_evenly` spaces shorter iterables through the longest one. `interleave_randomly` picks among the iterables that still have items.
218
+
219
+ ```python
220
+ from iterquarry import interleave, roundrobin
221
+
222
+ list(interleave([1, 2, 3], [4, 5], [6]))
223
+ # [1, 4, 6]
224
+
225
+ list(roundrobin("ABC", "D", "EF"))
226
+ # ['A', 'D', 'E', 'B', 'F', 'C']
227
+ ```
228
+
229
+ `zip_offset` shifts each iterable by a given offset before zipping. `zip_broadcast` repeats strings, bytes, and other scalars across the items of the real iterables. `sort_together` sorts several sequences by one or more columns and returns them in the new order:
230
+
231
+ ```python
232
+ from iterquarry import sort_together, zip_offset
233
+
234
+ list(zip_offset("0123", "abcdef", offsets=(0, 1)))
235
+ # [('0', 'b'), ('1', 'c'), ('2', 'd'), ('3', 'e')]
236
+
237
+ sort_together([["a", "b", "c"], [3, 1, 2]], key_list=(1,))
238
+ # (('b', 'c', 'a'), (1, 2, 3))
239
+ ```
240
+
241
+ `prepend` adds one value at the front. `value_chain` yields its arguments, iterating anything that is not a string or bytes. `partial_product` walks a product space one coordinate at a time. `dotproduct` and `transpose` cover the small linear-algebra cases, and `matmul` multiplies two matrices given as iterables of rows.
242
+
243
+ ## Selecting items
244
+
245
+ `first` and `last` return one end of an iterable. `take` and `tail` return several items. `nth` returns the item at an index, or a default when the iterable ends first. `nth_or_last` returns the last item when the index runs past the end.
246
+
247
+ ```python
248
+ from iterquarry import first, last, tail, take
249
+
250
+ first([1, 2, 3])
251
+ # 1
252
+ last([1, 2, 3])
253
+ # 3
254
+ take(2, "abcde")
255
+ # ['a', 'b']
256
+ list(tail(2, "abcde"))
257
+ # ['d', 'e']
258
+ ```
259
+
260
+ `one` requires exactly one item and raises `ValueError` when the iterable is empty or longer. `only` returns the single item, or a default when the iterable is empty, and raises when there is a second item. `strictly_n` yields exactly `n` items and calls `too_short` or `too_long` when the length differs.
261
+
262
+ `unique_everseen` drops items that have already appeared. `unique_justseen` drops only adjacent duplicates. `unique` sorts, then drops duplicates, so it accepts unhashable items. `duplicates_everseen` and `duplicates_justseen` yield the copies that the unique helpers would drop. `unique_in_window` treats an item as new when it has not appeared in the last `n` items.
263
+
264
+ `locate` yields indexes where a predicate is true. `rlocate` yields those indexes from the right. `replace` substitutes matching items, or matching windows when `window_size` is greater than one.
265
+
266
+ `strip`, `lstrip`, and `rstrip` drop leading or trailing items that match a predicate, the way `str.strip` drops characters. `before_and_after` splits once, at the first failing item, and returns both sides:
267
+
268
+ ```python
269
+ from iterquarry import before_and_after
270
+
271
+ head, rest = before_and_after(lambda value: value < 3, range(6))
272
+ list(head), list(rest)
273
+ # ([0, 1, 2], [3, 4, 5])
274
+ ```
275
+
276
+ `partition` splits into the items that fail a predicate and the items that pass. `filter_except` and `map_except` skip items that raise one of the given exceptions. `iter_suppress` does the same while iterating. `filter_map` keeps values that are true after a function runs. `extract` pulls items at selected indexes. `takewhile_inclusive` keeps the first item that fails the predicate, then stops. `longest_common_prefix` walks several iterables until they disagree.
277
+
278
+ ## Summaries
279
+
280
+ These helpers reduce an iterable to a count, a flag, or a small aggregate.
281
+
282
+ ```python
283
+ from iterquarry import all_equal, ilen, quantify
284
+
285
+ ilen(range(5))
286
+ # 5
287
+ quantify([1, 0, 2, 0, 3])
288
+ # 3
289
+ all_equal([2, 2, 2])
290
+ # True
291
+ ```
292
+
293
+ `all_unique` reports whether every item is distinct. `is_sorted` checks order, with `strict=True` when equal neighbors should fail. `exactly_n` is true when exactly `n` items satisfy a predicate. `iequals` compares several iterables item by item. `minmax` returns the smallest and largest value in one pass. `argmin` and `argmax` return the index of the extreme value.
294
+
295
+ `sample` draws `k` items. It supports `weights`, `counts`, and `strict`. The draw uses the `random` module, so successive calls differ. `run_length.encode` compresses adjacent repeats, and `run_length.decode` expands them:
296
+
297
+ ```python
298
+ from iterquarry import run_length
299
+
300
+ list(run_length.encode("aaabbca"))
301
+ # [('a', 3), ('b', 2), ('c', 1), ('a', 1)]
302
+ ```
303
+
304
+ `consecutive_groups` groups values that increase by one. `map_reduce` groups by a key, maps each item, and optionally reduces each group. `join_mappings` merges dictionaries that share keys. `unique_to_each` lists the items that appear in only one of several iterables.
305
+
306
+ ## Adding information to a stream
307
+
308
+ `mark_ends` tags the first and last items:
309
+
310
+ ```python
311
+ from iterquarry import mark_ends
312
+
313
+ list(mark_ends("ABC"))
314
+ # [(True, False, 'A'), (False, False, 'B'), (False, True, 'C')]
315
+ ```
316
+
317
+ `count_cycle` pairs each item with a cycle counter. `intersperse` inserts a separator every `n` items. `padded` extends an iterable out to a length, or out to the next multiple of a length. `repeat_each` repeats every item. `repeat_last` yields the final item forever after the source ends. `ncycles` repeats the whole iterable `n` times. `pad_none` is an endless tail of `None`.
318
+
319
+ ```python
320
+ from iterquarry import intersperse, padded, repeat_each
321
+
322
+ list(intersperse("|", "abc"))
323
+ # ['a', '|', 'b', '|', 'c']
324
+ list(padded([1, 2], n=4, fillvalue=0))
325
+ # [1, 2, 0, 0]
326
+ list(repeat_each("AB", 2))
327
+ # ['A', 'A', 'B', 'B']
328
+ ```
329
+
330
+ `classify_unique` yields `(item, unique_just_seen, unique_ever_seen)` so a single pass can answer both duplicate questions.
331
+
332
+ ## Combinatorics
333
+
334
+ `powerset` yields every subset, shortest first. `distinct_permutations` and `distinct_combinations` skip results that look the same because of repeated values. `circular_shifts` rotates a sequence. `partitions` splits a sequence into contiguous blocks. `set_partitions` splits it into unordered groups.
335
+
336
+ ```python
337
+ from iterquarry import circular_shifts, distinct_permutations, powerset, set_partitions
338
+
339
+ list(powerset("AB"))
340
+ # [(), ('A',), ('B',), ('A', 'B')]
341
+
342
+ list(distinct_permutations("AAB"))
343
+ # [('A', 'A', 'B'), ('A', 'B', 'A'), ('B', 'A', 'A')]
344
+
345
+ list(circular_shifts("ABCD"))
346
+ # [('A', 'B', 'C', 'D'), ('B', 'C', 'D', 'A'), ('C', 'D', 'A', 'B'), ('D', 'A', 'B', 'C')]
347
+
348
+ list(set_partitions("abc", 2))
349
+ # [[['a'], ['b', 'c']], [['a', 'b'], ['c']], [['b'], ['a', 'c']]]
350
+ ```
351
+
352
+ `gray_product` walks a product so that only one coordinate changes at each step. `derangements` yields permutations with no item left in its original place. `outer_product` applies a function to every pair from two iterables. `powerset_of_sets` builds the power set with set objects.
353
+
354
+ When you need one result by index, use `nth_combination`, `nth_combination_with_replacement`, `nth_permutation`, or `nth_product`. The matching `combination_index`, `combination_with_replacement_index`, `permutation_index`, and `product_index` functions go the other way. `random_product`, `random_permutation`, `random_combination`, `random_combination_with_replacement`, and `random_derangement` each return one result.
355
+
356
+ ```python
357
+ from iterquarry import gray_product, nth_combination
358
+
359
+ list(gray_product("AB", "CD"))
360
+ # [('A', 'C'), ('B', 'C'), ('B', 'D'), ('A', 'D')]
361
+
362
+ nth_combination(range(5), 3, 5)
363
+ # (0, 3, 4)
364
+ ```
365
+
366
+ ## Numeric helpers
367
+
368
+ `numeric_range` follows the same start, stop, and step pattern as `range`, for any numeric type that supports addition and comparison. That includes `Decimal`, `Fraction`, and `datetime` values. A datetime range needs an explicit `timedelta` step.
369
+
370
+ ```python
371
+ import datetime
372
+ from decimal import Decimal
373
+ from iterquarry import numeric_range
374
+
375
+ list(numeric_range(Decimal("1.0"), Decimal("2.0"), Decimal("0.3")))
376
+ # [Decimal('1.0'), Decimal('1.3'), Decimal('1.6'), Decimal('1.9')]
377
+
378
+ start = datetime.date(2026, 1, 1)
379
+ step = datetime.timedelta(days=1)
380
+ list(numeric_range(start, start + datetime.timedelta(days=3), step))
381
+ # [datetime.date(2026, 1, 1), datetime.date(2026, 1, 2), datetime.date(2026, 1, 3)]
382
+ ```
383
+
384
+ `running_min`, `running_max`, `running_mean`, and `running_median` yield the statistic of the items seen so far. Pass `maxlen` to keep a sliding window. `running_statistics` yields a frozen `Stats` value with `size`, `minimum`, `median`, `maximum`, and `mean`.
385
+
386
+ ```python
387
+ from iterquarry import running_mean
388
+
389
+ list(running_mean([1, 2, 3, 4]))
390
+ # [1.0, 1.5, 2.0, 2.5]
391
+ ```
392
+
393
+ `difference` yields the first value, then the gap from each item to the one before it. Pass `func` to use a function other than subtraction, or `initial` to set the starting previous value.
394
+
395
+ ```python
396
+ from iterquarry import difference
397
+
398
+ list(difference([10, 20, 30, 45]))
399
+ # [10, 10, 10, 15]
400
+ ```
401
+
402
+ `is_prime`, `factor`, `sieve`, `nth_prime`, and `totient` cover common integer-number tasks. `nth_prime` is zero-based, so `nth_prime(0)` is 2 and `nth_prime(10)` is 31. `multinomial` computes a multinomial coefficient. `convolve` combines a signal with a kernel. `dft` and `idft` are the discrete Fourier transform and its inverse.
403
+
404
+ ```python
405
+ from iterquarry import convolve, factor, is_prime, sieve, totient
406
+
407
+ is_prime(97)
408
+ # True
409
+ list(factor(84))
410
+ # [2, 2, 3, 7]
411
+ list(sieve(20))
412
+ # [2, 3, 5, 7, 11, 13, 17, 19]
413
+ totient(10)
414
+ # 4
415
+ list(convolve([1, -1, -20], [1, -3]))
416
+ # [1, -4, -17, 60]
417
+ ```
418
+
419
+ `sum_of_squares`, `polynomial_from_roots`, `polynomial_derivative`, and `polynomial_eval` are small polynomial helpers. `reshape` rearranges a nested iterable into a new shape.
420
+
421
+ ## Wrappers
422
+
423
+ `always_iterable` returns an iterator for any object. Strings and bytes are treated as single values. `None` becomes an empty iterator.
424
+
425
+ ```python
426
+ from iterquarry import always_iterable
427
+
428
+ list(always_iterable("hi"))
429
+ # ['hi']
430
+ list(always_iterable(None))
431
+ # []
432
+ ```
433
+
434
+ `always_reversible` caches a one-shot iterable so it can be reversed. `countable` counts the items that have been consumed in `items_seen`. `sized_iterator` reports a length that shrinks as you iterate. `consumer` primes a generator that receives values with `send`. `with_iter` iterates a context manager and closes it when iteration finishes. `callback_iter` runs a callback in a background thread and exposes the calls through an iterator. `AbortThread` is the exception used to stop that worker. `SequenceView` is a read-only view of a sequence.
435
+
436
+ ## Other tools
437
+
438
+ `side_effect` calls a function for each item, or for each chunk, and still yields the original items. Optional `before` and `after` hooks run around the iteration. `iterate` yields `start`, `func(start)`, `func(func(start))`, and so on. `time_limited` stops a slow iterable after a number of seconds and records whether it timed out. `make_decorator` turns an iterable tool into a decorator. `map_if` applies one function when a predicate is true and another when it is false. `doublestarmap` calls a function with each mapping unpacked as keyword arguments. `raise_` raises an exception from a point in an iterator pipeline where a `raise` statement is awkward. `consume` advances an iterator and discards the items. `tabulate`, `repeatfunc`, `iter_except`, `iter_index`, and `loops` cover function tables, repeated calls, and exception-driven iteration.
439
+
440
+ `seekable` and `peekable` are the right tools when a pipeline needs to look backward or forward. `concurrent_tee` copies an iterable out to several threads. `serialize` and `synchronized` take a lock around iteration or around a function.
441
+
442
+ ## API reference
443
+
444
+ | Area | Names |
445
+ | --- | --- |
446
+ | Grouping | `chunked`, `chunked_even`, `batched`, `ichunked`, `sliced`, `constrained_batches`, `distribute`, `divide`, `split_at`, `split_before`, `split_after`, `split_into`, `split_when`, `bucket`, `unzip`, `grouper`, `groupby_transform` |
447
+ | Windows | `pairwise`, `windowed`, `sliding_window`, `triplewise`, `stagger`, `windowed_complete`, `substrings`, `substrings_indexes`, `subslices`, `adjacent` |
448
+ | Lookahead | `spy`, `peekable`, `seekable` |
449
+ | Combining | `flatten`, `collapse`, `interleave`, `interleave_longest`, `interleave_evenly`, `interleave_randomly`, `roundrobin`, `zip_offset`, `zip_broadcast`, `sort_together`, `prepend`, `partial_product`, `value_chain`, `dotproduct`, `transpose`, `matmul` |
450
+ | Selecting | `first`, `last`, `one`, `only`, `nth`, `nth_or_last`, `take`, `tail`, `strip`, `lstrip`, `rstrip`, `unique_everseen`, `unique_justseen`, `unique`, `duplicates_everseen`, `duplicates_justseen`, `unique_in_window`, `locate`, `rlocate`, `replace`, `filter_except`, `map_except`, `filter_map`, `iter_suppress`, `before_and_after`, `takewhile_inclusive`, `strictly_n`, `partition`, `extract`, `longest_common_prefix`, `classify_unique` |
451
+ | Summaries | `ilen`, `sample`, `consecutive_groups`, `run_length`, `map_reduce`, `join_mappings`, `all_equal`, `all_unique`, `quantify`, `minmax`, `argmin`, `argmax`, `is_sorted`, `exactly_n`, `iequals`, `unique_to_each`, `first_true` |
452
+ | Augmenting | `count_cycle`, `intersperse`, `padded`, `pad_none`, `padnone`, `mark_ends`, `repeat_each`, `repeat_last`, `ncycles` |
453
+ | Combinatorics | `powerset`, `powerset_of_sets`, `distinct_permutations`, `distinct_combinations`, `partitions`, `set_partitions`, `circular_shifts`, `derangements`, `gray_product`, `outer_product`, `nth_combination`, `nth_combination_with_replacement`, `nth_permutation`, `nth_product`, `combination_index`, `combination_with_replacement_index`, `permutation_index`, `product_index`, `random_product`, `random_permutation`, `random_combination`, `random_combination_with_replacement`, `random_derangement` |
454
+ | Numbers | `numeric_range`, `difference`, `running_min`, `running_max`, `running_mean`, `running_median`, `running_statistics`, `Stats`, `is_prime`, `factor`, `sieve`, `nth_prime`, `totient`, `multinomial`, `convolve`, `dft`, `idft`, `sum_of_squares`, `polynomial_from_roots`, `polynomial_derivative`, `polynomial_eval`, `reshape` |
455
+ | Wrapping | `always_iterable`, `always_reversible`, `countable`, `sized_iterator`, `consumer`, `with_iter`, `callback_iter`, `AbortThread`, `SequenceView` |
456
+ | Other | `side_effect`, `iterate`, `time_limited`, `make_decorator`, `map_if`, `doublestarmap`, `raise_`, `consume`, `tabulate`, `repeatfunc`, `iter_except`, `iter_index`, `loops`, `concurrent_tee`, `serialize`, `synchronized` |
457
+
458
+ Every name in that table is exported from the top-level package:
459
+
460
+ ```python
461
+ import iterquarry
462
+
463
+ iterquarry.__version__
464
+ # '2.1.1'
465
+ ```
466
+
467
+ ## Development
468
+
469
+ Clone the repository, then install it in editable mode and run the test suite:
470
+
471
+ ```bash
472
+ pip install -e ".[test]"
473
+ pytest
474
+ ```
475
+
476
+ Build source and wheel archives with:
477
+
478
+ ```bash
479
+ python -m build
480
+ ```
481
+
482
+ The archives are written to `dist/`.