mirror of https://github.com/python/cpython
Update itertools recipes.
This commit is contained in:
parent
9b0e9180e2
commit
af9ab377d3
|
@ -580,16 +580,19 @@ which incur interpreter overhead.
|
||||||
"Return first n items of the iterable as a list"
|
"Return first n items of the iterable as a list"
|
||||||
return list(islice(iterable, n))
|
return list(islice(iterable, n))
|
||||||
|
|
||||||
def enumerate(iterable, start=0):
|
|
||||||
return zip(count(start), iterable)
|
|
||||||
|
|
||||||
def tabulate(function, start=0):
|
def tabulate(function, start=0):
|
||||||
"Return function(0), function(1), ..."
|
"Return function(0), function(1), ..."
|
||||||
return map(function, count(start))
|
return map(function, count(start))
|
||||||
|
|
||||||
def consume(iterator, n):
|
def consume(iterator, n):
|
||||||
"Advance the iterator n-steps ahead. If n is none, consume entirely."
|
"Advance the iterator n-steps ahead. If n is none, consume entirely."
|
||||||
collections.deque(islice(iterator, n), maxlen=0)
|
# Use functions that consume iterators at C speed.
|
||||||
|
if n is None:
|
||||||
|
# feed the entire iterator into a zero-length deque
|
||||||
|
collections.deque(iterator, maxlen=0)
|
||||||
|
else:
|
||||||
|
# advance to the emtpy slice starting at position n
|
||||||
|
next(islice(iterator, n, n), None)
|
||||||
|
|
||||||
def nth(iterable, n, default=None):
|
def nth(iterable, n, default=None):
|
||||||
"Returns the nth item or a default value"
|
"Returns the nth item or a default value"
|
||||||
|
@ -661,8 +664,7 @@ which incur interpreter overhead.
|
||||||
seen = set()
|
seen = set()
|
||||||
seen_add = seen.add
|
seen_add = seen.add
|
||||||
if key is None:
|
if key is None:
|
||||||
for element in iterable:
|
for element in filterfalse(seen.__contains__, iterable):
|
||||||
if element not in seen:
|
|
||||||
seen_add(element)
|
seen_add(element)
|
||||||
yield element
|
yield element
|
||||||
else:
|
else:
|
||||||
|
@ -677,3 +679,33 @@ which incur interpreter overhead.
|
||||||
# unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
|
# unique_justseen('AAAABBBCCDAABBB') --> A B C D A B
|
||||||
# unique_justseen('ABBCcAD', str.lower) --> A B C A D
|
# unique_justseen('ABBCcAD', str.lower) --> A B C A D
|
||||||
return map(next, map(itemgetter(1), groupby(iterable, key)))
|
return map(next, map(itemgetter(1), groupby(iterable, key)))
|
||||||
|
|
||||||
|
def iter_except(func, exception, first=None):
|
||||||
|
""" Call a function repeatedly until an exception is raised.
|
||||||
|
|
||||||
|
Converts a call-until-exception interface to an iterator interface.
|
||||||
|
Like __builtin__.iter(func, sentinel) but uses an exception instead
|
||||||
|
of a sentinel to end the loop.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
iter_except(functools.partial(heappop, h), IndexError) # priority queue iterator
|
||||||
|
iter_except(d.popitem, KeyError) # non-blocking dict iterator
|
||||||
|
iter_except(d.popleft, IndexError) # non-blocking deque iterator
|
||||||
|
iter_except(q.get_nowait, Queue.Empty) # loop over a producer Queue
|
||||||
|
iter_except(s.pop, KeyError) # non-blocking set iterator
|
||||||
|
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
if first is not None:
|
||||||
|
yield first() # For database APIs needing an initial cast to db.first()
|
||||||
|
while 1:
|
||||||
|
yield func()
|
||||||
|
except exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
Note, many of the above recipes can be optimized by replacing global lookups
|
||||||
|
with local variables defined as default values. For example, the
|
||||||
|
*dotproduct* recipe can be written as::
|
||||||
|
|
||||||
|
def dotproduct(vec1, vec2, sum=sum, map=map, mul=operator.mul):
|
||||||
|
return sum(map(mul, vec1, vec2))
|
||||||
|
|
Loading…
Reference in New Issue