
    O=dm}                     6   d Z ddlmZ ddlZddlZddlmZmZm	Z	m
Z
mZ dZd Zd(dZd(d	Zd(d
Zd(dZd(dZd(dZd(dZd)dZd(dZd Zd(dZd*dZd Zd(dZd(dZd Zd+dZd(dZd Z d,dZ!d,dZ"d-dZ#d,dZ$d(d Z%d! Z&d(d"Z'd# Z(d$ Z)d(d%Z*d+d&Z+d(d'Z,dS ).zE
Functions that operate on lists and dicts.

.. versionadded:: 1.0.0
    )
cmp_to_keyN   )callitcmpgetargcountiteratoriteriteratee)atcount_byeveryfilter_find	find_lastflat_mapflat_map_deepflat_map_depthfor_eachfor_each_rightgroup_byincludes
invoke_mapkey_bymap_nestorder_by	partitionpluckreduce_reduce_right
reductionsreductions_rightrejectsamplesample_sizeshufflesizesomesort_byc                 0     t          j        | |           S )a  
    Creates a list of elements from the specified indexes, or keys, of the collection. Indexes may
    be specified as individual arguments or as arrays of indexes.

    Args:
        collection (list|dict): Collection to iterate over.
        *paths (mixed): The indexes of `collection` to retrieve, specified as individual indexes or
            arrays of indexes.

    Returns:
        list: filtered list

    Example:

        >>> at([1, 2, 3, 4], 0, 2)
        [1, 3]
        >>> at({'a': 1, 'b': 2, 'c': 3, 'd': 4}, 'a', 'c')
        [1, 3]
        >>> at({'a': 1, 'b': 2, 'c': {'d': {'e': 3}}}, 'a', ['c', 'd', 'e'])
        [1, 3]

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.1.0
        Support deep path access.
    )pyd
properties)
collectionpathss     <D:\Sites\api_v1\venv\Lib\site-packages\pydash/collections.pyr
   r
   2   s    6 "3>5!*---    c                     i }t          | |          D ]4}|                    |d         d           ||d         xx         dz  cc<   5|S )a  
    Creates an object composed of keys generated from the results of running each element of
    `collection` through the iteratee.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed, optional): Iteratee applied per iteration.

    Returns:
        dict: Dict containing counts by key.

    Example:

        >>> results = count_by([1, 2, 1, 2, 3, 4])
        >>> assert results == {1: 2, 2: 2, 3: 1, 4: 1}
        >>> results = count_by(['a', 'A', 'B', 'b'], lambda x: x.lower())
        >>> assert results == {'a': 2, 'b': 2}
        >>> results = count_by({'a': 1, 'b': 1, 'c': 3, 'd': 3})
        >>> assert results == {1: 2, 3: 2}

    .. versionadded:: 1.0.0
    r   r   )r	   
setdefault)r,   iterateeretresults       r.   r   r   P   s[    . Cz844  vay!$$$F1I!Jr/   c                 j    |r"t          j        |          fd| D             } t          |           S )a  
    Checks if the predicate returns a truthy value for all elements of a collection. The predicate
    is invoked with three arguments: ``(value, index|key, collection)``. If a property name is
    passed for predicate, the created :func:`pluck` style predicate will return the property value
    of the given element. If an object is passed for predicate, the created :func:`.matches` style
    predicate will return ``True`` for elements that have the properties of the given object, else
    ``False``.

    Args:
        collection (list|dict): Collection to iterate over.
        predicate (mixed, optional): Predicate applied per iteration.

    Returns:
        bool: Whether all elements are truthy.

    Example:

        >>> every([1, True, 'hello'])
        True
        >>> every([1, False, 'hello'])
        False
        >>> every([{'a': 1}, {'a': True}, {'a': 'hello'}], 'a')
        True
        >>> every([{'a': 1}, {'a': False}, {'a': 'hello'}], 'a')
        False
        >>> every([{'a': 1}, {'a': 1}], {'a': 1})
        True
        >>> every([{'a': 1}, {'a': 2}], {'a': 1})
        False

    .. versionadded:: 1.0.0

    .. versionchanged: 4.0.0
        Removed alias ``all_``.
    c              3   .   K   | ]} |          V  d S N .0itemcbks     r.   	<genexpr>zevery.<locals>.<genexpr>   +      77Dcc$ii777777r/   )r*   r2   allr,   	predicater<   s     @r.   r   r   p   sB    H  8l9%%7777J777
