1  import itertools
       2  from collections import deque
       3  from itertools import islice
       4  
       5  
       6  # from jaraco.itertools 6.3.0
       7  class ESC[4;38;5;81mCounter:
       8      """
       9      Wrap an iterable in an object that stores the count of items
      10      that pass through it.
      11  
      12      >>> items = Counter(range(20))
      13      >>> items.count
      14      0
      15      >>> values = list(items)
      16      >>> items.count
      17      20
      18      """
      19  
      20      def __init__(self, i):
      21          self.count = 0
      22          self.iter = zip(itertools.count(1), i)
      23  
      24      def __iter__(self):
      25          return self
      26  
      27      def __next__(self):
      28          self.count, result = next(self.iter)
      29          return result
      30  
      31  
      32  # from more_itertools v8.13.0
      33  def always_iterable(obj, base_type=(str, bytes)):
      34      if obj is None:
      35          return iter(())
      36  
      37      if (base_type is not None) and isinstance(obj, base_type):
      38          return iter((obj,))
      39  
      40      try:
      41          return iter(obj)
      42      except TypeError:
      43          return iter((obj,))
      44  
      45  
      46  # from more_itertools v9.0.0
      47  def consume(iterator, n=None):
      48      """Advance *iterable* by *n* steps. If *n* is ``None``, consume it
      49      entirely.
      50      Efficiently exhausts an iterator without returning values. Defaults to
      51      consuming the whole iterator, but an optional second argument may be
      52      provided to limit consumption.
      53          >>> i = (x for x in range(10))
      54          >>> next(i)
      55          0
      56          >>> consume(i, 3)
      57          >>> next(i)
      58          4
      59          >>> consume(i)
      60          >>> next(i)
      61          Traceback (most recent call last):
      62            File "<stdin>", line 1, in <module>
      63          StopIteration
      64      If the iterator has fewer items remaining than the provided limit, the
      65      whole iterator will be consumed.
      66          >>> i = (x for x in range(3))
      67          >>> consume(i, 5)
      68          >>> next(i)
      69          Traceback (most recent call last):
      70            File "<stdin>", line 1, in <module>
      71          StopIteration
      72      """
      73      # Use functions that consume iterators at C speed.
      74      if n is None:
      75          # feed the entire iterator into a zero-length deque
      76          deque(iterator, maxlen=0)
      77      else:
      78          # advance to the empty slice starting at position n
      79          next(islice(iterator, n, n), None)