U
    AZ                  1   @   s  d dl mZ d dlmZmZmZ d dlmZmZ d dl	m
Z
 d dlmZmZmZmZmZmZmZmZmZmZ d dlmZmZmZmZ d dlmZmZ zd dlmZ W n  e k
r   d dlmZ Y nX d d	l!m"Z"m#Z#m$Z$ d d
l%m&Z&m'Z'm(Z(m)Z)m*Z* ddl+m,Z,m-Z-m.Z. dddddddddddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=g1Z/e0 Z1d>d Z2e1fd?dZ3G d@d, d,e0Z4dAdB Z5dCd Z6edDkre6j7Z8ee
Z6e8e6_7dEd Z9dFd Z:dGd$ Z;dHd< Z<dxdJd*Z=dKd Z>dydLd"Z?dMd: Z@dzdNd;ZAG dOd de0ZBd{dPd7ZCdQd! ZDdRd  ZEd|dSdZFd}dTd1ZGdUd2 ZHdVd4 ZIdWd6 ZJdXd5 ZKd~dZd+ZLd[d ZMdd]d8ZNd^d= ZOdd`d3ZPdad ZQe$e"ffdbdZRddcdZSddddZTded) ZUddfdZVeWfdgd%ZXdhd& ZYdid- ZZdjd9 Z[dkd# Z\dld Z]dmdn fdodZ^efdpdZ_G dqd0 d0eZ`G drd/ d/e0ZaG dsd. d.e0ZbeWfdtdZcdud Zdddvd'Zeddwd(ZfdIS )    )print_function)Counterdefaultdictdeque)partialwraps)merge)
chaincompresscountcycle	dropwhilegroupbyislicerepeat	takewhiletee)
itemgetterltgtsub)maxsizeversion_info)Sequence)binary_typestring_types	text_type)filtermaprangezipzip_longest   )consumeflattentakeadjacentalways_iterablealways_reversiblebucketchunkedcircular_shiftscollapsecollateconsecutive_groupsconsumercount_cycle
differencedistinct_permutations
distributedivide	exactly_nfirstgroupby_transformileninterleave_longest
interleaveintersperseislice_extendediteratelocatelstripmake_decorator
map_reducenumeric_rangeonepaddedpeekablerstrip
run_lengthseekableSequenceViewside_effectslicedsort_togethersplit_atsplit_aftersplit_beforespystaggerstripunique_to_eachwindowed	with_iter
zip_offsetc                 C   s   t tt|t | g S )a  Break *iterable* into lists of length *n*:

        >>> list(chunked([1, 2, 3, 4, 5, 6], 3))
        [[1, 2, 3], [4, 5, 6]]

    If the length of *iterable* is not evenly divisible by *n*, the last
    returned list will be shorter:

        >>> list(chunked([1, 2, 3, 4, 5, 6, 7, 8], 3))
        [[1, 2, 3], [4, 5, 6], [7, 8]]

    To use a fill-in value instead, see the :func:`grouper` recipe.

    :func:`chunked` is useful for splitting up a computation on a large number
    of keys into batches, to be pickled and sent off to worker processes. One
    example is operations on rows in MySQL, which does not implement
    server-side cursors properly and would otherwise load the entire dataset
    into RAM on the client.

    )iterr   r%   )iterablen rZ   5/usr/lib/python3/dist-packages/more_itertools/more.pyr*   U   s    c                 C   s<   zt t| W S  tk
r6   |tkr.td| Y S X dS )a  Return the first item of *iterable*, or *default* if *iterable* is
    empty.

        >>> first([0, 1, 2, 3])
        0
        >>> first([], 'some default')
        'some default'

    If *default* is not provided and there are no items in the iterable,
    raise ``ValueError``.

    :func:`first` is useful when you have a generator of expensive-to-retrieve
    values and want any arbitrary one. It is marginally shorter than
    ``next(iter(iterable), default)``.

    zKfirst() was called on an empty iterable, and no default value was provided.N)nextrW   StopIteration_marker
ValueError)rX   defaultrZ   rZ   r[   r6   m   s    c                   @   s`   e Zd ZdZdd Zdd Zdd Zdd	 Zefd
dZ	dd Z
dd ZeZdd Zdd ZdS )rE   a  Wrap an iterator to allow lookahead and prepending elements.

    Call :meth:`peek` on the result to get the value that will be returned
    by :func:`next`. This won't advance the iterator:

        >>> p = peekable(['a', 'b'])
        >>> p.peek()
        'a'
        >>> next(p)
        'a'

    Pass :meth:`peek` a default value to return that instead of raising
    ``StopIteration`` when the iterator is exhausted.

        >>> p = peekable([])
        >>> p.peek('hi')
        'hi'

    peekables also offer a :meth:`prepend` method, which "inserts" items
    at the head of the iterable:

        >>> p = peekable([1, 2, 3])
        >>> p.prepend(10, 11, 12)
        >>> next(p)
        10
        >>> p.peek()
        11
        >>> list(p)
        [11, 12, 1, 2, 3]

    peekables can be indexed. Index 0 is the item that will be returned by
    :func:`next`, index 1 is the item after that, and so on:
    The values up to the given index will be cached.

        >>> p = peekable(['a', 'b', 'c', 'd'])
        >>> p[0]
        'a'
        >>> p[1]
        'b'
        >>> next(p)
        'a'

    Negative indexes are supported, but be aware that they will cache the
    remaining items in the source iterator, which may require significant
    storage.

    To check whether a peekable is exhausted, check its truth value:

        >>> p = peekable(['a', 'b'])
        >>> if p:  # peekable has items
        ...     list(p)
        ['a', 'b']
        >>> if not p:  # peekable is exhaused
        ...     list(p)
        []

    c                 C   s   t || _t | _d S N)rW   _itr   _cacheselfrX   rZ   rZ   r[   __init__   s    
zpeekable.__init__c                 C   s   | S ra   rZ   re   rZ   rZ   r[   __iter__   s    zpeekable.__iter__c                 C   s(   z|    W n tk
r"   Y dS X dS NFT)peekr]   rg   rZ   rZ   r[   __bool__   s
    zpeekable.__bool__c                 C   s   |   S ra   )rk   rg   rZ   rZ   r[   __nonzero__   s    zpeekable.__nonzero__c                 C   sJ   | j s@z| j t| j W n" tk
r>   |tkr6 | Y S X | j d S )zReturn the item that will be next returned from ``next()``.

        Return ``default`` if there are no items left. If ``default`` is not
        provided, raise ``StopIteration``.

        r   )rc   appendr\   rb   r]   r^   )re   r`   rZ   rZ   r[   rj      s    
zpeekable.peekc                 G   s   | j t| dS )a  Stack up items to be the next ones returned from ``next()`` or
        ``self.peek()``. The items will be returned in
        first in, first out order::

            >>> p = peekable([1, 2, 3])
            >>> p.prepend(10, 11, 12)
            >>> next(p)
            10
            >>> list(p)
            [11, 12, 1, 2, 3]

        It is possible, by prepending items, to "resurrect" a peekable that
        previously raised ``StopIteration``.

            >>> p = peekable([])
            >>> next(p)
            Traceback (most recent call last):
              ...
            StopIteration
            >>> p.prepend(1)
            >>> next(p)
            1
            >>> next(p)
            Traceback (most recent call last):
              ...
            StopIteration

        N)rc   
