@@ -134,7 +134,7 @@ loops that truncate the stream.
134
134
total = func(total, element)
135
135
yield total
136
136
137
- There are a number of uses for the *func * argument. It can be set to
137
+ The *func * argument can be set to
138
138
:func: `min ` for a running minimum, :func: `max ` for a running maximum, or
139
139
:func: `operator.mul ` for a running product. Amortization tables can be
140
140
built by accumulating interest and applying payments:
@@ -184,21 +184,14 @@ loops that truncate the stream.
184
184
>>> unflattened
185
185
[('roses', 'red'), ('violets', 'blue'), ('sugar', 'sweet')]
186
186
187
- >>> for batch in batched(' ABCDEFG' , 3 ):
188
- ... print (batch)
189
- ...
190
- ('A', 'B', 'C')
191
- ('D', 'E', 'F')
192
- ('G',)
193
-
194
187
Roughly equivalent to::
195
188
196
189
def batched(iterable, n, *, strict=False):
197
190
# batched('ABCDEFG', 3) → ABC DEF G
198
191
if n < 1:
199
192
raise ValueError('n must be at least one')
200
- it = iter(iterable)
201
- while batch := tuple(islice(it , n)):
193
+ iterable = iter(iterable)
194
+ while batch := tuple(islice(iterable , n)):
202
195
if strict and len(batch) != n:
203
196
raise ValueError('batched(): incomplete batch')
204
197
yield batch
@@ -237,13 +230,13 @@ loops that truncate the stream.
237
230
238
231
Return *r * length subsequences of elements from the input *iterable *.
239
232
240
- The combination tuples are emitted in lexicographic ordering according to
233
+ The combination tuples are emitted in lexicographic order according to
241
234
the order of the input *iterable *. So, if the input *iterable * is sorted,
242
235
the output tuples will be produced in sorted order.
243
236
244
237
Elements are treated as unique based on their position, not on their
245
- value. So if the input elements are unique, there will be no repeated
246
- values in each combination.
238
+ value. So, if the input elements are unique, there will be no repeated
239
+ values within each combination.
247
240
248
241
Roughly equivalent to::
249
242
@@ -286,12 +279,12 @@ loops that truncate the stream.
286
279
Return *r * length subsequences of elements from the input *iterable *
287
280
allowing individual elements to be repeated more than once.
288
281
289
- The combination tuples are emitted in lexicographic ordering according to
282
+ The combination tuples are emitted in lexicographic order according to
290
283
the order of the input *iterable *. So, if the input *iterable * is sorted,
291
284
the output tuples will be produced in sorted order.
292
285
293
286
Elements are treated as unique based on their position, not on their
294
- value. So if the input elements are unique, the generated combinations
287
+ value. So, if the input elements are unique, the generated combinations
295
288
will also be unique.
296
289
297
290
Roughly equivalent to::
@@ -332,13 +325,13 @@ loops that truncate the stream.
332
325
.. function :: compress(data, selectors)
333
326
334
327
Make an iterator that filters elements from *data * returning only those that
335
- have a corresponding element in *selectors * that evaluates to `` True `` .
336
- Stops when either the *data * or *selectors * iterables has been exhausted.
328
+ have a corresponding element in *selectors * is true .
329
+ Stops when either the *data * or *selectors * iterables have been exhausted.
337
330
Roughly equivalent to::
338
331
339
332
def compress(data, selectors):
340
333
# compress('ABCDEF', [1,0,1,0,1,1]) → A C E F
341
- return (d for d, s in zip(data, selectors) if s )
334
+ return (datum for datum, selector in zip(data, selectors) if selector )
342
335
343
336
.. versionadded :: 3.1
344
337
@@ -392,7 +385,7 @@ loops that truncate the stream.
392
385
start-up time. Roughly equivalent to::
393
386
394
387
def dropwhile(predicate, iterable):
395
- # dropwhile(lambda x: x<5, [1,4,6,4,1 ]) → 6 4 1
388
+ # dropwhile(lambda x: x<5, [1,4,6,3,8 ]) → 6 3 8
396
389
iterable = iter(iterable)
397
390
for x in iterable:
398
391
if not predicate(x):
@@ -408,7 +401,7 @@ loops that truncate the stream.
408
401
that are false. Roughly equivalent to::
409
402
410
403
def filterfalse(predicate, iterable):
411
- # filterfalse(lambda x: x%2, range(10)) → 0 2 4 6 8
404
+ # filterfalse(lambda x: x<5, [1,4,6,3,8]) → 6 8
412
405
if predicate is None:
413
406
predicate = bool
414
407
for x in iterable:
@@ -444,36 +437,37 @@ loops that truncate the stream.
444
437
445
438
:func: `groupby ` is roughly equivalent to::
446
439
447
- class groupby:
440
+ def groupby(iterable, key=None) :
448
441
# [k for k, g in groupby('AAAABBBCCDAABBB')] → A B C D A B
449
442
# [list(g) for k, g in groupby('AAAABBBCCD')] → AAAA BBB CC D
450
443
451
- def __init__(self, iterable, key=None):
452
- if key is None:
453
- key = lambda x: x
454
- self.keyfunc = key
455
- self.it = iter(iterable)
456
- self.tgtkey = self.currkey = self.currvalue = object()
457
-
458
- def __iter__(self):
459
- return self
460
-
461
- def __next__(self):
462
- self.id = object()
463
- while self.currkey == self.tgtkey:
464
- self.currvalue = next(self.it) # Exit on StopIteration
465
- self.currkey = self.keyfunc(self.currvalue)
466
- self.tgtkey = self.currkey
467
- return (self.currkey, self._grouper(self.tgtkey, self.id))
468
-
469
- def _grouper(self, tgtkey, id):
470
- while self.id is id and self.currkey == tgtkey:
471
- yield self.currvalue
472
- try:
473
- self.currvalue = next(self.it)
474
- except StopIteration:
444
+ keyfunc = (lambda x: x) if key is None else key
445
+ iterator = iter(iterable)
446
+ exhausted = False
447
+
448
+ def _grouper(target_key):
449
+ nonlocal curr_value, curr_key, exhausted
450
+ yield curr_value
451
+ for curr_value in iterator:
452
+ curr_key = keyfunc(curr_value)
453
+ if curr_key != target_key:
475
454
return
476
- self.currkey = self.keyfunc(self.currvalue)
455
+ yield curr_value
456
+ exhausted = True
457
+
458
+ try:
459
+ curr_value = next(iterator)
460
+ except StopIteration:
461
+ return
462
+ curr_key = keyfunc(curr_value)
463
+
464
+ while not exhausted:
465
+ target_key = curr_key
466
+ curr_group = _grouper(target_key)
467
+ yield curr_key, curr_group
468
+ if curr_key == target_key:
469
+ for _ in curr_group:
470
+ pass
477
471
478
472
479
473
.. function :: islice(iterable, stop)
@@ -501,13 +495,15 @@ loops that truncate the stream.
501
495
# islice('ABCDEFG', 2, 4) → C D
502
496
# islice('ABCDEFG', 2, None) → C D E F G
503
497
# islice('ABCDEFG', 0, None, 2) → A C E G
498
+
504
499
s = slice(*args)
505
500
start = 0 if s.start is None else s.start
506
501
stop = s.stop
507
502
step = 1 if s.step is None else s.step
508
503
if start < 0 or (stop is not None and stop < 0) or step <= 0:
509
504
raise ValueError
510
- indices = count() if stop is None else range(max(stop, start))
505
+
506
+ indices = count() if stop is None else range(max(start, stop))
511
507
next_i = start
512
508
for i, element in zip(indices, iterable):
513
509
if i == next_i:
@@ -549,22 +545,25 @@ loops that truncate the stream.
549
545
the output tuples will be produced in sorted order.
550
546
551
547
Elements are treated as unique based on their position, not on their
552
- value. So if the input elements are unique, there will be no repeated
548
+ value. So, if the input elements are unique, there will be no repeated
553
549
values within a permutation.
554
550
555
551
Roughly equivalent to::
556
552
557
553
def permutations(iterable, r=None):
558
554
# permutations('ABCD', 2) → AB AC AD BA BC BD CA CB CD DA DB DC
559
555
# permutations(range(3)) → 012 021 102 120 201 210
556
+
560
557
pool = tuple(iterable)
561
558
n = len(pool)
562
559
r = n if r is None else r
563
560
if r > n:
564
561
return
562
+
565
563
indices = list(range(n))
566
564
cycles = list(range(n, n-r, -1))
567
565
yield tuple(pool[i] for i in indices[:r])
566
+
568
567
while n:
569
568
for i in reversed(range(r)):
570
569
cycles[i] -= 1
@@ -580,7 +579,7 @@ loops that truncate the stream.
580
579
return
581
580
582
581
The code for :func: `permutations ` can be also expressed as a subsequence of
583
- :func: `product `, filtered to exclude entries with repeated elements (those
582
+ :func: `product ` filtered to exclude entries with repeated elements (those
584
583
from the same position in the input pool)::
585
584
586
585
def permutations(iterable, r=None):
@@ -674,17 +673,16 @@ loops that truncate the stream.
674
673
predicate is true. Roughly equivalent to::
675
674
676
675
def takewhile(predicate, iterable):
677
- # takewhile(lambda x: x<5, [1,4,6,4,1 ]) → 1 4
676
+ # takewhile(lambda x: x<5, [1,4,6,3,8 ]) → 1 4
678
677
for x in iterable:
679
- if predicate(x):
680
- yield x
681
- else:
678
+ if not predicate(x):
682
679
break
680
+ yield x
683
681
684
682
Note, the element that first fails the predicate condition is
685
683
consumed from the input iterator and there is no way to access it.
686
684
This could be an issue if an application wants to further consume the
687
- input iterator after takewhile has been run to exhaustion. To work
685
+ input iterator after * takewhile * has been run to exhaustion. To work
688
686
around this problem, consider using `more-iterools before_and_after()
689
687
<https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.before_and_after> `_
690
688
instead.
@@ -734,10 +732,12 @@ loops that truncate the stream.
734
732
735
733
def zip_longest(*iterables, fillvalue=None):
736
734
# zip_longest('ABCD', 'xy', fillvalue='-') → Ax By C- D-
737
- iterators = [iter(it) for it in iterables]
735
+
736
+ iterators = list(map(iter, iterables))
738
737
num_active = len(iterators)
739
738
if not num_active:
740
739
return
740
+
741
741
while True:
742
742
values = []
743
743
for i, iterator in enumerate(iterators):
0 commit comments