z??r/   c                 6    d t          | |          D             S )ak  
    Iterates over elements of a collection, returning a list of all elements the predicate returns
    truthy for.

    Args:
        collection (list|dict): Collection to iterate over.
        predicate (mixed, optional): Predicate applied per iteration.

    Returns:
        list: Filtered list.

    Example:

        >>> results = filter_([{'a': 1}, {'b': 2}, {'a': 1, 'b': 3}], {'a': 1})
        >>> assert results == [{'a': 1}, {'a': 1, 'b': 3}]
        >>> filter_([1, 2, 3, 4], lambda x: x >= 3)
        [3, 4]

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Removed alias ``select``.
    c                      g | ]\  }}}}|	|S r8   r8   r:   is_truevalue_s       r.   
<listcomp>zfilter_.<locals>.<listcomp>   s'    ]]]*guaU\]E]]]r/   r	   r,   rA   s     r.   r   r      s#    0 ^]l:y.Q.Q]]]]r/   c                 V    d t          | |          D             }t          |d          S )aT  
    Iterates over elements of a collection, returning the first element that the predicate returns
    truthy for.

    Args:
        collection (list|dict): Collection to iterate over.
        predicate (mixed, optional): Predicate applied per iteration.

    Returns:
        mixed: First element found or ``None``.

    Example:

        >>> find([1, 2, 3, 4], lambda x: x >= 3)
        3
        >>> find([{'a': 1}, {'b': 2}, {'a': 1, 'b': 2}], {'a': 1})
        {'a': 1}

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Removed aliases ``detect`` and ``find_where``.
    c              3   (   K   | ]\  }}}}|	|V  d S r7   r8   rD   s       r.   r=   zfind.<locals>.<genexpr>   s1      __,1W^_e______r/   Nr	   nextr,   rA   searchs      r.   r   r      s2    0 `_Z0S0S___Fr/   c                 Z    d t          | |d          D             }t          |d          S )aQ  
    This method is like :func:`find` except that it iterates over elements of a `collection` from
    right to left.

    Args:
        collection (list|dict): Collection to iterate over.
        predicate (mixed, optional): Predicate applied per iteration.

    Returns:
        mixed: Last element found or ``None``.

    Example:

        >>> find_last([1, 2, 3, 4], lambda x: x >= 3)
        4
        >>> results = find_last([{'a': 1}, {'b': 2}, {'a': 1, 'b': 2}],                                 {'a': 1})
        >>> assert results == {'a': 1, 'b': 2}

    .. versionadded:: 1.0.0
    c              3   (   K   | ]\  }}}}|	|V  d S r7   r8   rD   s       r.   r=   zfind_last.<locals>.<genexpr>   sD         GUAq     r/   TreverseNrM   rO   s      r.   r   r      sB    , $0YPT$U$U$U  F
 r/   c                 H    t          j        t          | |                    S )a7  
    Creates a flattened list of values by running each element in collection thru `iteratee` and
    flattening the mapped results. The `iteratee` is invoked with three arguments: ``(value,
    index|key, collection)``.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed, optional): Iteratee applied per iteration.

    Returns:
        list: Flattened mapped list.

    Example:

        >>> duplicate = lambda n: [[n, n]]
        >>> flat_map([1, 2], duplicate)
        [[1, 1], [2, 2]]

    .. versionadded:: 4.0.0
    r2   )r*   flattenitermapr,   r2   s     r.   r   r      s!    * ;wzH===>>>r/   c                 H    t          j        t          | |                    S )a  
    This method is like :func:`flat_map` except that it recursively flattens the mapped results.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed, optional): Iteratee applied per iteration.

    Returns:
        list: Flattened mapped list.

    Example:

        >>> duplicate = lambda n: [[n, n]]
        >>> flat_map_deep([1, 2], duplicate)
        [1, 1, 2, 2]

    .. versionadded:: 4.0.0
    rV   )r*   flatten_deeprX   rY   s     r.   r   r     s"    & GJBBBCCCr/   c                 L    t          j        t          | |          |          S )a#  
    This method is like :func:`flat_map` except that it recursively flattens the mapped results up
    to `depth` times.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed, optional): Iteratee applied per iteration.

    Returns:
        list: Flattened mapped list.

    Example:

        >>> duplicate = lambda n: [[n, n]]
        >>> flat_map_depth([1, 2], duplicate, 1)
        [[1, 1], [2, 2]]
        >>> flat_map_depth([1, 2], duplicate, 2)
        [1, 1, 2, 2]

    .. versionadded:: 4.0.0
    rV   )depth)r*   flatten_depthrX   )r,   r2   r]   s      r.   r   r     s'    , WZ(CCC5QQQQr/   c                 V    t          d t          | |          D             d           | S )a6  
    Iterates over elements of a collection, executing the iteratee for each element.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed, optional): Iteratee applied per iteration.

    Returns:
        list|dict: `collection`

    Example:

        >>> results = {}
        >>> def cb(x): results[x] = x ** 2
        >>> for_each([1, 2, 3, 4], cb)
        [1, 2, 3, 4]
        >>> assert results == {1: 1, 2: 4, 3: 9, 4: 16}

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Removed alias ``each``.
    c              3   ,   K   | ]\  }}}}|d u dV  dS FNr8   r:   r3   rG   s      r.   r=   zfor_each.<locals>.<genexpr>O  s/      	V	V<31aPU$	V	Vr/   NrN   r	   rY   s     r.   r   r   7  s4    0 		V	V<
H#E#E	V	V	VX\]]]r/   c                 Z    t          d t          | |d          D             d           | S )ax  
    This method is like :func:`for_each` except that it iterates over elements of a `collection`
    from right to left.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed, optional): Iteratee applied per iteration.

    Returns:
        list|dict: `collection`

    Example:

        >>> results = {'total': 1}
        >>> def cb(x): results['total'] = x * results['total']
        >>> for_each_right([1, 2, 3, 4], cb)
        [1, 2, 3, 4]
        >>> assert results == {'total': 24}

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Removed alias ``each_right``.
    c              3   ,   K   | ]\  }}}}|d u dV  dS ra   r8   rb   s      r.   r=   z!for_each_right.<locals>.<genexpr>m  s6      cc,#q!QVY]bVbVbVbVbVbVbccr/   TrS   Nrc   rY   s     r.   r   r   S  sA    2 	cc,z8T"R"R"Rccc   r/   c                     i }t          j        |          }| D ]>} ||          }|                    |g            ||                             |           ?|S )a  
    Creates an object composed of keys generated from the results of running each element of a
    `collection` through the iteratee.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed, optional): Iteratee applied per iteration.

    Returns:
        dict: Results of grouping by `iteratee`.

    Example:

        >>> results = group_by([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}], 'a')
        >>> assert results == {1: [{'a': 1, 'b': 2}], 3: [{'a': 3, 'b': 4}]}
        >>> results = group_by([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}], {'a': 1})
        >>> assert results == {False: [{'a': 3, 'b': 4}],                               True: [{'a': 1, 'b': 2}]}

    .. versionadded:: 1.0.0
    )r*   r2   r1   append)r,   r2   r3   r<   rF   keys         r.   r   r   s  sf    , C
,x
 
 C  c%jjsBCJr/   c                 r    t          | t                    r|                                 } n
| |d         } || v S )a  
    Checks if a given value is present in a collection. If `from_index` is negative, it is used as
    the offset from the end of the collection.

    Args:
        collection (list|dict): Collection to iterate over.
        target (mixed): Target value to compare to.
        from_index (int, optional): Offset to start search from.

    Returns:
        bool: Whether `target` is in `collection`.

    Example:

        >>> includes([1, 2, 3, 4], 2)
        True
        >>> includes([1, 2, 3, 4], 2, from_index=2)
        False
        >>> includes({'a': 1, 'b': 2, 'c': 3, 'd': 4}, 2)
        True

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Renamed from ``contains`` to ``includes`` and removed alias
        ``include``.
    N)
isinstancedictvalues)r,   target
from_indexs      r.   r   r     sD    8 *d## -&&((

  
,
Zr/   c                 2    t          | fd          S )a  
    Invokes the method at `path` of each element in `collection`, returning a list of the results of
    each invoked method. Any additional arguments are provided to each invoked method. If `path` is
    a function, it's invoked for each element in `collection`.

    Args:
        collection (list|dict): Collection to iterate over.
        path (str|func): String path to method to invoke or callable to invoke for each element in
            `collection`.
        args (optional): Arguments to pass to method call.
        kwargs (optional): Keyword arguments to pass to method call.

    Returns:
        list: List of results of invoking method of each item.

    Example:

        >>> items = [{'a': [{'b': 1}]}, {'a': [{'c': 2}]}]
        >>> expected = [{'b': 1}.items(), {'c': 2}.items()]
        >>> invoke_map(items, 'a[0].items') == expected
        True

    .. versionadded:: 4.0.0
    c                 0    t          j        | gR i S r7   )r*   invoke)r;   argskwargspaths    r.   <lambda>zinvoke_map.<locals>.<lambda>  s#    D$)P)P)P)P)P)P r/   )r   )r,   rt   rr   rs   s    ```r.   r   r     s'    2 