extendleftreversed)re   itemsrZ   rZ   r[   prepend   s    zpeekable.prependc                 C   s   | j r| j  S t| jS ra   )rc   popleftr\   rb   rg   rZ   rZ   r[   __next__  s    
zpeekable.__next__c                 C   s   |j d krdn|j }|dkrF|jd kr*dn|j}|jd kr>tn|j}n@|dk r~|jd kr\dn|j}|jd krvt d n|j}ntd|dk s|dk r| j| j n>tt	||d t}t
| j}||kr| jt| j||  t| j| S )Nr"   r   zslice step cannot be zero)stepstartstopr   r_   rc   extendrb   minmaxlenr   list)re   indexru   rv   rw   rY   	cache_lenrZ   rZ   r[   
_get_slice  s    
zpeekable._get_slicec                 C   sd   t |tr| |S t| j}|dk r6| j| j n$||krZ| jt| j|d |  | j| S Nr   r"   )
isinstanceslicer   r{   rc   rx   rb   r   )re   r}   r~   rZ   rZ   r[   __getitem__(  s    


zpeekable.__getitem__N)__name__
__module____qualname____doc__rf   rh   rk   rl   r^   rj   rq   rs   r\   r   r   rZ   rZ   rZ   r[   rE      s   9c                  /   s   | ddd  | dd}t|r&tnttdd}dd	 | D }d
d	 |D }|r| fdd|D \}}t|V  dd	 |D }qPdS )zHelper for ``collate()``, called when the user is using the ``reverse``
    or ``key`` keyword arguments on Python versions below 3.5.

    keyc                 S   s   | S ra   rZ   )arZ   rZ   r[   <lambda>:      z_collate.<locals>.<lambda>reverseFr   r   c                 S   s   g | ]}t |qS rZ   )rE   .0itrZ   rZ   r[   
<listcomp>>  s     z_collate.<locals>.<listcomp>c                 S   s   g | ]}|r|qS rZ   rZ   r   prZ   rZ   r[   r   ?  s      c                 3   s   | ]} |  |fV  qd S ra   )rj   r   r   rZ   r[   	<genexpr>A  s     z_collate.<locals>.<genexpr>c                 S   s   g | ]}|r|qS rZ   rZ   r   xrZ   rZ   r[   r   C  s      N)popr   rz   ry   r   r\   )	iterableskwargsr   Z
min_or_maxZ	peekables_r   rZ   r   r[   _collate5  s    
r   c                  O   s   |st |  S t| |S )a^  Return a sorted merge of the items from each of several already-sorted
    *iterables*.

        >>> list(collate('ACDZ', 'AZ', 'JKL'))
        ['A', 'A', 'C', 'D', 'J', 'K', 'L', 'Z', 'Z']

    Works lazily, keeping only the next value from each iterable in memory. Use
    :func:`collate` to, for example, perform a n-way mergesort of items that
    don't fit in memory.

    If a *key* function is specified, the iterables will be sorted according
    to its result:

        >>> key = lambda s: int(s)  # Sort by numeric value, not by string
        >>> list(collate(['1', '10'], ['2', '11'], key=key))
        ['1', '2', '10', '11']


    If the *iterables* are sorted in descending order, set *reverse* to
    ``True``:

        >>> list(collate([5, 3, 1], [4, 2, 0], reverse=True))
        [5, 4, 3, 2, 1, 0]

    If the elements of the passed-in iterables are out of order, you might get
    unexpected results.

    On Python 2.7, this function delegates to :func:`heapq.merge` if neither
    of the keyword arguments are specified. On Python 3.5+, this function
    is an alias for :func:`heapq.merge`.

    )r   r   )r   r   rZ   rZ   r[   r-   F  s    !)      r   c                    s   t   fdd}|S )ab  Decorator that automatically advances a PEP-342-style "reverse iterator"
    to its first yield point so you don't have to call ``next()`` on it
    manually.

        >>> @consumer
        ... def tally():
        ...     i = 0
        ...     while True:
        ...         print('Thing number %s is %s.' % (i, (yield)))
        ...         i += 1
        ...
        >>> t = tally()
        >>> t.send('red')
        Thing number 0 is red.
        >>> t.send('fish')
        Thing number 1 is fish.

    Without the decorator, you would have to call ``next(t)`` before
    ``t.send()`` could be used.

    c                     s    | |}t | |S ra   )r\   )argsr   genfuncrZ   r[   wrapper  s    
zconsumer.<locals>.wrapper)r   )r   r   rZ   r   r[   r/   u  s    c                 C   s&   t t| ddd}|r"|d d S dS )zReturn the number of items in *iterable*.

        >>> ilen(x for x in range(1000000) if x % 3 == 0)
        333334

    This consumes the iterable, so handle with care.

    r"   maxlenr   )r   	enumerate)rX   drZ   rZ   r[   r8     s    
c                 c   s   |V  | |}q dS )zReturn ``start``, ``func(start)``, ``func(func(start))``, ...

        >>> from itertools import islice
        >>> list(islice(iterate(lambda x: 2*x, 1), 10))
        [1, 2, 4, 8, 16, 32, 64, 128, 256, 512]

    NrZ   )r   rv   rZ   rZ   r[   r=     s    	c              	   c   s$   | }|D ]
}|V  q
W 5 Q R X dS )a:  Wrap an iterable in a ``with`` statement, so it closes once exhausted.

    For example, this will close the file when the iterator is exhausted::

        upper_lines = (line.upper() for line in with_iter(open('foo')))

    Any context manager which returns an iterable is a candidate for
    ``with_iter``.

    NrZ   )Zcontext_managerrX   itemrZ   rZ   r[   rU     s    Nc                 C   sh   t | }zt|}W n  tk
r4   |p.tdY nX zt| W n tk
rV   Y nX |pbtd|S )a  Return the first item from *iterable*, which is expected to contain only
    that item. Raise an exception if *iterable* is empty or has more than one
    item.

    :func:`one` is useful for ensuring that an iterable contains only one item.
    For example, it can be used to retrieve the result of a database query
    that is expected to return a single row.

    If *iterable* is empty, ``ValueError`` will be raised. You may specify a
    different exception with the *too_short* keyword:

        >>> it = []
        >>> one(it)  # doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
        ...
        ValueError: too many items in iterable (expected 1)'
        >>> too_short = IndexError('too few items')
        >>> one(it, too_short=too_short)  # doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
        ...
        IndexError: too few items

    Similarly, if *iterable* contains more than one item, ``ValueError`` will
    be raised. You may specify a different exception with the *too_long*
    keyword:

        >>> it = ['too', 'many']
        >>> one(it)  # doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
        ...
        ValueError: too many items in iterable (expected 1)'
        >>> too_long = RuntimeError
        >>> one(it, too_long=too_long)  # doctest: +IGNORE_EXCEPTION_DETAIL
        Traceback (most recent call last):
        ...
        RuntimeError

    Note that :func:`one` attempts to advance *iterable* twice to ensure there
    is only one item. If there is more than one, both items will be discarded.
    See :func:`spy` or :func:`peekable` to check iterable contents less
    destructively.

    z&too few items in iterable (expected 1)z'too many items in iterable (expected 1))rW   r\   r]   r_   )rX   Z	too_shortZtoo_longr   valuerZ   rZ   r[   rC     s    ,c                    s6    fdd t | }t| } |dg| |d S )aw  Yield successive distinct permutations of the elements in *iterable*.

        >>> sorted(distinct_permutations([1, 0, 1]))
        [(0, 1, 1), (1, 0, 1), (1, 1, 0)]

    Equivalent to ``set(permutations(iterable))``, except duplicates are not
    generated and thrown away. For larger input sequences this is much more
    efficient.

    Duplicate permutations arise when there are duplicated elements in the
    input iterable. The number of items returned is
    `n! / (x_1! * x_2! * ... * x_n!)`, where `n` is the total number of
    items input, and each `x_i` is the count of a distinct item in the input
    sequence.

    c                 3   st   |dk rt |V  n\| D ]V}| | dkr*q|||< | |  d8  <  | ||d D ]
}|V  qR| |  d7  < qdS )a  Internal helper function

        :arg item_counts: Stores the unique items in ``iterable`` and how many
            times they are repeated
        :arg perm: The permutation that is being built for output
        :arg i: The index of the permutation being modified

        The output permutations are built up recursively; the distinct items
        are placed until their repetitions are exhausted.
        r   r"   N)tuple)item_countsZpermir   r   perm_unique_helperrZ   r[   r     s    z1distinct_permutations.<locals>.perm_unique_helperNr"   )r   sumvalues)rX   r   ZlengthrZ   r   r[   r2     s    c                 C   s^   |dkrt dnH|dkr0ttt| |ddS t| g}t||}ttt||ddS dS )a6  Intersperse filler element *e* among the items in *iterable*, leaving
    *n* items between each filler element.

        >>> list(intersperse('!', [1, 2, 3, 4, 5]))
        [1, '!', 2, '!', 3, '!', 4, '!', 5]

        >>> list(intersperse(None, [1, 2, 3, 4, 5], n=2))
        [1, 2, None, 3, 4, None, 5]

    r   zn must be > 0r"   N)r_   r   r:   r   r*   r$   )erX   rY   ZfillerZchunksrZ   rZ   r[   r;   ,  s    


