B
    [p:                 @   s  d 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 ddlZddlmZmZmZ ddlmZ ddlmZmZmZ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#gZejfd$dZd%d! ZdAd&dZd'd  Z dBd(d
Z!dCd)dZ"d*d	 Z#e$fd+dZ%d,d Z&d-d Z'd.d Z(d/d Z)dDd0dZ*d1d Z+dEd2dZ,d3d Z-d4d Z.d5d Z/dFd6d"Z0dGd7d#Z1dHd8dZ2dId:dZ3d;d Z4dJd<dZ5d=d Z6d>d Z7d?d Z8d@d Z9dS )Ka  Imported from the recipes section of the itertools documentation.

All functions taken from the recipes section of the itertools library docs
[1]_.
Some backward-compatible usability improvements have been made.

.. [1] http://docs.python.org/library/itertools.html#recipes

    )deque)	chaincombinationscountcyclegroupbyislicerepeatstarmapteeN)	randrangesamplechoice)PY2)filterfilterfalsemaprangezipzip_longest
accumulate	all_equalconsume
dotproduct
first_trueflattengrouperiter_exceptncyclesnthnth_combinationpadnonepairwise	partitionpowersetprependquantify#random_combination_with_replacementrandom_combinationrandom_permutationrandom_product
repeatfunc
roundrobintabulatetailtakeunique_everseenunique_justseenc             c   sR   t | }yt|}W n tk
r(   dS X |V  x|D ]}|||}|V  q6W dS )a_  
    Return an iterator whose items are the accumulated results of a function
    (specified by the optional *func* argument) that takes two arguments.
    By default, returns accumulated sums with :func:`operator.add`.

        >>> list(accumulate([1, 2, 3, 4, 5]))  # Running sum
        [1, 3, 6, 10, 15]
        >>> list(accumulate([1, 2, 3], func=operator.mul))  # Running product
        [1, 2, 6]
        >>> list(accumulate([0, 1, -1, 2, 3, 2], func=max))  # Running maximum
        [0, 1, 1, 2, 3, 3]

    This function is available in the ``itertools`` module for Python 3.2 and
    greater.

    N)iternextStopIteration)iterablefuncitZtotalelement r9   8/usr/lib/python3/dist-packages/more_itertools/recipes.pyr   4   s    

c             C   s   t t|| S )a.  Return first *n* items of the iterable as a list.

        >>> take(3, range(10))
        [0, 1, 2]
        >>> take(5, range(3))
        [0, 1, 2]

    Effectively a short replacement for ``next`` based iterator consumption
    when you want more than one item, but less than the whole iterator.

    )listr   )nr5   r9   r9   r:   r/   R   s    c             C   s   t | t|S )a  Return an iterator over the results of ``func(start)``,
    ``func(start + 1)``, ``func(start + 2)``...

    *func* should be a function that accepts one integer argument.

    If *start* is not specified it defaults to 0. It will be incremented each
    time the iterator is advanced.

        >>> square = lambda x: x ** 2
        >>> iterator = tabulate(square, -3)
        >>> take(4, iterator)
        [9, 4, 1, 0]

    )r   r   )Zfunctionstartr9   r9   r:   r-   a   s    c             C   s   t t|| dS )zReturn an iterator over the last *n* items of *iterable*.

        >>> t = tail(3, 'ABCDEFG')
        >>> list(t)
        ['E', 'F', 'G']

    )maxlen)r2   r   )r<   r5   r9   r9   r:   r.   s   s    c             C   s,   |dkrt | dd ntt| ||d dS )aX  Advance *iterable* by *n* steps. If *n* is ``None``, consume it
    entirely.

    Efficiently exhausts an iterator without returning values. Defaults to
    consuming the whole iterator, but an optional second argument may be
    provided to limit consumption.

        >>> i = (x for x in range(10))
        >>> next(i)
        0
        >>> consume(i, 3)
        >>> next(i)
        4
        >>> consume(i)
        >>> next(i)
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        StopIteration

    If the iterator has fewer items remaining than the provided limit, the
    whole iterator will be consumed.

        >>> i = (x for x in range(3))
        >>> consume(i, 5)
        >>> next(i)
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
        StopIteration

    Nr   )r>   )r   r3   r   )iteratorr<   r9   r9   r:   r   ~   s     c             C   s   t t| |d|S )zReturns the nth item or a default value.

        >>> l = range(10)
        >>> nth(l, 3)
        3
        >>> nth(l, 20, "zebra")
        'zebra'

    N)r3   r   )r5   r<   defaultr9   r9   r:   r      s    