PPPPPPQQQr/   c                 X    i }t          j        |          }| D ]}|| ||          <   |S )ai  
    Creates an object composed of keys generated from the results of running each element of the
    collection through the given iteratee.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed, optional): Iteratee applied per iteration.

    Returns:
        dict: Results of indexing by `iteratee`.

    Example:

        >>> results = key_by([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}], 'a')
        >>> assert results == {1: {'a': 1, 'b': 2}, 3: {'a': 3, 'b': 4}}


    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Renamed from ``index_by`` to ``key_by``.
    )r*   r2   )r,   r2   r3   r<   rF   s        r.   r   r     s?    . C
,x
 
 C    CCJJJr/   c                 <    t          t          | |                    S )a  
    Creates an array of values by running each element in the collection through the iteratee. The
    iteratee is invoked with three arguments: ``(value, index|key, collection)``. If a property name
    is passed for iteratee, the created :func:`pluck` style iteratee will return the property value
    of the given element. If an object is passed for iteratee, the created :func:`.matches` style
    iteratee will return ``True`` for elements that have the properties of the given object, else
    ``False``.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed, optional): Iteratee applied per iteration.

    Returns:
        list: Mapped list.

    Example:

        >>> map_([1, 2, 3, 4], str)
        ['1', '2', '3', '4']
        >>> map_([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}, {'a': 5, 'b': 6}], 'a')
        [1, 3, 5]
        >>> map_([[[0, 1]], [[2, 3]], [[4, 5]]], '0.1')
        [1, 3, 5]
        >>> map_([{'a': {'b': 1}}, {'a': {'b': 2}}], 'a.b')
        [1, 2]
        >>> map_([{'a': {'b': [0, 1]}}, {'a': {'b': [2, 3]}}], 'a.b[1]')
        [1, 3]

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Removed alias ``collect``.
    )listrX   rY   s     r.   r   r     s    D 