c                     sF   dd | D }t ttt|  fdd D fdd|D S )a  Return the elements from each of the input iterables that aren't in the
    other input iterables.

    For example, suppose you have a set of packages, each with a set of
    dependencies::

        {'pkg_1': {'A', 'B'}, 'pkg_2': {'B', 'C'}, 'pkg_3': {'B', 'D'}}

    If you remove one package, which dependencies can also be removed?

    If ``pkg_1`` is removed, then ``A`` is no longer necessary - it is not
    associated with ``pkg_2`` or ``pkg_3``. Similarly, ``C`` is only needed for
    ``pkg_2``, and ``D`` is only needed for ``pkg_3``::

        >>> unique_to_each({'A', 'B'}, {'B', 'C'}, {'B', 'D'})
        [['A'], ['C'], ['D']]

    If there are duplicates in one input iterable that aren't in the others
    they will be duplicated in the output. Input order is preserved::

        >>> unique_to_each("mississippi", "missouri")
        [['p', 'p'], ['o', 'u', 'r']]

    It is assumed that the elements of each iterable are hashable.

    c                 S   s   g | ]}t |qS rZ   )r|   r   rZ   rZ   r[   r   a  s     z"unique_to_each.<locals>.<listcomp>c                    s   h | ]} | d kr|qS )r"   rZ   )r   element)countsrZ   r[   	<setcomp>c  s      z!unique_to_each.<locals>.<setcomp>c                    s   g | ]}t t j|qS rZ   )r|   r   __contains__r   )uniquesrZ   r[   r   d  s     )r   r	   from_iterabler   set)r   ZpoolrZ   )r   r   r[   rS   F  s    c           
      c   s   |dk rt d|dkr$t V  dS |dk r4t dt| }tg |}|j}t|D ]}|t|| qTt|V  d}|D ].}	||	 |d | }|| dkrzt|V  qz|| r|| |k rt|| D ]}|| qt|V  dS )a  Return a sliding window of width *n* over the given iterable.

        >>> all_windows = windowed([1, 2, 3, 4, 5], 3)
        >>> list(all_windows)
        [(1, 2, 3), (2, 3, 4), (3, 4, 5)]

    When the window is larger than the iterable, *fillvalue* is used in place
    of missing values::

        >>> list(windowed([1, 2, 3], 4))
        [(1, 2, 3, None)]

    Each window will advance in increments of *step*:

        >>> list(windowed([1, 2, 3, 4, 5, 6], 3, fillvalue='!', step=2))
        [(1, 2, 3), (3, 4, 5), (5, 6, '!')]

    r   zn must be >= 0Nr"   zstep must be >= 1)r_   r   rW   r   rm   r   r\   )
seqrY   	fillvalueru   r   Zwindowrm   r   r   r   rZ   rZ   r[   rT   g  s.    


c                   @   s2   e Zd ZdZdddZdd Zdd Zd	d
 ZdS )r)   a  Wrap *iterable* and return an object that buckets it iterable into
    child iterables based on a *key* function.

        >>> iterable = ['a1', 'b1', 'c1', 'a2', 'b2', 'c2', 'b3']
        >>> s = bucket(iterable, key=lambda x: x[0])
        >>> a_iterable = s['a']
        >>> next(a_iterable)
        'a1'
        >>> next(a_iterable)
        'a2'
        >>> list(s['b'])
        ['b1', 'b2', 'b3']

    The original iterable will be advanced and its items will be cached until
    they are used by the child iterables. This may require significant storage.

    By default, attempting to select a bucket to which no items belong  will
    exhaust the iterable and cache all values.
    If you specify a *validator* function, selected buckets will instead be
    checked against it.

        >>> from itertools import count
        >>> it = count(1, 2)  # Infinite sequence of odd numbers
        >>> key = lambda x: x % 10  # Bucket by last digit
        >>> validator = lambda x: x in {1, 3, 5, 7, 9}  # Odd digits only
        >>> s = bucket(it, key=key, validator=validator)
        >>> 2 in s
        False
        >>> list(s[2])
        []

    Nc                 C   s,   t || _|| _tt| _|p$dd | _d S )Nc                 S   s   dS )NTrZ   r   rZ   rZ   r[   r     r   z!bucket.__init__.<locals>.<lambda>)rW   rb   _keyr   r   rc   
_validator)re   rX   r   Z	validatorrZ   rZ   r[   rf     s    

zbucket.__init__c                 C   sJ   |  |sdS zt| | }W n tk
r4   Y dS X | j| | dS ri   )r   r\   r]   rc   
appendleft)re   r   r   rZ   rZ   r[   r     s    
zbucket.__contains__c                 c   s   | j | r| j |  V  q zt| j}W n tk
r@   Y dS X | |}||kr^|V  q q| |r| j | | qq dS )z
        Helper to yield items from the parent iterator that match *value*.
        Items that don't match are stored in the local cache as they
        are encountered.
        N)rc   rr   r\   rb   r]   r   r   rm   )re   r   r   Z
item_valuerZ   rZ   r[   _get_values  s    	


zbucket._get_valuesc                 C   s   |  |stdS | |S )NrZ   )r   rW   r   )re   r   rZ   rZ   r[   r     s    
zbucket.__getitem__)N)r   r   r   r   rf   r   r   r   rZ   rZ   rZ   r[   r)     s
    
c                 C   s    t | }t||}|t||fS )a  Return a 2-tuple with a list containing the first *n* elements of
    *iterable*, and an iterator with the same items as *iterable*.
    This allows you to "look ahead" at the items in the iterable without
    advancing it.

    There is one item in the list by default:

        >>> iterable = 'abcdefg'
        >>> head, iterable = spy(iterable)
        >>> head
        ['a']
        >>> list(iterable)
        ['a', 'b', 'c', 'd', 'e', 'f', 'g']

    You may use unpacking to retrieve items instead of lists:

        >>> (head,), iterable = spy('abcdefg')
        >>> head
        'a'
        >>> (first, second), iterable = spy('abcdefg', 2)
        >>> first
        'a'
        >>> second
        'b'

    The number of items requested can be larger than the number of items in
    the iterable:

        >>> iterable = [1, 2, 3, 4, 5]
        >>> head, iterable = spy(iterable, 10)
        >>> head
        [1, 2, 3, 4, 5]
        >>> list(iterable)
        [1, 2, 3, 4, 5]

    )rW   r%   r	   )rX   rY   r   headrZ   rZ   r[   rP     s    %
c                  G   s   t t|  S )a4  Return a new iterable yielding from each iterable in turn,
    until the shortest is exhausted.

        >>> list(interleave([1, 2, 3], [4, 5], [6, 7, 8]))
        [1, 4, 6, 2, 5, 7]

    For a version that doesn't terminate after the shortest iterable is
    exhausted, see :func:`interleave_longest`.

    )r	   r   r    )r   rZ   rZ   r[   r:     s    c                  G   s"   t t| dti}dd |D S )as  Return a new iterable yielding from each iterable in turn,
    skipping any that are exhausted.

        >>> list(interleave_longest([1, 2, 3], [4, 5], [6, 7, 8]))
        [1, 4, 6, 2, 5, 7, 3, 8]

    This function produces the same output as :func:`roundrobin`, but may
    perform better for some inputs (in particular when the number of iterables
    is large).

    r   c                 s   s   | ]}|t k	r|V  qd S ra   )r^   r   rZ   rZ   r[   r   6  s      z%interleave_longest.<locals>.<genexpr>)r	   r   r!   r^   )r   r   rZ   rZ   r[   r9   )  s    c                 #   s*    fdd| dD ]
}|V  qdS )a.  Flatten an iterable with multiple levels of nesting (e.g., a list of
    lists of tuples) into non-iterable types.

        >>> iterable = [(1, 2), ([3, 4], [[5], [6]])]
        >>> list(collapse(iterable))
        [1, 2, 3, 4, 5, 6]

    String types are not considered iterable and will not be collapsed.
    To avoid collapsing other types, specify *base_type*:

        >>> iterable = ['ab', ('cd', 'ef'), ['gh', 'ij']]
        >>> list(collapse(iterable, base_type=tuple))
        ['ab', ('cd', 'ef'), 'gh', 'ij']

    Specify *levels* to stop flattening after a certain level:

    >>> iterable = [('a', ['b']), ('c', ['d'])]
    >>> list(collapse(iterable))  # Fully flattened
    ['a', 'b', 'c', 'd']
    >>> list(collapse(iterable, levels=1))  # Only one level flattened
    ['a', ['b'], 'c', ['d']]

    c                 3   s   d k	r|ks,t | ts, d k	r6t |  r6| V  d S zt| }W n tk