c             C   s   t | }t|dot|d S )z
    Returns ``True`` if all the elements are equal to each other.

        >>> all_equal('aaaa')
        True
        >>> all_equal('aaab')
        False

    TF)r   r3   )r5   gr9   r9   r:   r      s    
c             C   s   t t|| S )zkReturn the how many times the predicate is true.

        >>> quantify([True, False, True])
        2

    )sumr   )r5   predr9   r9   r:   r&      s    c             C   s   t | tdS )zReturns the sequence of elements and then returns ``None`` indefinitely.

        >>> take(5, padnone(range(3)))
        [0, 1, 2, None, None]

    Useful for emulating the behavior of the built-in :func:`map` function.

    See also :func:`padded`.

    N)r   r	   )r5   r9   r9   r:   r!      s    c             C   s   t tt| |S )z~Returns the sequence elements *n* times

        >>> list(ncycles(["a", "b"], 3))
        ['a', 'b', 'a', 'b', 'a', 'b']

    )r   from_iterabler	   tuple)r5   r<   r9   r9   r:   r      s    c             C   s   t ttj| |S )zkReturns the dot product of the two iterables.

        >>> dotproduct([10, 10], [20, 20])
        400

    )rB   r   operatormul)Zvec1Zvec2r9   r9   r:   r      s    c             C   s
   t | S )zReturn an iterator flattening one level of nesting in a list of lists.

        >>> list(flatten([[0, 1], [2, 3]]))
        [0, 1, 2, 3]

    See also :func:`collapse`, which can flatten multiple levels of nesting.

    )r   rD   )ZlistOfListsr9   r9   r:   r      s    	c             G   s&   |dkrt | t|S t | t||S )aG  Call *func* with *args* repeatedly, returning an iterable over the
    results.

    If *times* is specified, the iterable will terminate after that many
    repetitions:

        >>> from operator import add
        >>> times = 4
        >>> args = 3, 5
        >>> list(repeatfunc(add, times, *args))
        [8, 8, 8, 8]

    If *times* is ``None`` the iterable will not terminate:

        >>> from random import randrange
        >>> times = None
        >>> args = 1, 11
        >>> take(6, repeatfunc(randrange, times, *args))  # doctest:+SKIP
        [2, 4, 8, 1, 8, 4]

    N)r
   r	   )r6   timesargsr9   r9   r:   r+      s    c             C   s    t | \}}t|d t||S )zReturns an iterator of paired items, overlapping, from the original

        >>> take(4, pairwise(count()))
        [(0, 1), (1, 2), (2, 3), (3, 4)]

    N)r   r3   r   )r5   abr9   r9   r:   r"     s    
c             C   s   t |g|  }t|d|iS )zCollect data into fixed-length chunks or blocks.

        >>> list(grouper(3, 'ABCDEFG', 'x'))
        [('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'x', 'x')]

    	fillvalue)r2   r   )r<   r5   rL   rI   r9   r9   r:   r      s    c              g   s   t | }tr tdd | D }ntdd | D }xN|ryx|D ]}| V  q@W W q4 tk
r|   |d8 }tt||}Y q4X q4W dS )aJ  Yields an item from each iterable, alternating between them.

        >>> list(roundrobin('ABC', 'D', 'EF'))
        ['A', 'D', 'E', 'B', 'F', 'C']

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

    c             s   s   | ]}t |jV  qd S )N)r2   r3   ).0r7   r9   r9   r:   	<genexpr>9  s    zroundrobin.<locals>.<genexpr>c             s   s   | ]}t |jV  qd S )N)r2   __next__)rM   r7   r9   r9   r:   rN   ;  s       N)lenr   r   r4   r   )	iterablespendingZnextsr3   r9   r9   r:   r,   +  s    
