@@ -580,16 +580,19 @@ which incur interpreter overhead.
580580 "Return first n items of the iterable as a list"
581581 return list(islice(iterable, n))
582582
583- def enumerate(iterable, start=0):
584- return zip(count(start), iterable)
585-
586583 def tabulate(function, start=0):
587584 "Return function(0), function(1), ..."
588585 return map(function, count(start))
589586
590587 def consume(iterator, n):
591588 "Advance the iterator n-steps ahead. If n is none, consume entirely."
592- collections.deque(islice(iterator, n), maxlen=0)
589+ # Use functions that consume iterators at C speed.
590+ if n is None:
591+ # feed the entire iterator into a zero-length deque
592+ collections.deque(iterator, maxlen=0)
593+ else:
594+ # advance to the emtpy slice starting at position n
595+ next(islice(iterator, n, n), None)
593596
594597 def nth(iterable, n, default=None):
595598 "Returns the nth item or a default value"
@@ -661,10 +664,9 @@ which incur interpreter overhead.
661664 seen = set()
662665 seen_add = seen.add
663666 if key is None:
664- for element in iterable:
665- if element not in seen:
666- seen_add(element)
667- yield element
667+ for element in filterfalse(seen.__contains__, iterable):
668+ seen_add(element)
669+ yield element
668670 else:
669671 for element in iterable:
670672 k = key(element)
@@ -677,3 +679,33 @@ which incur interpreter overhead.
677679 # unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
678680 # unique_justseen('ABBCcAD', str.lower) --> A B C A D
679681 return map(next, map(itemgetter(1), groupby(iterable, key)))
682+
683+ def iter_except(func, exception, first=None):
684+ """ Call a function repeatedly until an exception is raised.
685+
686+ Converts a call-until-exception interface to an iterator interface.
687+ Like __builtin__.iter(func, sentinel) but uses an exception instead
688+ of a sentinel to end the loop.
689+
690+ Examples:
691+ iter_except(functools.partial(heappop, h), IndexError) # priority queue iterator
692+ iter_except(d.popitem, KeyError) # non-blocking dict iterator
693+ iter_except(d.popleft, IndexError) # non-blocking deque iterator
694+ iter_except(q.get_nowait, Queue.Empty) # loop over a producer Queue
695+ iter_except(s.pop, KeyError) # non-blocking set iterator
696+
697+ """
698+ try:
699+ if first is not None:
700+ yield first() # For database APIs needing an initial cast to db.first()
701+ while 1:
702+ yield func()
703+ except exception:
704+ pass
705+
706+ Note, many of the above recipes can be optimized by replacing global lookups
707+ with local variables defined as default values. For example, the
708+ *dotproduct * recipe can be written as::
709+
710+ def dotproduct(vec1, vec2, sum=sum, map=map, mul=operator.mul):
711+ return sum(map(mul, vec1, vec2))
0 commit comments