a
    ij                     @  s   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
 eZeZe
dZe
dZeZe
dZe
dZe
d	Zddd
ddZeddddddddZddddddZdddddZdS ) zItertools utils.    )annotationsN)AnyCallableIterableIteratorTypeVar_T_KeyT_K_Tin_Tout)xreturnc                 C  s   | S )zPass through function. )r   r   r   Q/home/ghrups/robot-bench/.venv/lib/python3.9/site-packages/etils/epy/itertools.py	_identity(   s    r   )valuezIterable[_Tin]zCallable[[_Tin], _K]zCallable[[_Tin], _Tout]zdict[_K, list[_Tout]])iterablekeyr   r   c                C  s2   t t}| D ]}||| || qt|S )a  Similar to `itertools.groupby` but return result as a `dict()`.

  Example:

  ```python
  out = epy.groupby(
      ['555', '4', '11', '11', '333'],
      key=len,
      value=int,
  )
  # Order is consistent with above
  assert out == {
      3: [555, 333],
      1: [4],
      2: [11, 11],
  }
  ```

  Other difference with `itertools.groupby`:

   * Iterable do not need to be sorted. Order of the original iterator is
     preserved in the group.
   * Transformation can be applied to the value too

  Args:
    iterable: The iterable to group
    key: Mapping applied to group the values (should return a hashable)
    value: Mapping applied to the values

  Returns:
    The dict
  )collectionsdefaultdictlistappenddict)r   r   r   groupsvr   r   r   groupby-   s    &
r   zIterable[_T]zCallable[[_T], bool]ztuple[list[_T], list[_T]])r   	predicater   c                 C  s8   g }g }| D ]"}||r$| | q| | q||fS )a]  Split the iterable into 2 lists (false, true), based on the predicate.

  Example:

  ```python
  small, big = epy.splitby([100, 4, 4, 1, 200], lambda x: x > 10)
  assert small == [4, 4, 1]
  assert big == [100, 200]
  ```

  Args:
    iterable: The iterable to split
    predicate: Function applied to split

  Returns:
    False list, True list
  )r   )r   r   Z
false_listZ	true_listr   r   r   r   splitbyY   s    r   zUnpack[dict[_KeyT, _ValuesT]]z(Iterator[_KeyT, tuple[Unpack[_ValuesT]]])dictsr   c                  '  sf   t tj|  }| d }t|t|kr<td|t |A  |D ]   t fdd| D fV  q@dS )a  Iterate over items of dictionaries grouped by their keys.

  Example:

  ```python
  d0 = {'a': 1, 'b': 2}
  d1 = {'a': 10, 'b': 20}
  d2 = {'a': 100, 'b': 200}

  list(epy.zip_dict(d0, d1, d2)) == [
      ('a', (1, 10, 100)),
      ('b', (2, 20, 200)),
  ]
  ```

  Args:
    *dicts: The dict to iterate over. Should all have the same keys

  Yields:
    The iterator of `(key, zip(*values))`

  Raises:
    KeyError: If dicts does not contain the same keys.
  r   zMissing keys: c                 3  s   | ]}|  V  qd S )Nr   ).0dr   r   r   	<genexpr>       zzip_dict.<locals>.<genexpr>N)set	itertoolschainlenKeyErrortuple)r   all_keysZd0r   r"   r   zip_dictw   s    r,   )__doc__
__future__r   r   r&   typingr   r   r   r   r   ZUnpackZTypeVarTupler   r	   Z_ValuesTr
   r   r   r   r   r   r,   r   r   r   r   <module>   s"   	,