r^   | V  Y d S X |D ]}||d D ]
}|V  qvqdd S Nr"   )r   r   rW   	TypeError)ZnodelevelZtreeZchildr   	base_typelevelswalkrZ   r[   r   Q  s(    zcollapse.<locals>.walkr   NrZ   )rX   r   r   r   rZ   r   r[   r,   9  s    c                 c   sr   z\|dk	r|  |dkr2|D ]}| | |V  qn(t ||D ]}| | |D ]
}|V  qLq<W 5 |dk	rl|  X dS )au  Invoke *func* on each item in *iterable* (or on each *chunk_size* group
    of items) before yielding the item.

    `func` must be a function that takes a single argument. Its return value
    will be discarded.

    *before* and *after* are optional functions that take no arguments. They
    will be executed before iteration starts and after it ends, respectively.

    `side_effect` can be used for logging, updating progress bars, or anything
    that is not functionally "pure."

    Emitting a status message:

        >>> from more_itertools import consume
        >>> func = lambda item: print('Received {}'.format(item))
        >>> consume(side_effect(func, range(2)))
        Received 0
        Received 1

    Operating on chunks of items:

        >>> pair_sums = []
        >>> func = lambda chunk: pair_sums.append(sum(chunk))
        >>> list(side_effect(func, [0, 1, 2, 3, 4, 5], 2))
        [0, 1, 2, 3, 4, 5]
        >>> list(pair_sums)
        [1, 5, 9]

    Writing to a file-like object:

        >>> from io import StringIO
        >>> from more_itertools import consume
        >>> f = StringIO()
        >>> func = lambda x: print(x, file=f)
        >>> before = lambda: print(u'HEADER', file=f)
        >>> after = f.close
        >>> it = [u'a', u'b', u'c']
        >>> consume(side_effect(func, it, before=before, after=after))
        >>> f.closed
        True

    N)r*   )r   rX   Z
chunk_sizeZbeforeZafterr   chunkrZ   rZ   r[   rJ   h  s    ,
c                    s    t t fddtd D S )a  Yield slices of length *n* from the sequence *seq*.

        >>> list(sliced((1, 2, 3, 4, 5, 6), 3))
        [(1, 2, 3), (4, 5, 6)]

    If the length of the sequence is not divisible by the requested slice
    length, the last slice will be shorter.

        >>> list(sliced((1, 2, 3, 4, 5, 6, 7, 8), 3))
        [(1, 2, 3), (4, 5, 6), (7, 8)]

    This function will only work for iterables that support slicing.
    For non-sliceable iterables, see :func:`chunked`.

    c                 3   s   | ]}||   V  qd S ra   rZ   )r   r   rY   r   rZ   r[   r     s     zsliced.<locals>.<genexpr>r   )r   boolr   )r   rY   rZ   r   r[   rK     s    c                 c   s6   g }| D ]"}||r |V  g }q| | q|V  dS )aw  Yield lists of items from *iterable*, where each list is delimited by
    an item where callable *pred* returns ``True``. The lists do not include
    the delimiting items.

        >>> list(split_at('abcdcba', lambda x: x == 'b'))
        [['a'], ['c', 'd', 'c'], ['a']]

        >>> list(split_at(range(10), lambda n: n % 2 == 1))
        [[0], [2], [4], [6], [8], []]
    Nrm   rX   predZbufr   rZ   rZ   r[   rM     s    c                 c   s8   g }| D ]$}||r"|r"|V  g }| | q|V  dS )aW  Yield lists of items from *iterable*, where each list starts with an
    item where callable *pred* returns ``True``:

        >>> list(split_before('OneTwo', lambda s: s.isupper()))
        [['O', 'n', 'e'], ['T', 'w', 'o']]

        >>> list(split_before(range(10), lambda n: n % 3 == 0))
        [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

    Nr   r   rZ   rZ   r[   rO     s    c                 c   s<   g }| D ]$}| | ||r|r|V  g }q|r8|V  dS )a_  Yield lists of items from *iterable*, where each list ends with an
    item where callable *pred* returns ``True``:

        >>> list(split_after('one1two2', lambda s: s.isdigit()))
        [['o', 'n', 'e', '1'], ['t', 'w', 'o', '2']]

        >>> list(split_after(range(10), lambda n: n % 3 == 0))
        [[0], [1, 2, 3], [4, 5, 6], [7, 8, 9]]

    Nr   r   rZ   rZ   r[   rN     s    
Fc           	      c   s   t | }|dkr,t|t|D ]
}|V  qnZ|dk r>tdnHd}|D ]}|V  |d7 }qF|rj|| | n|| }t|D ]
}|V  qzdS )a  Yield the elements from *iterable*, followed by *fillvalue*, such that
    at least *n* items are emitted.

        >>> list(padded([1, 2, 3], '?', 5))
        [1, 2, 3, '?', '?']

    If *next_multiple* is ``True``, *fillvalue* will be emitted until the
    number of items emitted is a multiple of *n*::

        >>> list(padded([1, 2, 3, 4], n=3, next_multiple=True))
        [1, 2, 3, 4, None, None]

    If *n* is ``None``, *fillvalue* will be emitted indefinitely.

    Nr"   n must be at least 1r   )rW   r	   r   r_   r   )	rX   r   rY   Znext_multipler   r   Z
item_countZ	remainingr   rZ   rZ   r[   rD     s    


c                    s0    dk rt dt| } fddt|D S )a  Distribute the items from *iterable* among *n* smaller iterables.

        >>> group_1, group_2 = distribute(2, [1, 2, 3, 4, 5, 6])
        >>> list(group_1)
        [1, 3, 5]
        >>> list(group_2)
        [2, 4, 6]

    If the length of *iterable* is not evenly divisible by *n*, then the
    length of the returned iterables will not be identical:

        >>> children = distribute(3, [1, 2, 3, 4, 5, 6, 7])
        >>> [list(c) for c in children]
        [[1, 4, 7], [2, 5], [3, 6]]

    If the length of *iterable* is smaller than *n*, then the last returned
    iterables will be empty:

        >>> children = distribute(5, [1, 2, 3])
        >>> [list(c) for c in children]
        [[1], [2], [3], [], []]

    This function uses :func:`itertools.tee` and may require significant
    storage. If you need the order items in the smaller iterables to match the
    original iterable, see :func:`divide`.

    r"   r   c                    s   g | ]\}}t ||d  qS ra   )r   )r   r}   r   rY   rZ   r[   r   8  s     zdistribute.<locals>.<listcomp>)r_   r   r   )rY   rX   childrenrZ   r   r[   r3     s    