c             C   s    t |\}}t| |t| |fS )a  
    Returns a 2-tuple of iterables derived from the input iterable.
    The first yields the items that have ``pred(item) == False``.
    The second yields the items that have ``pred(item) == True``.

        >>> is_odd = lambda x: x % 2 != 0
        >>> iterable = range(10)
        >>> even_items, odd_items = partition(is_odd, iterable)
        >>> list(even_items), list(odd_items)
        ([0, 2, 4, 6, 8], [1, 3, 5, 7, 9])

    )r   r   r   )rC   r5   Zt1Zt2r9   r9   r:   r#   E  s    c                s,   t |  t fddtt d D S )zYields all possible subsets of the iterable.

        >>> list(powerset([1,2,3]))
        [(), (1,), (2,), (3,), (1, 2), (1, 3), (2, 3), (1, 2, 3)]

    c             3   s   | ]}t  |V  qd S )N)r   )rM   r)sr9   r:   rN   _  s    zpowerset.<locals>.<genexpr>rP   )r;   r   rD   r   rQ   )r5   r9   )rU   r:   r$   W  s    c          	   c   s   t  }|j}g }|j}|dkrtx| D ]J}y||kr@|| |V  W q$ tk
rl   ||krh|| |V  Y q$X q$W n\xZ| D ]R}||}y||kr|| |V  W qz tk
r   ||kr|| |V  Y qzX qzW dS )aj  
    Yield unique elements, preserving order.

        >>> list(unique_everseen('AAAABBBCCDAABBB'))
        ['A', 'B', 'C', 'D']
        >>> list(unique_everseen('ABBCcAD', str.lower))
        ['A', 'B', 'C', 'D']

    Sequences with a mix of hashable and unhashable items can be used.
    The function will be slower (i.e., `O(n^2)`) for unhashable items.

    N)setaddappend	TypeError)r5   keyZseensetZseenset_addZseenlistZseenlist_addr8   kr9   r9   r:   r0   b  s0    



c             C   s   t tt tdt| |S )zYields elements in order, ignoring serial duplicates

        >>> list(unique_justseen('AAAABBBCCDAABBB'))
        ['A', 'B', 'C', 'D', 'A', 'B']
        >>> list(unique_justseen('ABBCcAD', str.lower))
        ['A', 'B', 'C', 'A', 'D']

    rP   )r   r3   rF   
itemgetterr   )r5   rZ   r9   r9   r:   r1     s    	c             c   s<   y"|dk	r| V  x|  V  qW W n |k
r6   Y nX dS )aX  Yields results from a function repeatedly until an exception is raised.

    Converts a call-until-exception interface to an iterator interface.
    Like ``iter(func, sentinel)``, but uses an exception instead of a sentinel
    to end the loop.

        >>> l = [0, 1, 2]
        >>> list(iter_except(l.pop, IndexError))
        [2, 1, 0]

    Nr9   )r6   Z	exceptionfirstr9   r9   r:   r     s    Fc             C   s   t t|| |S )a  
    Returns the first true value in the iterable.

    If no true value is found, returns *default*

    If *pred* is not None, returns the first item for which
    ``pred(item) == True`` .

        >>> first_true(range(10))
        1
        >>> first_true(range(10), pred=lambda x: x > 5)
        6
        >>> first_true(range(10), default='missing', pred=lambda x: x > 9)
        'missing'

    )r3   r   )r5   r@   rC   r9   r9   r:   r     s    c              O   s,   dd | D | dd }tdd |D S )a  Draw an item at random from each of the input iterables.

        >>> random_product('abc', range(4), 'XYZ')  # doctest:+SKIP
        ('c', 3, 'Z')

    If *repeat* is provided as a keyword argument, that many items will be
    drawn from each iterable.

        >>> random_product('abcd', range(4), repeat=2)  # doctest:+SKIP
        ('a', 2, 'd', 3)

    This equivalent to taking a random selection from
    ``itertools.product(*args, **kwarg)``.

    c             S   s   g | ]}t |qS r9   )rE   )rM   poolr9   r9   r:   
