@@ -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:
@@ -184,21 +184,14 @@ loops that truncate the stream.
184184 >>> unflattened
185185 [('roses', 'red'), ('violets', 'blue'), ('sugar', 'sweet')]
186186
187- >>> for batch in batched(' ABCDEFG' , 3 ):
188- ... print (batch)
189- ...
190- ('A', 'B', 'C')
191- ('D', 'E', 'F')
192- ('G',)
193-
194187 Roughly equivalent to::
195188
196189 def batched(iterable, n, *, strict=False):
197190 # batched('ABCDEFG', 3) → ABC DEF G
198191 if n < 1:
199192 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)):
202195 if strict and len(batch) != n:
203196 raise ValueError('batched(): incomplete batch')
204197 yield batch
@@ -237,13 +230,13 @@ loops that truncate the stream.
237230
238231 Return *r * length subsequences of elements from the input *iterable *.
239232
240- The combination tuples are emitted in lexicographic ordering according to
233+ The combination tuples are emitted in lexicographic order according to
241234 the order of the input *iterable *. So, if the input *iterable * is sorted,
242235 the output tuples will be produced in sorted order.
243236
244237 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.
247240
248241 Roughly equivalent to::
249242
@@ -286,12 +279,12 @@ loops that truncate the stream.
286279 Return *r * length subsequences of elements from the input *iterable *
287280 allowing individual elements to be repeated more than once.
288281
289- The combination tuples are emitted in lexicographic ordering according to
282+ The combination tuples are emitted in lexicographic order according to
290283 the order of the input *iterable *. So, if the input *iterable * is sorted,
291284 the output tuples will be produced in sorted order.
292285
293286 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
295288 will also be unique.
296289
297290 Roughly equivalent to::
@@ -332,13 +325,13 @@ loops that truncate the stream.
332325.. function :: compress(data, selectors)
333326
334327 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.
337330 Roughly equivalent to::
338331
339332 def compress(data, selectors):
340333 # 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 )
342335
343336 .. versionadded :: 3.1
344337
@@ -392,7 +385,7 @@ loops that truncate the stream.
392385 start-up time. Roughly equivalent to::
393386
394387 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
396389 iterable = iter(iterable)
397390 for x in iterable:
398391 if not predicate(x):
@@ -408,7 +401,7 @@ loops that truncate the stream.
408401 that are false. Roughly equivalent to::
409402
410403 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
412405 if predicate is None:
413406 predicate = bool
414407 for x in iterable:
@@ -444,36 +437,37 @@ loops that truncate the stream.
444437
445438 :func: `groupby ` is roughly equivalent to::
446439
447- class groupby:
440+ def groupby(iterable, key=None) :
448441 # [k for k, g in groupby('AAAABBBCCDAABBB')] → A B C D A B
449442 # [list(g) for k, g in groupby('AAAABBBCCD')] → AAAA BBB CC D
450443
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:
475454 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
477471
478472
479473.. function :: islice(iterable, stop)
@@ -501,13 +495,15 @@ loops that truncate the stream.
501495 # islice('ABCDEFG', 2, 4) → C D
502496 # islice('ABCDEFG', 2, None) → C D E F G
503497 # islice('ABCDEFG', 0, None, 2) → A C E G
498+
504499 s = slice(*args)
505500 start = 0 if s.start is None else s.start
506501 stop = s.stop
507502 step = 1 if s.step is None else s.step
508503 if start < 0 or (stop is not None and stop < 0) or step <= 0:
509504 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))
511507 next_i = start
512508 for i, element in zip(indices, iterable):
513509 if i == next_i:
@@ -549,22 +545,25 @@ loops that truncate the stream.
549545 the output tuples will be produced in sorted order.
550546
551547 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
553549 values within a permutation.
554550
555551 Roughly equivalent to::
556552
557553 def permutations(iterable, r=None):
558554 # permutations('ABCD', 2) → AB AC AD BA BC BD CA CB CD DA DB DC
559555 # permutations(range(3)) → 012 021 102 120 201 210
556+
560557 pool = tuple(iterable)
561558 n = len(pool)
562559 r = n if r is None else r
563560 if r > n:
564561 return
562+
565563 indices = list(range(n))
566564 cycles = list(range(n, n-r, -1))
567565 yield tuple(pool[i] for i in indices[:r])
566+
568567 while n:
569568 for i in reversed(range(r)):
570569 cycles[i] -= 1
@@ -580,7 +579,7 @@ loops that truncate the stream.
580579 return
581580
582581 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
584583 from the same position in the input pool)::
585584
586585 def permutations(iterable, r=None):
@@ -674,17 +673,16 @@ loops that truncate the stream.
674673 predicate is true. Roughly equivalent to::
675674
676675 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
678677 for x in iterable:
679- if predicate(x):
680- yield x
681- else:
678+ if not predicate(x):
682679 break
680+ yield x
683681
684682 Note, the element that first fails the predicate condition is
685683 consumed from the input iterator and there is no way to access it.
686684 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
688686 around this problem, consider using `more-iterools before_and_after()
689687 <https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.before_and_after> `_
690688 instead.
@@ -734,10 +732,12 @@ loops that truncate the stream.
734732
735733 def zip_longest(*iterables, fillvalue=None):
736734 # zip_longest('ABCD', 'xy', fillvalue='-') → Ax By C- D-
737- iterators = [iter(it) for it in iterables]
735+
736+ iterators = list(map(iter, iterables))
738737 num_active = len(iterators)
739738 if not num_active:
740739 return
740+
741741 while True:
742742 values = []
743743 for i, iterator in enumerate(iterators):
0 commit comments