Source code for circuit_knitting.utils.iteration

# This code is a Qiskit project.

# (C) Copyright IBM 2023.

# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""
Iteration utilities.

.. currentmodule:: circuit_knitting.utils.iteration

.. autosummary::
   :toctree: ../stubs/

   unique_by_id
   unique_by_eq
"""

import sys
from collections.abc import Iterable, ValuesView

# Certain calls to `zip` should be strict, but the `strict` kwarg was not added
# until Python 3.10.  The following allows us to begin marking today which
# calls should be strict, even though this will only be enforced on Python 3.10
# and later.
if sys.version_info >= (3, 10, 0):  # pragma: no cover

    def strict_zip(*args, **kwargs):
        """Equivalent to ``zip([...], strict=True)`` where supported."""
        return zip(*args, strict=True, **kwargs)

else:  # pragma: no cover
    strict_zip = zip  # type: ignore


[docs] def unique_by_id(iterable: Iterable, /) -> ValuesView: """Return unique objects in ``iterable``, by identity. >>> a = {0} >>> list(unique_by_id([a, a])) [{0}] >>> list(unique_by_id([a, a.copy()])) [{0}, {0}] """ return {id(x): x for x in iterable}.values()
[docs] def unique_by_eq(iterable: Iterable, /) -> list: """Return unique objects in ``iterable``, by equality. This function is only appropriate if (i) there are a small number of objects, and (ii) the objects are not guaranteed to be hashable. Otherwise, a ``dict`` or ``set`` is a better choice. This function may potentially make a comparison between all pairs of elements, so it executes in :math:`O(n^2)` time in the worst case, in contrast to a ``dict`` or ``set``, both of which can be constructed in :math:`O(n)` time. >>> a = {0} >>> list(unique_by_eq([a, a])) [{0}] >>> list(unique_by_eq([a, a.copy()])) [{0}] """ rv = [] for item in unique_by_id(iterable): if item not in rv: rv.append(item) return rv