rt   r   r"   c                 C   s    t | t|}t||||dS )a[  Yield tuples whose elements are offset from *iterable*.
    The amount by which the `i`-th item in each tuple is offset is given by
    the `i`-th item in *offsets*.

        >>> list(stagger([0, 1, 2, 3]))
        [(None, 0, 1), (0, 1, 2), (1, 2, 3)]
        >>> list(stagger(range(8), offsets=(0, 2, 4)))
        [(0, 2, 4), (1, 3, 5), (2, 4, 6), (3, 5, 7)]

    By default, the sequence will end when the final element of a tuple is the
    last item in the iterable. To continue until the first element of a tuple
    is the last item in the iterable, set *longest* to ``True``::

        >>> list(stagger([0, 1, 2, 3], longest=True))
        [(None, 0, 1), (0, 1, 2), (1, 2, 3), (2, 3, None), (3, None, None)]

    By default, ``None`` will be used to replace offsets beyond the end of the
    sequence. Specify *fillvalue* to use some other value.

    )offsetslongestr   )r   r{   rV   )rX   r   r   r   r   rZ   rZ   r[   rQ   ;  s       c                  O   s   |d }| dd}| dd}t| t|kr8tdg }t| |D ]P\}}|dk rp|tt|| | qF|dkr|t||d qF|| qF|rt|d|iS t| S )aG  ``zip`` the input *iterables* together, but offset the `i`-th iterable
    by the `i`-th item in *offsets*.

        >>> list(zip_offset('0123', 'abcdef', offsets=(0, 1)))
        [('0', 'b'), ('1', 'c'), ('2', 'd'), ('3', 'e')]

    This can be used as a lightweight alternative to SciPy or pandas to analyze
    data sets in which somes series have a lead or lag relationship.

    By default, the sequence will end when the shortest iterable is exhausted.
    To continue until the longest iterable is exhausted, set *longest* to
    ``True``.

        >>> list(zip_offset('0123', 'abcdef', offsets=(0, 1), longest=True))
        [('0', 'b'), ('1', 'c'), ('2', 'd'), ('3', 'e'), (None, 'f')]

    By default, ``None`` will be used to replace offsets beyond the end of the
    sequence. Specify *fillvalue* to use some other value.

    r   r   Fr   Nz,Number of iterables and offsets didn't matchr   )	getr{   r_   r    rm   r	   r   r   r!   )r   r   r   r   r   Z	staggeredr   rY   rZ   rZ   r[   rV   W  s    r   c                 C   s   t ttt|  t| |d S )a  Return the input iterables sorted together, with *key_list* as the
    priority for sorting. All iterables are trimmed to the length of the
    shortest one.

    This can be used like the sorting function in a spreadsheet. If each
    iterable represents a column of data, the key list determines which
    columns are used for sorting.

    By default, all iterables are sorted using the ``0``-th iterable::

        >>> iterables = [(4, 3, 2, 1), ('a', 'b', 'c', 'd')]
        >>> sort_together(iterables)
        [(1, 2, 3, 4), ('d', 'c', 'b', 'a')]

    Set a different key list to sort according to another iterable.
    Specifying mutliple keys dictates how ties are broken::

        >>> iterables = [(3, 1, 2), (0, 1, 0), ('c', 'b', 'a')]
        >>> sort_together(iterables, key_list=(1, 2))
        [(2, 3, 1), (0, 0, 1), ('a', 'c', 'b')]

    Set *reverse* to ``True`` to sort in descending order.

        >>> sort_together([(1, 2, 3), ('c', 'b', 'a')], reverse=True)
        [(3, 2, 1), ('a', 'b', 'c')]

    )r   r   )r|   r    sortedr   )r   Zkey_listr   rZ   rZ   r[   rL     s    c           	      C   s   | dk rt dt|}tt|| \}}g }t| D ]V}|| ||k rL|n| }|d | |d |k rp|d n| }|t|||  q6|S )a  Divide the elements from *iterable* into *n* parts, maintaining
    order.

        >>> group_1, group_2 = divide(2, [1, 2, 3, 4, 5, 6])
        >>> list(group_1)
        [1, 2, 3]
        >>> list(group_2)
        [4, 5, 6]

    If the length of *iterable* is not evenly divisible by *n*, then the
    length of the returned iterables will not be identical:

        >>> children = divide(3, [1, 2, 3, 4, 5, 6, 7])
        >>> [list(c) for c in children]
        [[1, 2, 3], [4, 5], [6, 7]]

    If the length of the iterable is smaller than n, then the last returned
    iterables will be empty:

        >>> children = divide(5, [1, 2, 3])
        >>> [list(c) for c in children]
        [[1], [2], [3], [], []]

    This function will exhaust the iterable before returning and may require
    significant storage. If order is not important, see :func:`distribute`,
    which does not first pull the iterable into memory.

    r"   r   )r_   r   divmodr{   r   rm   rW   )	rY   rX   r   qrretr   rv   rw   rZ   rZ   r[   r4     s    $c                 C   sZ   | dkrt dS |dk	r,t| |r,t | fS z
t | W S  tk
rT   t | f Y S X dS )ax  If *obj* is iterable, return an iterator over its items::

        >>> obj = (1, 2, 3)
        >>> list(always_iterable(obj))
        [1, 2, 3]

    If *obj* is not iterable, return a one-item iterable containing *obj*::

        >>> obj = 1
        >>> list(always_iterable(obj))
        [1]

    If *obj* is ``None``, return an empty iterable:

        >>> obj = None
        >>> list(always_iterable(None))
        []

    By default, binary and text strings are not considered iterable::

        >>> obj = 'foo'
        >>> list(always_iterable(obj))
        ['foo']

    If *base_type* is set, objects for which ``isinstance(obj, base_type)``
    returns ``True`` won't be considered iterable.

        >>> obj = {'a': 1}
        >>> list(always_iterable(obj))  # Iterate over the dict's keys
        ['a']
        >>> list(always_iterable(obj, base_type=dict))  # Treat dicts as a unit
        [{'a': 1}]

    Set *base_type* to ``None`` to avoid any special handling and treat objects
    Python considers iterable as iterable:

        >>> obj = 'foo'
        >>> list(always_iterable(obj, base_type=None))
        ['f', 'o', 'o']
    NrZ   )rW   r   r   )objr   rZ   rZ   r[   r'     s    )

c                 C   sZ   |dk rt dt|\}}dg| }t|t| ||}ttt|d| d }t||S )as  Return an iterable over `(bool, item)` tuples where the `item` is
    drawn from *iterable* and the `bool` indicates whether
    that item satisfies the *predicate* or is adjacent to an item that does.

    For example, to find whether items are adjacent to a ``3``::

        >>> list(adjacent(lambda x: x == 3, range(6)))
        [(False, 0), (False, 1), (True, 2), (True, 3), (True, 4), (False, 5)]

    Set *distance* to change what counts as adjacent. For example, to find
    whether items are two places away from a ``3``:

        >>> list(adjacent(lambda x: x == 3, range(6), distance=2))
        [(False, 0), (True, 1), (True, 2), (True, 3), (True, 4), (True, 5)]

    This is useful for contextualizing the results of a search function.
    For example, a code comparison tool might want to identify lines that
    have changed, but also surrounding lines to give the viewer of the diff
    context.

    The predicate function will only be called once for each item in the
    iterable.

    See also :func:`groupby_transform`, which can be used with this function
    to group ranges of items with the same `bool` value.

    r   zdistance must be at least 0F   r"   )r_   r   r	   r   anyrT   r    )	predicaterX   ZdistanceZi1Zi2ZpaddingZselectedZadjacent_to_selectedrZ   rZ   r[   r&     s    