H--...r/   c                     |s| S t          j        |          }|d         |dd         c}t          j        t          | |          fd          S )a  
    This method is like :func:`group_by` except that it supports nested grouping by multiple string
    `properties`. If only a single key is given, it is like calling ``group_by(collection, prop)``.

    Args:
        collection (list|dict): Collection to iterate over.
        *properties (str): Properties to nest by.

    Returns:
        dict: Results of nested grouping by `properties`.

    Example:

        >>> results = nest([{'shape': 'square', 'color': 'red', 'qty': 5},                            {'shape': 'square', 'color': 'blue', 'qty': 10},                            {'shape': 'square', 'color': 'orange', 'qty': 5},                            {'shape': 'circle', 'color': 'yellow', 'qty': 5},                            {'shape': 'circle', 'color': 'pink', 'qty': 10},                            {'shape': 'oval', 'color': 'purple', 'qty': 5}],                           'shape', 'qty')
        >>> expected = {            'square': {5: [{'shape': 'square', 'color': 'red', 'qty': 5},                           {'shape': 'square', 'color': 'orange', 'qty': 5}],                       10: [{'shape': 'square', 'color': 'blue', 'qty': 10}]},            'circle': {5: [{'shape': 'circle', 'color': 'yellow', 'qty': 5}],                       10: [{'shape': 'circle', 'color': 'pink', 'qty': 10}]},            'oval': {5: [{'shape': 'oval', 'color': 'purple', 'qty': 5}]}}
        >>> results == expected
        True

    .. versionadded:: 4.3.0
    r   r   Nc                     t          | gR  S r7   )r   )rF   rests    r.   ru   znest.<locals>.<lambda>A  s    T%EWRVEWEWEW r/   )r*   rW   
