@@ -134,7 +134,7 @@ loops that truncate the stream.
134134 total = func(total, element)
135135 yield total
136136
137- There are a number of uses for the *func * argument. It can be set to
137+ The *func * argument can be set to
138138 :func: `min ` for a running minimum, :func: `max ` for a running maximum, or
139139 :func: `operator.mul ` for a running product. Amortization tables can be
140140 built by accumulating interest and applying payments:
@@ -181,21 +181,14 @@ loops that truncate the stream.
181181 >>> unflattened
182182 [('roses', 'red'), ('violets', 'blue'), ('sugar', 'sweet')]
183183
184- >>> for batch in batched(' ABCDEFG' , 3 ):
185- ... print (batch)
186- ...
187- ('A', 'B', 'C')
188- ('D', 'E', 'F')
189- ('G',)
190-
191184 Roughly equivalent to::
192185
193186 def batched(iterable, n):
194187 # batched('ABCDEFG', 3) → ABC DEF G
195188 if n < 1:
196189 raise ValueError('n must be at least one')
197- it = iter(iterable)
198- while batch := tuple(islice(it , n)):
190+ iterable = iter(iterable)
191+ while batch := tuple(islice(iterable , n)):
199192 yield batch
200193
201194 .. versionadded :: 3.12
@@ -229,13 +222,13 @@ loops that truncate the stream.
229222
230223 Return *r * length subsequences of elements from the input *iterable *.
231224
232- The combination tuples are emitted in lexicographic ordering according to
225+ The combination tuples are emitted in lexicographic order according to
233226 the order of the input *iterable *. So, if the input *iterable * is sorted,
234227 the output tuples will be produced in sorted order.
235228
236229 Elements are treated as unique based on their position, not on their
237- value. So if the input elements are unique, there will be no repeated
238- values in each combination.
230+ value. So, if the input elements are unique, there will be no repeated
231+ values within each combination.
239232
240233 Roughly equivalent to::
241234
@@ -278,12 +271,12 @@ loops that truncate the stream.
278271 Return *r * length subsequences of elements from the input *iterable *
279272 allowing individual elements to be repeated more than once.
280273
281- The combination tuples are emitted in lexicographic ordering according to
274+ The combination tuples are emitted in lexicographic order according to
282275 the order of the input *iterable *. So, if the input *iterable * is sorted,
283276 the output tuples will be produced in sorted order.
284277
285278 Elements are treated as unique based on their position, not on their
286- value. So if the input elements are unique, the generated combinations
279+ value. So, if the input elements are unique, the generated combinations
287280 will also be unique.
288281
289282 Roughly equivalent to::
@@ -324,13 +317,13 @@ loops that truncate the stream.
324317.. function :: compress(data, selectors)
325318
326319 Make an iterator that filters elements from *data * returning only those that
327- have a corresponding element in *selectors * that evaluates to `` True `` .
328- Stops when either the *data * or *selectors * iterables has been exhausted.
320+ have a corresponding element in *selectors * is true .
321+ Stops when either the *data * or *selectors * iterables have been exhausted.
329322 Roughly equivalent to::
330323
331324 def compress(data, selectors):
332325 # compress('ABCDEF', [1,0,1,0,1,1]) → A C E F
333- return (d for d, s in zip(data, selectors) if s )
326+ return (datum for datum, selector in zip(data, selectors) if selector )
334327
335328 .. versionadded :: 3.1
336329
@@ -384,7 +377,7 @@ loops that truncate the stream.
384377 start-up time. Roughly equivalent to::
385378
386379 def dropwhile(predicate, iterable):
387- # dropwhile(lambda x: x<5, [1,4,6,4,1 ]) → 6 4 1
380+ # dropwhile(lambda x: x<5, [1,4,6,3,8 ]) → 6 3 8
388381 iterable = iter(iterable)
389382 for x in iterable:
390383 if not predicate(x):
@@ -400,7 +393,7 @@ loops that truncate the stream.
400393 that are false. Roughly equivalent to::
401394
402395 def filterfalse(predicate, iterable):
403- # filterfalse(lambda x: x%2, range(10)) → 0 2 4 6 8
396+ # filterfalse(lambda x: x<5, [1,4,6,3,8]) → 6 8
404397 if predicate is None:
405398 predicate = bool
406399 for x in iterable:
@@ -436,36 +429,37 @@ loops that truncate the stream.
436429
437430 :func: `groupby ` is roughly equivalent to::
438431
439- class groupby:
432+ def groupby(iterable, key=None) :
440433 # [k for k, g in groupby('AAAABBBCCDAABBB')] → A B C D A B
441434 # [list(g) for k, g in groupby('AAAABBBCCD')] → AAAA BBB CC D
442435
443- def __init__(self, iterable, key=None):
444- if key is None:
445- key = lambda x: x
446- self.keyfunc = key
447- self.it = iter(iterable)
448- self.tgtkey = self.currkey = self.currvalue = object()
449-
450- def __iter__(self):
451- return self
452-
453- def __next__(self):
454- self.id = object()
455- while self.currkey == self.tgtkey:
456- self.currvalue = next(self.it) # Exit on StopIteration
457- self.currkey = self.keyfunc(self.currvalue)
458- self.tgtkey = self.currkey
459- return (self.currkey, self._grouper(self.tgtkey, self.id))
460-
461- def _grouper(self, tgtkey, id):
462- while self.id is id and self.currkey == tgtkey:
463- yield self.currvalue
464- try:
465- self.currvalue = next(self.it)
466- except StopIteration:
436+ keyfunc = (lambda x: x) if key is None else key
437+ iterator = iter(iterable)
438+ exhausted = False
439+
440+ def _grouper(target_key):
441+ nonlocal curr_value, curr_key, exhausted
442+ yield curr_value
443+ for curr_value in iterator:
444+ curr_key = keyfunc(curr_value)
445+ if curr_key != target_key:
467446 return
468- self.currkey = self.keyfunc(self.currvalue)
447+ yield curr_value
448+ exhausted = True
449+
450+ try:
451+ curr_value = next(iterator)
452+ except StopIteration:
453+ return
454+ curr_key = keyfunc(curr_value)
455+
456+ while not exhausted:
457+ target_key = curr_key
458+ curr_group = _grouper(target_key)
459+ yield curr_key, curr_group
460+ if curr_key == target_key:
461+ for _ in curr_group:
462+ pass
469463
470464
471465.. function :: islice(iterable, stop)
@@ -493,13 +487,15 @@ loops that truncate the stream.
493487 # islice('ABCDEFG', 2, 4) → C D
494488 # islice('ABCDEFG', 2, None) → C D E F G
495489 # islice('ABCDEFG', 0, None, 2) → A C E G
490+
496491 s = slice(*args)
497492 start = 0 if s.start is None else s.start
498493 stop = s.stop
499494 step = 1 if s.step is None else s.step
500495 if start < 0 or (stop is not None and stop < 0) or step <= 0:
501496 raise ValueError
502- indices = count() if stop is None else range(max(stop, start))
497+
498+ indices = count() if stop is None else range(max(start, stop))
503499 next_i = start
504500 for i, element in zip(indices, iterable):
505501 if i == next_i:
@@ -541,22 +537,25 @@ loops that truncate the stream.
541537 the output tuples will be produced in sorted order.
542538
543539 Elements are treated as unique based on their position, not on their
544- value. So if the input elements are unique, there will be no repeated
540+ value. So, if the input elements are unique, there will be no repeated
545541 values within a permutation.
546542
547543 Roughly equivalent to::
548544
549545 def permutations(iterable, r=None):
550546 # permutations('ABCD', 2) → AB AC AD BA BC BD CA CB CD DA DB DC
551547 # permutations(range(3)) → 012 021 102 120 201 210
548+
552549 pool = tuple(iterable)
553550 n = len(pool)
554551 r = n if r is None else r
555552 if r > n:
556553 return
554+
557555 indices = list(range(n))
558556 cycles = list(range(n, n-r, -1))
559557 yield tuple(pool[i] for i in indices[:r])
558+
560559 while n:
561560 for i in reversed(range(r)):
562561 cycles[i] -= 1
@@ -572,7 +571,7 @@ loops that truncate the stream.
572571 return
573572
574573 The code for :func: `permutations ` can be also expressed as a subsequence of
575- :func: `product `, filtered to exclude entries with repeated elements (those
574+ :func: `product ` filtered to exclude entries with repeated elements (those
576575 from the same position in the input pool)::
577576
578577 def permutations(iterable, r=None):
@@ -666,17 +665,16 @@ loops that truncate the stream.
666665 predicate is true. Roughly equivalent to::
667666
668667 def takewhile(predicate, iterable):
669- # takewhile(lambda x: x<5, [1,4,6,4,1 ]) → 1 4
668+ # takewhile(lambda x: x<5, [1,4,6,3,8 ]) → 1 4
670669 for x in iterable:
671- if predicate(x):
672- yield x
673- else:
670+ if not predicate(x):
674671 break
672+ yield x
675673
676674 Note, the element that first fails the predicate condition is
677675 consumed from the input iterator and there is no way to access it.
678676 This could be an issue if an application wants to further consume the
679- input iterator after takewhile has been run to exhaustion. To work
677+ input iterator after * takewhile * has been run to exhaustion. To work
680678 around this problem, consider using `more-iterools before_and_after()
681679 <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.before_and_after> `_
682680 instead.
@@ -726,10 +724,12 @@ loops that truncate the stream.
726724
727725 def zip_longest(*iterables, fillvalue=None):
728726 # zip_longest('ABCD', 'xy', fillvalue='-') → Ax By C- D-
729- iterators = [iter(it) for it in iterables]
727+
728+ iterators = list(map(iter, iterables))
730729 num_active = len(iterators)
731730 if not num_active:
732731 return
732+
733733 while True:
734734 values = []
735735 for i, iterator in enumerate(iterators):
0 commit comments