c                    s,    dkrdd n   fddt | |D S )a  An extension of :func:`itertools.groupby` that transforms the values of
    *iterable* after grouping them.
    *keyfunc* is a function used to compute a grouping key for each item.
    *valuefunc* is a function for transforming the items after grouping.

        >>> iterable = 'AaaABbBCcA'
        >>> keyfunc = lambda x: x.upper()
        >>> valuefunc = lambda x: x.lower()
        >>> grouper = groupby_transform(iterable, keyfunc, valuefunc)
        >>> [(k, ''.join(g)) for k, g in grouper]
        [('A', 'aaaa'), ('B', 'bbb'), ('C', 'cc'), ('A', 'a')]

    *keyfunc* and *valuefunc* default to identity functions if they are not
    specified.

    :func:`groupby_transform` is useful when grouping elements of an iterable
    using a separate iterable as the key. To do this, :func:`zip` the iterables
    and pass a *keyfunc* that extracts the first element and a *valuefunc*
    that extracts the second element::

        >>> from operator import itemgetter
        >>> keys = [0, 0, 1, 1, 1, 2, 2, 2, 3]
        >>> values = 'abcdefghi'
        >>> iterable = zip(keys, values)
        >>> grouper = groupby_transform(iterable, itemgetter(0), itemgetter(1))
        >>> [(k, ''.join(g)) for k, g in grouper]
        [(0, 'ab'), (1, 'cde'), (2, 'fgh'), (3, 'i')]

    Note that the order of items in the iterable is significant.
    Only adjacent items are grouped together, so if you don't want any
    duplicate groups, you should sort the iterable by the key function.

    Nc                 S   s   | S ra   rZ   r   rZ   rZ   r[   r   M  r   z#groupby_transform.<locals>.<lambda>c                 3   s    | ]\}}|t  |fV  qd S ra   )r   r   kg	valuefuncrZ   r[   r   N  s     z$groupby_transform.<locals>.<genexpr>r   )rX   keyfuncr   rZ   r   r[   r7   +  s    "c                     s   t | }|dkr(| \}t|d dn<|dkr>| \ }dn&|dkrR| \ }nd}t|| fddt D }dkrttt||S dk rttt||S t	dd	S )
aR  An extension of the built-in ``range()`` function whose arguments can
    be any orderable numeric type.

    With only *stop* specified, *start* defaults to ``0`` and *step*
    defaults to ``1``. The output items will match the type of *stop*:

        >>> list(numeric_range(3.5))
        [0.0, 1.0, 2.0, 3.0]

    With only *start* and *stop* specified, *step* defaults to ``1``. The
    output items will match the type of *start*:

        >>> from decimal import Decimal
        >>> start = Decimal('2.1')
        >>> stop = Decimal('5.1')
        >>> list(numeric_range(start, stop))
        [Decimal('2.1'), Decimal('3.1'), Decimal('4.1')]

    With *start*, *stop*, and *step*  specified the output items will match
    the type of ``start + step``:

        >>> from fractions import Fraction
        >>> start = Fraction(1, 2)  # Start at 1/2
        >>> stop = Fraction(5, 2)  # End at 5/2
        >>> step = Fraction(1, 2)  # Count by 1/2
        >>> list(numeric_range(start, stop, step))
        [Fraction(1, 2), Fraction(1, 1), Fraction(3, 2), Fraction(2, 1)]

    If *step* is zero, ``ValueError`` is raised. Negative steps are supported:

        >>> list(numeric_range(3, -1, -1.0))
        [3.0, 2.0, 1.0, 0.0]

    Be aware of the limitations of floating point numbers; the representation
    of the yielded numbers may be surprising.

    r"   r   r   r   z/numeric_range takes at most 3 arguments, got {}c                 3   s   | ]} |  V  qd S ra   rZ   )r   rY   rv   ru   rZ   r[   r     s     z numeric_range.<locals>.<genexpr>z$numeric_range arg 3 must not be zeroN)
r{   typer   formatr   r   r   r   r   r_   )r   Zargcrw   err_msgr   rZ   r   r[   rB   Q  s$    &c                    s<   t    stdS |dkr"t nt|} fdd|D S )a  Cycle through the items from *iterable* up to *n* times, yielding
    the number of completed cycles along with each item. If *n* is omitted the
    process repeats indefinitely.

    >>> list(count_cycle('AB', 3))
    [(0, 'A'), (0, 'B'), (1, 'A'), (1, 'B'), (2, 'A'), (2, 'B')]

    rZ   Nc                 3   s    | ]} D ]}||fV  q
qd S ra   rZ   )r   r   r   rX   rZ   r[   r     s       zcount_cycle.<locals>.<genexpr>)r   rW   r   r   )rX   rY   ZcounterrZ   r   r[   r0     s
    	c                 C   s   t t t|| S )a  Yield the index of each item in *iterable* for which *pred* returns
    ``True``.

    *pred* defaults to :func:`bool`, which will select truthy items:

        >>> list(locate([0, 1, 1, 0, 1, 0, 0]))
        [1, 2, 4]

    Set *pred* to a custom function to, e.g., find the indexes for a particular
    item:

        >>> list(locate(['a', 'b', 'c', 'b'], lambda x: x == 'b'))
        [1, 3]

    Use with :func:`windowed` to find the indexes of a sub-sequence:

        >>> from more_itertools import windowed
        >>> iterable = [0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]
        >>> sub = [1, 2, 3]
        >>> pred = lambda w: w == tuple(sub)  # windowed() returns tuples
        >>> list(locate(windowed(iterable, len(sub)), pred=pred))
        [1, 5, 9]

    Use with :func:`seekable` to find indexes and then retrieve the associated
    items:

        >>> from itertools import count
        >>> from more_itertools import seekable
        >>> source = (3 * n + 1 if (n % 2) else n // 2 for n in count())
        >>> it = seekable(source)
        >>> pred = lambda x: x > 100
        >>> indexes = locate(it, pred=pred)
        >>> i = next(indexes)
        >>> it.seek(i)
        >>> next(it)
        106

    )r
   r   r   rX   r   rZ   rZ   r[   r>     s    'c                 C   s
   t || S )a  Yield the items from *iterable*, but strip any from the beginning
    for which *pred* returns ``True``.

    For example, to remove a set of items from the start of an iterable:

        >>> iterable = (None, False, None, 1, 2, None, 3, False, None)
        >>> pred = lambda x: x in {None, False, ''}
        >>> list(lstrip(iterable, pred))
        [1, 2, None, 3, False, None]

    This function is analogous to to :func:`str.lstrip`, and is essentially
    an wrapper for :func:`itertools.dropwhile`.

    )r   r   rZ   rZ   r[   r?     s    c                 c   sJ   g }|j }| D ]6}||r$|| q|D ]
}|V  q(|dd= |V  qdS )a  Yield the items from *iterable*, but strip any from the end
    for which *pred* returns ``True``.

    For example, to remove a set of items from the end of an iterable:

        >>> iterable = (None, False, None, 1, 2, None, 3, False, None)
        >>> pred = lambda x: x in {None, False, ''}
        >>> list(rstrip(iterable, pred))
        [None, False, None, 1, 2, None, 3]

    This function is analogous to :func:`str.rstrip`.

    Nr   )rX   r   cacheZcache_appendr   yrZ   rZ   r[   rF     s    

c                 C   s   t t| ||S )a  Yield the items from *iterable*, but strip any from the
    beginning and end for which *pred* returns ``True``.

    For example, to remove a set of items from both ends of an iterable:

        >>> iterable = (None, False, None, 1, 2, None, 3, False, None)
        >>> pred = lambda x: x in {None, False, ''}
        >>> list(strip(iterable, pred))
        [1, 2, None, 3]

    This function is analogous to :func:`str.strip`.

    )rF   r?   r   rZ   rZ   r[   rR     s    c                 g   s  t | }|j}|j}|jdkr&td|jp.d}t| }|dkr|dkrNdn|}|dk rtt|d| d}|r~|d d nd}t|| d}	|dkr|}
n"|dkrt	||}
nt|| d}
|
|	 }|dkrdS t
|d||D ]\}}|V  qn|dk	rl|dk rltt
|||d tt
|| | d}t|D ]0\}}| }|| dkr\|V  || q8nt
||||D ]}|V  qzn<|dkrdn|}|dk	r4|dk r4| d }tt|d|d}|r|d d nd}|dk r|| }	}
nt	|| dd }	}
t||	|
| D ]\}}|V  q n|dk	rX|d }tt
|||d |dk rl|}	d}n2|dkrd}	|d }nd}	|| }|dkrdS tt
||}||	d| D ]}|V  qdS )aH  An extension of :func:`itertools.islice` that supports negative values
    for *stop*, *start*, and *step*.

        >>> iterable = iter('abcdefgh')
        >>> list(islice_extended(iterable, -4, -1))
        ['e', 'f', 'g']

    Slices with negative values require some caching of *iterable*, but this
    function takes care to minimize the amount of memory required.

    For example, you can use a negative step with an infinite iterator:

        >>> from itertools import count
        >>> list(islice_extended(count(), 110, 99, -2))
        [110, 108, 106, 104, 102, 100]

    r   z1step argument must be a non-zero integer or None.r"   Nr   rt   )r   rv   rw   ru   r_   rW   r   r   rz   ry   r   r\   rr   rm   r|   )rX   r   srv   rw   ru   r   r   Zlen_iterr   jrY   r}   r   Zcached_itemmrZ   rZ   r[   r<     sv    