map_valuesr   )r,   r+   firstr{   s      @r.   r   r     s`    B  Z((JQ-ABBKE4>(:u557W7W7W7WXXXr/   Fc                 @   t          | t                    r|                                 } t          j        |          r|}d}g |rct          |          D ]R\  }}t          j        ||          r||         rdnd}nd}                    t          j        |          |f           SnR|D ]O}|	                    d          rd}|dd         }nd}                    t          j        |          |f           Pfd}t          | t          |          |          S )a  
    This method is like :func:`sort_by` except that it sorts by key names instead of an iteratee
    function. Keys can be sorted in descending order by prepending a ``"-"`` to the key name (e.g.
    ``"name"`` would become ``"-name"``) or by passing a list of boolean sort options via `orders`
    where ``True`` is ascending and ``False`` is descending.

    Args:
        collection (list|dict): Collection to iterate over.
        keys (list): List of keys to sort by. By default, keys will be sorted in ascending order. To
            sort a key in descending order, prepend a ``"-"`` to the key name. For example, to sort
            the key value for ``"name"`` in descending order, use ``"-name"``.
        orders (list, optional): List of boolean sort orders to apply for each key. ``True``
            corresponds to ascending order while ``False`` is descending. Defaults to ``None``.
        reverse (bool, optional): Whether to reverse the sort. Defaults to ``False``.

    Returns:
        list: Sorted list.

    Example:

        >>> items = [{'a': 2, 'b': 1}, {'a': 3, 'b': 2}, {'a': 1, 'b': 3}]
        >>> results = order_by(items, ['b', 'a'])
        >>> assert results == [{'a': 2, 'b': 1},                               {'a': 3, 'b': 2},                               {'a': 1, 'b': 3}]
        >>> results = order_by(items, ['a', 'b'])
        >>> assert results == [{'a': 1, 'b': 3},                               {'a': 2, 'b': 1},                               {'a': 3, 'b': 2}]
        >>> results = order_by(items, ['-a', 'b'])
        >>> assert results == [{'a': 3, 'b': 2},                               {'a': 2, 'b': 1},                               {'a': 1, 'b': 3}]
        >>> results = order_by(items, ['a', 'b'], [False, True])
        >>> assert results == [{'a': 3, 'b': 2},                               {'a': 2, 'b': 1},                               {'a': 1, 'b': 3}]

    .. versionadded:: 3.0.0

    .. versionchanged:: 3.2.0
        Added `orders` argument.

    .. versionchanged:: 3.2.0
        Added :func:`sort_by_order` as alias.

    .. versionchanged:: 4.0.0
        Renamed from ``order_by`` to ``order_by`` and removed alias
        ``sort_by_order``.
    Nr   -c                 n    D ]0\  }}t           ||            ||                    }|r||z  c S 1dS )Nr   )r   )leftrightfuncmultr4   	comparerss        r.   
comparisonzorder_by.<locals>.comparison  sY    # 	 	JD$dTT%[[11F %f}$$$% 1r/   rh   rT   )rj   rk   rl   r*   
is_boolean	enumeratehasrg   	property_
startswithsortedr   )	r,   keysordersrT   irh   orderr   r   s	           @r.   r   r   D  sa   f *d## )&&((
 ~f I :oo 	: 	:FAswvq!! #AY.BcmC00%89999	:  	: 	:C~~c"" !""gcmC00%89999     **Z"8"8'JJJJr/   c                     g }g }t          | |          D ]4\  }}}}|r|                    |           |                    |           5||gS )a  
    Creates an array of elements split into two groups, the first of which contains elements the
    `predicate` returns truthy for, while the second of which contains elements the `predicate`
    returns falsey for. The `predicate` is invoked with three arguments: ``(value, index|key,
    collection)``.

    If a property name is provided for `predicate` the created :func:`pluck` style predicate returns
    the property value of the given element.

    If an object is provided for `predicate` the created :func:`.matches` style predicate returns
    ``True`` for elements that have the properties of the given object, else ``False``.

    Args:
        collection (list|dict): Collection to iterate over.
        predicate (mixed, optional): Predicate applied per iteration.

    Returns:
        list: List of grouped elements.

    Example:

        >>> partition([1, 2, 3, 4], lambda x: x >= 3)
        [[3, 4], [1, 2]]

    .. versionadded:: 1.1.0
    )r	   rg   )r,   rA   truesfalsesrE   rF   rG   s          r.   r   r     sl    6 EF ,Z C C ! !1 	!LLMM%    6?r/   c                 F    t          | t          j        |                    S )aB  
    Retrieves the value of a specified property from all elements in the collection.

    Args:
        collection (list): List of dicts.
        path (str|list): Collection's path to pluck

    Returns:
        list: Plucked list.

    Example:

        >>> pluck([{'a': 1, 'b': 2}, {'a': 3, 'b': 4}, {'a': 5, 'b': 6}], 'a')
        [1, 3, 5]
        >>> pluck([[[0, 1]], [[2, 3]], [[4, 5]]], '0.1')
        [1, 3, 5]
        >>> pluck([{'a': {'b': 1}}, {'a': {'b': 2}}], 'a.b')
        [1, 2]
        >>> pluck([{'a': {'b': [0, 1]}}, {'a': {'b': [2, 3]}}], 'a.b.1')
        [1, 3]
        >>> pluck([{'a': {'b': [0, 1]}}, {'a': {'b': [2, 3]}}], ['a', 'b', 1])
        [1, 3]

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Function removed.

    .. versionchanged:: 4.0.1
        Made property access deep.
    )r   r*   r   )r,   rt   s     r.   r   r     s    @ 
CM$//000r/   c                 
   t          |           }|1	 t          |          \  }}n# t          $ r t          d          w xY w|}|t          j        }d}nt          |d          }|D ]\  }}t          |||||          }|S )a  
    Reduces a collection to a value which is the accumulated result of running each element in the
    collection through the iteratee, where each successive iteratee execution consumes the return
    value of the previous execution.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed): Iteratee applied per iteration.
        accumulator (mixed, optional): Initial value of aggregator. Default is to use the result of
            the first iteration.

    Returns:
        mixed: Accumulator object containing results of reduction.

    Example:

        >>> reduce_([1, 2, 3, 4], lambda total, x: total * x)
        24

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Removed aliases ``foldl`` and ``inject``.
    Nz1reduce_() of empty sequence with no initial valuer      maxargsargcount)r   rN   StopIteration	TypeErrorr*   identityr   r   )	r,   r2   accumulatoriterablerG   r4   r   indexr;   s	            r.   r   r     s    2 
##H	Q!(^^NA{{ 	Q 	Q 	QOPPP	Q F<x333 J Jt&$IIIMs	   & A c                 ~    t          | t                    st          |           ddd         } t          | ||          S )a  
    This method is like :func:`reduce_` except that it iterates over elements of a `collection` from
    right to left.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed): Iteratee applied per iteration.
        accumulator (mixed, optional): Initial value of aggregator. Default is to use the result of
            the first iteration.

    Returns:
        mixed: Accumulator object containing results of reduction.

    Example:

        >>> reduce_right([1, 2, 3, 4], lambda total, x: total ** x)
        4096

    .. versionadded:: 1.0.0

    .. versionchanged:: 3.2.1
        Fix bug where collection was not reversed correctly.

    .. versionchanged:: 4.0.0
        Removed alias ``foldr``.
    Nr   )rj   rk   rx   r   r,   r2   r   s      r.   r   r     s@    6 j$'' ,*%%ddd+
:x555r/   c                     t           j        dnt          d          g fd}|rt          nt          } || ||           S )a  
    This function is like :func:`reduce_` except that it returns a list of every intermediate value
    in the reduction operation.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed): Iteratee applied per iteration.
        accumulator (mixed, optional): Initial value of aggregator. Default is to use the result of
            the first iteration.

    Returns:
        list: Results of each reduction operation.

    Example:

        >>> reductions([1, 2, 3, 4], lambda total, x: total * x)
        [2, 6, 24]

    Note:
        The last element of the returned list would be the result of using
        :func:`reduce_`.

    .. versionadded:: 2.0.0
    Nr   r   r   c                 Z    t          | ||          }                     |            | S )Nr   )r   rg   )r4   r;   r   r   r2   resultss      r.   interceptorzreductions.<locals>.interceptorZ  s2    &$IIIvr/   )r*   r   r   r   r   )r,   r2   r   
from_rightr   reducerr   r   s    `    @@r.   r    r    9  s~    2 <x333G      
 )5llgGGJ[111Nr/   c                 (    t          | ||d          S )a  
    This method is like :func:`reductions` except that it iterates over elements of a `collection`
    from right to left.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed): Iteratee applied per iteration.
        accumulator (mixed, optional): Initial value of aggregator. Default is to use the result of
            the first iteration.

    Returns:
        list: Results of each reduction operation.

    Example:

        >>> reductions_right([1, 2, 3, 4], lambda total, x: total ** x)
        [64, 4096, 4096]

    Note:
        The last element of the returned list would be the result of using
        :func:`reduce_`.

    .. versionadded:: 2.0.0
    T)r   )r    r   s      r.   r!   r!   e  s    2 j(KDIIIIr/   c                 6    d t          | |          D             S )ap  
    The opposite of :func:`filter_` this method returns the elements of a collection that the
    predicate does **not** return truthy for.

    Args:
        collection (list|dict): Collection to iterate over.
        predicate (mixed, optional): Predicate applied per iteration.

    Returns:
        list: Rejected elements of `collection`.

    Example:

        >>> reject([1, 2, 3, 4], lambda x: x >= 3)
        [1, 2]
        >>> reject([{'a': 0}, {'a': 1}, {'a': 2}], 'a')
        [{'a': 0}]
        >>> reject([{'a': 0}, {'a': 1}, {'a': 2}], {'a': 1})
        [{'a': 0}, {'a': 2}]

    .. versionadded:: 1.0.0
    c                      g | ]\  }}}}|	|S r8   r8   rD   s       r.   rH   zreject.<locals>.<listcomp>  s'    aaa*guaY`aEaaar/   rI   rJ   s     r.   r"   r"     s#    . bal:y.Q.Qaaaar/   c                 *    t          j        |           S )a  
    Retrieves a random element from a given `collection`.

    Args:
        collection (list|dict): Collection to iterate over.

    Returns:
        mixed: Random element from the given collection.

    Example:

        >>> items = [1, 2, 3, 4, 5]
        >>> results = sample(items)
        >>> assert results in items

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Moved multiple samples functionality to :func:`sample_size`. This
        function now only returns a single random sample.
    )randomchoicer,   s    r.   r#   r#     s    , =$$$r/   c                 j    t          |pdt          |                     }t          j        | |          S )a  
    Retrieves list of `n` random elements from a collection.

    Args:
        collection (list|dict): Collection to iterate over.
        n (int, optional): Number of random samples to return.

    Returns:
        list: List of `n` sampled collection values.

    Examples:

        >>> items = [1, 2, 3, 4, 5]
        >>> results = sample_size(items, 2)
        >>> assert len(results) == 2
        >>> assert set(items).intersection(results) == set(results)

    .. versionadded:: 4.0.0
    r   )minlenr   r#   )r,   nnums      r.   r$   r$     s/    ( af1c*oo