<listcomp>  s    z"random_product.<locals>.<listcomp>r	   rP   c             s   s   | ]}t |V  qd S )N)r   )rM   r^   r9   r9   r:   rN     s    z!random_product.<locals>.<genexpr>)getrE   )rI   kwdsZpoolsr9   r9   r:   r*     s    c             C   s*   t | }|dkrt|n|}t t||S )ab  Return a random *r* length permutation of the elements in *iterable*.

    If *r* is not specified or is ``None``, then *r* defaults to the length of
    *iterable*.

        >>> random_permutation(range(5))  # doctest:+SKIP
        (3, 4, 0, 1, 2)

    This equivalent to taking a random selection from
    ``itertools.permutations(iterable, r)``.

    N)rE   rQ   r   )r5   rT   r^   r9   r9   r:   r)     s    c                s8   t |  t }ttt||}t  fdd|D S )zReturn a random *r* length subsequence of the elements in *iterable*.

        >>> random_combination(range(5), 3)  # doctest:+SKIP
        (2, 3, 4)

    This equivalent to taking a random selection from
    ``itertools.combinations(iterable, r)``.

    c             3   s   | ]} | V  qd S )Nr9   )rM   i)r^   r9   r:   rN     s    z%random_combination.<locals>.<genexpr>)rE   rQ   sortedr   r   )r5   rT   r<   indicesr9   )r^   r:   r(     s    
c                s@   t | t t fddt|D }t fdd|D S )aS  Return a random *r* length subsequence of elements in *iterable*,
    allowing individual elements to be repeated.

        >>> random_combination_with_replacement(range(3), 5) # doctest:+SKIP
        (0, 0, 1, 2, 2)

    This equivalent to taking a random selection from
    ``itertools.combinations_with_replacement(iterable, r)``.

    c             3   s   | ]}t  V  qd S )N)r   )rM   rb   )r<   r9   r:   rN     s    z6random_combination_with_replacement.<locals>.<genexpr>c             3   s   | ]} | V  qd S )Nr9   )rM   rb   )r^   r9   r:   rN     s    )rE   rQ   rc   r   )r5   rT   rd   r9   )r<   r^   r:   r'     s    c       	      C   s   t | }t|}|dk s ||kr$td}t||| }x*td|d D ]}||| |  | }qFW |dk rr||7 }|dk s||krtg }xj|r|| | |d |d   }}}x.||kr||8 }|||  | |d  }}qW ||d|   qW t |S )a)  Equivalent to ``list(combinations(iterable, r))[index]``.

    The subsequences of *iterable* that are of length *r* can be ordered
    lexicographically. :func:`nth_combination` computes the subsequence at
    sort position *index* directly, without computing the previous
    subsequences.

    r   rP   )rE   rQ   
ValueErrorminr   
IndexErrorrX   )	r5   rT   indexr^   r<   cr[   rb   resultr9   r9   r:   r      s(    	 
c             C   s   t | g|S )a  Yield *value*, followed by the elements in *iterator*.

        >>> value = '0'
        >>> iterator = ['1', '2', '3']
        >>> list(prepend(value, iterator))
        ['0', '1', '2', '3']

    To prepend multiple values, see :func:`itertools.chain`.

    )r   )valuer?   r9   r9   r:   r%   *  s    )r   )N)N)N)N)N)N)N)FN)N):__doc__collectionsr   	itertoolsr   r   r   r   r   r   r	   r
   r   rF   Zrandomr   r   r   Zsixr   Z	six.movesr   r   r   r   r   r   __all__rW   r   r/   r-   r.   r   r   r   boolr&   r!   r   r   r   r+   r"   r   r,   r#   r$   r0   r1   r   r   r*   r)   r(   r'   r    r%   r9   r9   r9   r:   <module>	   s|   , 

(






(



$