c                 C   s0   z
t | W S  tk
r*   t t|  Y S X dS )a  An extension of :func:`reversed` that supports all iterables, not
    just those which implement the ``Reversible`` or ``Sequence`` protocols.

        >>> print(*always_reversible(x for x in range(3)))
        2 1 0

    If the iterable is already reversible, this function returns the
    result of :func:`reversed()`. If the iterable is not reversible,
    this function will cache the remaining items in the iterable and
    yield them in reverse order, which may require significant storage.
    N)ro   r   r|   r   rZ   rZ   r[   r(   {  s    
c                 C   s   | S ra   rZ   r   rZ   rZ   r[   r     r   r   c                 #   s6   t t|  fdddD ]\}}ttd|V  qdS )a  Yield groups of consecutive items using :func:`itertools.groupby`.
    The *ordering* function determines whether two items are adjacent by
    returning their position.

    By default, the ordering function is the identity function. This is
    suitable for finding runs of numbers:

        >>> iterable = [1, 10, 11, 12, 20, 30, 31, 32, 33, 40]
        >>> for group in consecutive_groups(iterable):
        ...     print(list(group))
        [1]
        [10, 11, 12]
        [20]
        [30, 31, 32, 33]
        [40]

    For finding runs of adjacent letters, try using the :meth:`index` method
    of a string of letters:

        >>> from string import ascii_lowercase
        >>> iterable = 'abcdfgilmnop'
        >>> ordering = ascii_lowercase.index
        >>> for group in consecutive_groups(iterable, ordering):
        ...     print(list(group))
        ['a', 'b', 'c', 'd']
        ['f', 'g']
        ['i']
        ['l', 'm', 'n', 'o', 'p']

    c                    s   | d  | d  S r   rZ   r   orderingrZ   r[   r     r   z$consecutive_groups.<locals>.<lambda>r   r"   N)r   r   r   r   )rX   r   r   r   rZ   r   r[   r.     s
     
c                    sV   t | \}}zt|}W n tk
r4   tg  Y S X t|gt fddt||S )a  By default, compute the first difference of *iterable* using
    :func:`operator.sub`.

        >>> iterable = [0, 1, 3, 6, 10]
        >>> list(difference(iterable))
        [0, 1, 2, 3, 4]

    This is the opposite of :func:`accumulate`'s default behavior:

        >>> from more_itertools import accumulate
        >>> iterable = [0, 1, 2, 3, 4]
        >>> list(accumulate(iterable))
        [0, 1, 3, 6, 10]
        >>> list(difference(accumulate(iterable)))
        [0, 1, 2, 3, 4]

    By default *func* is :func:`operator.sub`, but other functions can be
    specified. They will be applied as follows::

        A, B, C, D, ... --> A, func(B, A), func(C, B), func(D, C), ...

    For example, to do progressive division:

        >>> iterable = [1, 2, 6, 24, 120]  # Factorial sequence
        >>> func = lambda x, y: x // y
        >>> list(difference(iterable, func))
        [1, 2, 3, 4, 5]

    c                    s    | d | d S )Nr"   r   rZ   r   r   rZ   r[   r     r   zdifference.<locals>.<lambda>)r   r\   r]   rW   r	   r   r    )rX   r   r   br   rZ   r   r[   r1     s    c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )rI   aS  Return a read-only view of the sequence object *target*.

    :class:`SequenceView` objects are analagous to Python's built-in
    "dictionary view" types. They provide a dynamic view of a sequence's items,
    meaning that when the sequence updates, so does the view.

        >>> seq = ['0', '1', '2']
        >>> view = SequenceView(seq)
        >>> view
        SequenceView(['0', '1', '2'])
        >>> seq.append('3')
        >>> view
        SequenceView(['0', '1', '2', '3'])

    Sequence views support indexing, slicing, and length queries. They act
    like the underlying sequence, except they don't allow assignment:

        >>> view[1]
        '1'
        >>> view[1:-1]
        ['1', '2']
        >>> len(view)
        4

    Sequence views are useful as an alternative to copying, as they don't
    require (much) extra storage.

    c                 C   s   t |tst|| _d S ra   )r   r   r   _target)re   targetrZ   rZ   r[   rf     s    
zSequenceView.__init__c                 C   s
   | j | S ra   )r   )re   r}   rZ   rZ   r[   r     s    zSequenceView.__getitem__c                 C   s
   t | jS ra   )r{   r   rg   rZ   rZ   r[   __len__  s    zSequenceView.__len__c                 C   s   d | jjt| jS )Nz{}({}))r   	__class__r   reprr   rg   rZ   rZ   r[   __repr__   s    zSequenceView.__repr__N)r   r   r   r   rf   r   r   r   rZ   rZ   rZ   r[   rI     s
   c                   @   s<   e Zd ZdZdd Zdd Zdd ZeZdd	 Zd
d Z	dS )rH   a  Wrap an iterator to allow for seeking backward and forward. This
    progressively caches the items in the source iterable so they can be
    re-visited.

    Call :meth:`seek` with an index to seek to that position in the source
    iterable.

    To "reset" an iterator, seek to ``0``:

        >>> from itertools import count
        >>> it = seekable((str(n) for n in count()))
        >>> next(it), next(it), next(it)
        ('0', '1', '2')
        >>> it.seek(0)
        >>> next(it), next(it), next(it)
        ('0', '1', '2')
        >>> next(it)
        '3'

    You can also seek forward:

        >>> it = seekable((str(n) for n in range(20)))
        >>> it.seek(10)
        >>> next(it)
        '10'
        >>> it.seek(20)  # Seeking past the end of the source isn't a problem
        >>> list(it)
        []
        >>> it.seek(0)  # Resetting works even after hitting the end
        >>> next(it), next(it), next(it)
        ('0', '1', '2')

    The cache grows as the source iterable progresses, so beware of wrapping
    very large or infinite iterables.

    You may view the contents of the cache with the :meth:`elements` method.
    That returns a :class:`SequenceView`, a view that updates automatically:

        >>> it = seekable((str(n) for n in range(10)))
        >>> next(it), next(it), next(it)
        ('0', '1', '2')
        >>> elements = it.elements()
        >>> elements
        SequenceView(['0', '1', '2'])
        >>> next(it)
        '3'
        >>> elements
        SequenceView(['0', '1', '2', '3'])

    c                 C   s   t || _g | _d | _d S ra   )rW   _sourcerc   _indexrd   rZ   rZ   r[   rf   8  s    
zseekable.__init__c                 C   s   | S ra   rZ   rg   rZ   rZ   r[   rh   =  s    zseekable.__iter__c                 C   sb   | j d k	rHz| j| j  }W n tk
r4   d | _ Y nX |  j d7  _ |S t| j}| j| |S r   )r   rc   
IndexErrorr\   r   rm   )re   r   rZ   rZ   r[   rs   @  s    

zseekable.__next__c                 C   s
   t | jS ra   )rI   rc   rg   rZ   rZ   r[   elementsP  s    zseekable.elementsc                 C   s*   || _ |t| j }|dkr&t| | d S )Nr   )r   r{   rc   r#   )re   r}   Z	remainderrZ   rZ   r[   seekS  s    zseekable.seekN)
r   r   r   r   rf   rh   rs   r\   r   r   rZ   rZ   rZ   r[   rH     s   3c                   @   s(   e Zd ZdZedd Zedd ZdS )rG   a  
    :func:`run_length.encode` compresses an iterable with run-length encoding.
    It yields groups of repeated items with the count of how many times they
    were repeated:

        >>> uncompressed = 'abbcccdddd'
        >>> list(run_length.encode(uncompressed))
        [('a', 1), ('b', 2), ('c', 3), ('d', 4)]

    :func:`run_length.decode` decompresses an iterable that was previously
    compressed with run-length encoding. It yields the items of the
    decompressed iterable:

        >>> compressed = [('a', 1), ('b', 2), ('c', 3), ('d', 4)]
        >>> list(run_length.decode(compressed))
        ['a', 'b', 'b', 'c', 'c', 'c', 'd', 'd', 'd', 'd']

    c                 C   s   dd t | D S )Nc                 s   s   | ]\}}|t |fV  qd S ra   )r8   r   rZ   rZ   r[   r   p  s     z$run_length.encode.<locals>.<genexpr>r   r   rZ   rZ   r[   encoden  s    zrun_length.encodec                 C   s   t dd | D S )Nc                 s   s   | ]\}}t ||V  qd S ra   )r   )r   r   rY   rZ   rZ   r[   r   t  s     z$run_length.decode.<locals>.<genexpr>)r	   r   r   rZ   rZ   r[   decoder  s    zrun_length.decodeN)r   r   r   r   staticmethodr   r   rZ   rZ   rZ   r[   rG   Z  s
   
c                 C   s   t t|d t|| |kS )a  Return ``True`` if exactly ``n`` items in the iterable are ``True``
    according to the *predicate* function.

        >>> exactly_n([True, True, False], 2)
        True
        >>> exactly_n([True, True, False], 1)
        False
        >>> exactly_n([0, 1, 2, 3, 4, 5], 3, lambda x: x < 3)
        True

    The iterable will be advanced until ``n + 1`` truthy items are encountered,
    so avoid calling it on infinite iterables.

    r"   )r{   r%   r   )rX   rY   r   rZ   rZ   r[   r5   w  s    c                 C   s$   t | }tt|tt|t|S )zReturn a list of circular shifts of *iterable*.

        >>> circular_shifts(range(4))
        [(0, 1, 2, 3), (1, 2, 3, 0), (2, 3, 0, 1), (3, 0, 1, 2)]
    )r|   r%   r{   rT   r   )rX   ZlstrZ   rZ   r[   r+     s    c                    s    fdd}|S )a  Return a decorator version of *wrapping_func*, which is a function that
    modifies an iterable. *result_index* is the position in that function's
    signature where the iterable goes.

    This lets you use itertools on the "production end," i.e. at function
    definition. This can augment what the function returns without changing the
    function's code.

    For example, to produce a decorator version of :func:`chunked`:

        >>> from more_itertools import chunked
        >>> chunker = make_decorator(chunked, result_index=0)
        >>> @chunker(3)
        ... def iter_range(n):
        ...     return iter(range(n))
        ...
        >>> list(iter_range(9))
        [[0, 1, 2], [3, 4, 5], [6, 7, 8]]

    To only allow truthy items to be returned:

        >>> truth_serum = make_decorator(filter, result_index=1)
        >>> @truth_serum(bool)
        ... def boolean_test():
        ...     return [0, 1, '', ' ', False, True]
        ...
        >>> list(boolean_test())
        [1, ' ', True]

    The :func:`peekable` and :func:`seekable` wrappers make for practical
    decorators:

        >>> from more_itertools import peekable
        >>> peekable_function = make_decorator(peekable)
        >>> @peekable_function()
        ... def str_range(*args):
        ...     return (str(x) for x in range(*args))
        ...
        >>> it = str_range(1, 20, 2)
        >>> next(it), next(it), next(it)
        ('1', '3', '5')
        >>> it.peek()
        '7'
        >>> next(it)
        '7'

    c                     s    fdd}|S )Nc                    s    fdd}|S )Nc                     s(    | |}t }|| |S ra   )r|   insert)r   r   resultZwrapping_args_)fresult_indexwrapping_argswrapping_funcwrapping_kwargsrZ   r[   inner_wrapper  s    
zOmake_decorator.<locals>.decorator.<locals>.outer_wrapper.<locals>.inner_wrapperrZ   )r  r  )r  r  r  r  )r  r[   outer_wrapper  s    z8make_decorator.<locals>.decorator.<locals>.outer_wrapperrZ   )r  r  r	  r  r  )r  r  r[   	decorator  s    	z!make_decorator.<locals>.decoratorrZ   )r  r  r  rZ   r
  r[   r@     s    2c           	      C   st   |dkrdd n|}t t}| D ]"}||}||}|| | q |dk	rj| D ]\}}||||< qTd|_|S )a  Return a dictionary that maps the items in *iterable* to categories
    defined by *keyfunc*, transforms them with *valuefunc*, and
    then summarizes them by category with *reducefunc*.

    *valuefunc* defaults to the identity function if it is unspecified.
    If *reducefunc* is unspecified, no summarization takes place:

        >>> keyfunc = lambda x: x.upper()
        >>> result = map_reduce('abbccc', keyfunc)
        >>> sorted(result.items())
        [('A', ['a']), ('B', ['b', 'b']), ('C', ['c', 'c', 'c'])]

    Specifying *valuefunc* transforms the categorized items:

        >>> keyfunc = lambda x: x.upper()
        >>> valuefunc = lambda x: 1
        >>> result = map_reduce('abbccc', keyfunc, valuefunc)
        >>> sorted(result.items())
        [('A', [1]), ('B', [1, 1]), ('C', [1, 1, 1])]

    Specifying *reducefunc* summarizes the categorized items:

        >>> keyfunc = lambda x: x.upper()
        >>> valuefunc = lambda x: 1
        >>> reducefunc = sum
        >>> result = map_reduce('abbccc', keyfunc, valuefunc, reducefunc)
        >>> sorted(result.items())
        [('A', 1), ('B', 2), ('C', 3)]

    You may want to filter the input iterable before applying the map/reduce
    proecdure:

        >>> all_items = range(30)
        >>> items = [x for x in all_items if 10 <= x <= 20]  # Filter
        >>> keyfunc = lambda x: x % 2  # Evens map to 0; odds to 1
        >>> categories = map_reduce(items, keyfunc=keyfunc)
        >>> sorted(categories.items())
        [(0, [10, 12, 14, 16, 18, 20]), (1, [11, 13, 15, 17, 19])]
        >>> summaries = map_reduce(items, keyfunc=keyfunc, reducefunc=sum)
        >>> sorted(summaries.items())
        [(0, 90), (1, 75)]

    Note that all items in the iterable are gathered into a list before the
    summarization step, which may require significant storage.

    The returned object is a :obj:`collections.defaultdict` with the
    ``default_factory`` set to ``None``, such that it behaves like a normal
    dictionary.

    Nc                 S   s   | S ra   rZ   r   rZ   rZ   r[   r     r   zmap_reduce.<locals>.<lambda>)r   r|   rm   rp   default_factory)	rX   r   r   Z
reducefuncr   r   r   r   Z
value_listrZ   rZ   r[   rA     s    3)NN)r"   )Nr"   )r"   )NN)NNN)NNF)r   FN)r   F)r"   )NN)N)r   )NN)gZ
__future__r   collectionsr   r   r   	functoolsr   r   heapqr   	itertoolsr	   r
   r   r   r   r   r   r   r   r   operatorr   r   r   r   sysr   r   Zcollections.abcr   ImportErrorZsixr   r   r   Z	six.movesr   r   r   r    r!   Zrecipesr#   r$   r%   __all__objectr^   r*   r6   rE   r   r-   r   Z_collate_docstringr/   r8   r=   rU   rC   r2   r;   rS   rT   r)   rP   r:   r9   r,   rJ   rK   rM   rO   rN   rD   r3   rQ   rV   rL   r4   r'   r&   r7   rB   r0   r   r>   r?   rF   rR   r<   r(   r.   r1   rI   rH   rG   r5   r+   r@   rA   rZ   rZ   rZ   r[   <module>   s   04 +)

=.
!
4U
+
/
>
!#
+
!,5
'
&=
*v%&,V

A