&
&C=S)))r/   c                     t          | t                    r|                                 } t          |           } t	          j        |            | S )a  
    Creates a list of shuffled values, using a version of the Fisher-Yates shuffle.

    Args:
        collection (list|dict): Collection to iterate over.

    Returns:
        list: Shuffled list of values.

    Example:

        >>> items = [1, 2, 3, 4]
        >>> results = shuffle(items)
        >>> assert len(results) == len(items)
        >>> assert set(results) == set(items)

    .. versionadded:: 1.0.0
    )rj   rk   rl   rx   r   r%   r   s    r.   r%   r%     sN    & *d## )&&((
 j!!J N:r/   c                      t          |           S )a*  
    Gets the size of the `collection` by returning `len(collection)` for iterable objects.

    Args:
        collection (list|dict): Collection to iterate over.

    Returns:
        int: Collection length.

    Example:

        >>> size([1, 2, 3, 4])
        4

    .. versionadded:: 1.0.0
    )r   r   s    r.   r&   r&     s    " z??r/   c                 j    |r"t          j        |          fd| D             } t          |           S )a  
    Checks if the predicate returns a truthy value for any element of a collection. The predicate is
    invoked with three arguments: ``(value, index|key, collection)``. If a property name is passed
    for predicate, the created :func:`map_` style predicate will return the property value of the
    given element. If an object is passed for predicate, the created :func:`.matches` style
    predicate will return ``True`` for elements that have the properties of the given object, else
    ``False``.

    Args:
        collection (list|dict): Collection to iterate over.
        predicate (mixed, optional): Predicate applied per iteration.

    Returns:
        bool: Whether any of the elements are truthy.

    Example:

        >>> some([False, True, 0])
        True
        >>> some([False, 0, None])
        False
        >>> some([1, 2, 3, 4], lambda x: x >= 3)
        True
        >>> some([1, 2, 3, 4], lambda x: x == 0)
        False

    .. versionadded:: 1.0.0

    .. versionchanged:: 4.0.0
        Removed alias ``any_``.
    c              3   .   K   | ]} |          V  d S r7   r8   r9   s     r.   r=   zsome.<locals>.<genexpr>!  r>   r/   )r*   r2   anyr@   s     @r.   r'   r'     sB    @  8l9%%7777J777
