a
    ž³‹að  ã                   @   s@   d dl mZmZmZ d dlmZmZ G dd„ deƒZdd„ Z	dS )é    )ÚgetterÚconsÚpluck)ÚteeÚstarmapc                   @   sL   e Zd ZdZddgZdZdd„ Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dd„ ZdS )ÚEqualityHashKeya´   Create a hash key that uses equality comparisons between items.

    This may be used to create hash keys for otherwise unhashable types:

    >>> from toolz import curry
    >>> EqualityHashDefault = curry(EqualityHashKey, None)
    >>> set(map(EqualityHashDefault, [[], (), [1], [1]]))  # doctest: +SKIP
    {=[]=, =()=, =[1]=}

    **Caution:** adding N ``EqualityHashKey`` items to a hash container
    may require O(N**2) operations, not O(N) as for typical hashable types.
    Therefore, a suitable key function such as ``tuple`` or ``frozenset``
    is usually preferred over using ``EqualityHashKey`` if possible.

    The ``key`` argument to ``EqualityHashKey`` should be a function or
    index that returns a hashable object that effectively distinguishes
    unequal items.  This helps avoid the poor scaling that occurs when
    using the default key.  For example, the above example can be improved
    by using a key function that distinguishes items by length or type:

    >>> EqualityHashLen = curry(EqualityHashKey, len)
    >>> EqualityHashType = curry(EqualityHashKey, type)  # this works too
    >>> set(map(EqualityHashLen, [[], (), [1], [1]]))  # doctest: +SKIP
    {=[]=, =()=, =[1]=}

    ``EqualityHashKey`` is convenient to use when a suitable key function
    is complicated or unavailable.  For example, the following returns all
    unique values based on equality:

    >>> from toolz import unique
    >>> vals = [[], [], (), [1], [1], [2], {}, {}, {}]
    >>> list(unique(vals, key=EqualityHashDefault))
    [[], (), [1], [2], {}]

    **Warning:** don't change the equality value of an item already in a hash
    containter.  Unhashable types are unhashable for a reason.  For example:

    >>> L1 = [1] ; L2 = [2]
    >>> s = set(map(EqualityHashDefault, [L1, L2]))
    >>> s  # doctest: +SKIP
    {=[1]=, =[2]=}

    >>> L1[0] = 2  # Don't do this!  ``s`` now has duplicate items!
    >>> s  # doctest: +SKIP
    {=[2]=, =[2]=}

    Although this may appear problematic, immutable data types is a common
    idiom in functional programming, and``EqualityHashKey`` easily allows
    the same idiom to be used by convention rather than strict requirement.

    See Also:
        identity
    ÚitemÚkeyZ__default__hashkey__c                 C   s6   |d u r| j | _nt|ƒs&t|ƒ| _n|| _|| _d S ©N)Ú_default_hashkeyr	   Úcallabler   r   )Úselfr	   r   © r   úX/home/ankuromar296_gmail_com/anaconda3/lib/python3.9/site-packages/toolz/sandbox/core.pyÚ__init__@   s    
zEqualityHashKey.__init__c                 C   s(   | j | jkr| j }n|   | j¡}t|ƒS r
   )r	   r   r   Úhash)r   Úvalr   r   r   Ú__hash__I   s    zEqualityHashKey.__hash__c                 C   s4   z| j |j ko| j|jkW S  ty.   Y dS 0 d S )NF)r   r   ÚAttributeError©r   Úotherr   r   r   Ú__eq__P   s    
ÿzEqualityHashKey.__eq__c                 C   s   |   |¡ S r
   )r   r   r   r   r   Ú__ne__W   s    zEqualityHashKey.__ne__c                 C   s   dt | jƒ S ©Nz=%s=)Ústrr   ©r   r   r   r   Ú__str__Z   s    zEqualityHashKey.__str__c                 C   s   dt | jƒ S r   )Úreprr   r   r   r   r   Ú__repr__]   s    zEqualityHashKey.__repr__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	__slots__r   r   r   r   r   r   r   r   r   r   r   r      s   5	r   c                 C   s\   t | ƒ} ztt| ƒƒ}W n ty0   tƒ  Y S 0 t|ƒ}tt|| ƒ|ƒ}tttt	|ƒƒƒS )aJ  Inverse of ``zip``

    >>> a, b = unzip([('a', 1), ('b', 2)])
    >>> list(a)
    ['a', 'b']
    >>> list(b)
    [1, 2]

    Unlike the naive implementation ``def unzip(seq): zip(*seq)`` this
    implementation can handle an infinite sequence ``seq``.

    Caveats:

    * The implementation uses ``tee``, and so can use a significant amount
      of auxiliary storage if the resulting iterators are consumed at
      different times.

    * The inner sequence cannot be infinite. In Python 3 ``zip(*seq)`` can be
      used if ``seq`` is a finite sequence of infinite sequences.

    )
ÚiterÚtupleÚnextÚStopIterationÚlenr   r   r   r   Ú	enumerate)ÚseqÚfirstZnitersÚseqsr   r   r   Úunzipb   s    r-   N)
Ztoolz.itertoolzr   r   r   Ú	itertoolsr   r   Úobjectr   r-   r   r   r   r   Ú<module>   s   [