
    [c                     L    d dl mZmZmZ d dlmZmZ  G d de          Zd Z	dS )    )getterconspluck)teestarmapc                   B    e Zd ZdZddgZdZd Zd Zd Zd Z	d	 Z
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
    container.  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key__default__hashkey__c                     || j         | _        n+t          |          st          |          | _        n|| _        || _        d S N)_default_hashkeyr   callabler   r
   )selfr   r
   s      2lib/python3.11/site-packages/toolz/sandbox/core.py__init__zEqualityHashKey.__init__@   sE     	,DHH# 	c{{DHHDH			    c                     | j         | j        k    r| j         }n|                      | j                  }t          |          S r   )r   r   r
   hash)r   vals     r   __hash__zEqualityHashKey.__hash__I   s<    8t,, 	&(CC((49%%CCyyr   c                 f    	 | j         |j         k    o| j        |j        k    S # t          $ r Y dS w xY w)NF)r   r
   AttributeErrorr   others     r   __eq__zEqualityHashKey.__eq__P   sM    	)U-CC ,I+- 	 	 	55	s   " 
00c                 .    |                      |           S r   )r   r   s     r   __ne__zEqualityHashKey.__ne__W   s    ;;u%%%%r   c                 0    dt          | j                  z  S Nz=%s=)strr
   r   s    r   __str__zEqualityHashKey.__str__Z   s    DI&&r   c                 0    dt          | j                  z  S r!   )reprr
   r#   s    r   __repr__zEqualityHashKey.__repr__]   s    TY''r   N)__name__
__module____qualname____doc__	__slots__r   r   r   r   r   r$   r'    r   r   r	   r	      s        4 4j I-      & & &' ' '( ( ( ( (r   r	   c                 P   t          |           } 	 t          t          |                     }n# t          $ r t                      cY S w xY w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firstnitersseqss       r   unzipr9   b   s    . s))Cd3ii     ww ZZFtE3((D	$00111s   . A	A	N)
toolz.itertoolzr   r   r   	itertoolsr   r   objectr	   r9   r-   r   r   <module>r=      s    / / / / / / / / / / " " " " " " " "
W( W( W( W( W(f W( W( W(v#2 #2 #2 #2 #2r   