z??r/   c                     t          | t                    r|                                 } t          | t	          j        |          |          S )a  
    Creates a list of elements, sorted in ascending order by the results of running each element in
    a `collection` through the iteratee.

    Args:
        collection (list|dict): Collection to iterate over.
        iteratee (mixed, optional): Iteratee applied per iteration.
        reverse (bool, optional): Whether to reverse the sort. Defaults to ``False``.

    Returns:
        list: Sorted list.

    Example:

        >>> sort_by({'a': 2, 'b': 3, 'c': 1})
        [1, 2, 3]
        >>> sort_by({'a': 2, 'b': 3, 'c': 1}, reverse=True)
        [3, 2, 1]
        >>> sort_by([{'a': 2}, {'a': 3}, {'a': 1}], 'a')
        [{'a': 1}, {'a': 2}, {'a': 3}]

    .. versionadded:: 1.0.0
    r   )rj   rk   rl   r   r*   r2   )r,   r2   rT   s      r.   r(   r(   &  sF    0 *d## )&&((
*#,x"8"8'JJJJr/   c              #   D   K   t          | |          D ]}|d         V  dS )zGenerative mapper.r   NrI   )r,   r2   r4   s      r.   rX   rX   I  s8      z844  Qi r/   r7   )Nr   )r   )NF)NN)NNF)-__doc__	functoolsr   r   pydashr*   helpersr   r   r   r   r	   __all__r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   r%   r&   r'   r(   rX   r8   r/   r.   <module>r      s    !                E E E E E E E E E E E E E E F. . .<   @( ( ( (V^ ^ ^ ^6   8   <? ? ? ?0D D D D,R R R R2   8  @   B"  "  "  " JR R R8   @"/ "/ "/ "/J'Y 'Y 'YTXK XK XK XKv$ $ $ $N 1  1  1F, , , ,^6 6 6 6B) ) ) )XJ J J J8b b b b4% % %2* * * *0  >  ($ $ $ $NK K K KF     r/   