Skip to content

StableSet

Bases: PyoMutableSet[T]


              flowchart TD
              pyochain.collections._stable_set.StableSet[StableSet]
              pyochain.abc._set.PyoMutableSet[PyoMutableSet]
              pyochain.abc._set.PyoSet[PyoSet]
              pyochain.abc._collection.PyoCollection[PyoCollection]
              pyochain.abc._iterable.PyoIterable[PyoIterable]
              pyochain.rs.Pipeable[Pipeable]
              pyochain.rs.Into[Into]
              pyochain.rs.Inspect[Inspect]
              pyochain.rs.Checkable[Checkable]
              pyochain.abc._collection.PyoContainer[PyoContainer]
              pyochain.abc._collection.PyoSized[PyoSized]

                              pyochain.abc._set.PyoMutableSet --> pyochain.collections._stable_set.StableSet
                                pyochain.abc._set.PyoSet --> pyochain.abc._set.PyoMutableSet
                                pyochain.abc._collection.PyoCollection --> pyochain.abc._set.PyoSet
                                pyochain.abc._iterable.PyoIterable --> pyochain.abc._collection.PyoCollection
                                pyochain.rs.Pipeable --> pyochain.abc._iterable.PyoIterable
                                pyochain.rs.Into --> pyochain.rs.Pipeable
                
                pyochain.rs.Inspect --> pyochain.rs.Pipeable
                

                pyochain.rs.Checkable --> pyochain.abc._iterable.PyoIterable
                

                pyochain.abc._collection.PyoContainer --> pyochain.abc._collection.PyoCollection
                
                pyochain.abc._collection.PyoSized --> pyochain.abc._collection.PyoCollection
                





              click pyochain.collections._stable_set.StableSet href "" "pyochain.collections._stable_set.StableSet"
              click pyochain.abc._set.PyoMutableSet href "" "pyochain.abc._set.PyoMutableSet"
              click pyochain.abc._set.PyoSet href "" "pyochain.abc._set.PyoSet"
              click pyochain.abc._collection.PyoCollection href "" "pyochain.abc._collection.PyoCollection"
              click pyochain.abc._iterable.PyoIterable href "" "pyochain.abc._iterable.PyoIterable"
              click pyochain.rs.Pipeable href "" "pyochain.rs.Pipeable"
              click pyochain.rs.Into href "" "pyochain.rs.Into"
              click pyochain.rs.Inspect href "" "pyochain.rs.Inspect"
              click pyochain.rs.Checkable href "" "pyochain.rs.Checkable"
              click pyochain.abc._collection.PyoContainer href "" "pyochain.abc._collection.PyoContainer"
              click pyochain.abc._collection.PyoSized href "" "pyochain.abc._collection.PyoSized"
            

A mutable collection of unique elements which remember their insertion order.

Uses a dict as the underlying data structure to maintain insertion order while ensuring uniqueness of elements.

Thus, it has the same characteristics of "standard" sets, with lookup and iteration speed the same as a dict.

This is very similar to using Dict::from_keys with None values, but with a specialized interface for set operations.

Note

This is not the same as sortedcontainers, i.e it does not maintain the elements in sorted order, but rather in the order they were inserted.

Parameters:

Name Type Description Default
data Iterable[T]

Any Iterable of elements to initialize the set with.

required

Examples:

>>> from pyochain.collections import StableSet
>>>
>>> s = StableSet(("a", "b", "c"))
>>> s
StableSet('a', 'b', 'c')
>>> s.add("d")
>>> s
StableSet('a', 'b', 'c', 'd')
>>> s.discard("b")
>>> s
StableSet('a', 'c', 'd')
Source code in src/pyochain/collections/_stable_set.py
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
class StableSet[T](PyoMutableSet[T]):  # noqa: PLW1641
    """A mutable collection of unique elements which remember their insertion order.

    Uses a `dict` as the underlying data structure to maintain insertion order while ensuring uniqueness of elements.

    Thus, it has the same characteristics of "standard" sets, with lookup and iteration speed the same as a `dict`.

    This is very similar to using `Dict::from_keys` with `None` values, but with a specialized interface for set operations.

    Note:
        This is not the same as `sortedcontainers`, i.e it does not maintain the elements in sorted order, but rather in the order they were inserted.

    Args:
        data (Iterable[T]): Any `Iterable` of elements to initialize the set with.

    Examples:
        ```python
        >>> from pyochain.collections import StableSet
        >>>
        >>> s = StableSet(("a", "b", "c"))
        >>> s
        StableSet('a', 'b', 'c')
        >>> s.add("d")
        >>> s
        StableSet('a', 'b', 'c', 'd')
        >>> s.discard("b")
        >>> s
        StableSet('a', 'c', 'd')

        ```

    """

    _inner: dict[T, None]
    __slots__ = ("_inner",)  # pyright: ignore[reportUnannotatedClassAttribute, reportIncompatibleUnannotatedOverride]

    def __init__(self, data: Iterable[T]) -> None:
        self._inner = dict.fromkeys(data)

    @override
    def __repr__(self) -> str:
        return f"{self.__class__.__name__}({get_repr(self._inner.keys())})"

    @override
    def __iter__(self) -> Iterator[T]:
        return iter(self._inner)

    @override
    def __len__(self) -> int:
        return len(self._inner)

    @override
    def __contains__(self, item: object) -> bool:
        return item in self._inner

    @override
    def __eq__(self, other: object) -> bool:
        match other:
            case Set() | SetMut():
                return self._inner.keys() == other.inner  # pyright: ignore[reportUnknownMemberType]
            case AbstractSet():
                return self._inner.keys() == other
            case _:
                return False

    @staticmethod
    def from_ref[V](data: dict[V, Any]) -> StableSet[V]:  # pyright: ignore[reportExplicitAny]
        """Create a `StableSet` from a reference to an existing `dict`.

        This method wraps the provided `dict` without copying it, allowing for efficient object instanciation.

        This is the recommended way to create a `StableSet` from foreign functions that return `dict` objects.

        Warning:
            Since the `StableSet` directly references the original `dict`, any modifications made to the `StableSet` will also affect the original `dict`, and vice versa.

        Args:
            data (dict[V, Any]): The `dict` to wrap.

        Returns:
            StableSet[V]: A new `StableSet` instance.

        Example:
            ```python
            >>> from pyochain.collections import StableSet
            >>>
            >>> original = {"Alice": 30, "Bob": 25, "Charlie": 35}
            >>> set_obj = StableSet.from_ref(original)
            >>> set_obj
            StableSet('Alice', 'Bob', 'Charlie')
            >>> original["David"] = 40
            >>> set_obj
            StableSet('Alice', 'Bob', 'Charlie', 'David')

            ```
        """
        instance: StableSet[V] = StableSet.__new__(StableSet)  # pyright: ignore[reportUnknownVariableType]
        instance._inner = data
        return instance

    @override
    def add(self, value: T) -> None:
        self._inner[value] = None

    @override
    def discard(self, value: T) -> None:
        del self._inner[value]

    @override
    def intersection(self, other: AbstractSet[T]) -> SetMut[T]:
        return SetMut.from_ref(self._inner.keys() & other)

    @override
    def union(self, other: AbstractSet[T]) -> SetMut[T]:
        return SetMut.from_ref(self._inner.keys() | other)

    @override
    def difference(self, other: AbstractSet[T]) -> SetMut[T]:
        return SetMut.from_ref(self._inner.keys() - other)

    @override
    def symmetric_difference(self, other: AbstractSet[T]) -> SetMut[T]:
        return SetMut.from_ref(self._inner.keys() ^ other)

from_ref(data) staticmethod

Create a StableSet from a reference to an existing dict.

This method wraps the provided dict without copying it, allowing for efficient object instanciation.

This is the recommended way to create a StableSet from foreign functions that return dict objects.

Warning

Since the StableSet directly references the original dict, any modifications made to the StableSet will also affect the original dict, and vice versa.

Parameters:

Name Type Description Default
data dict[V, Any]

The dict to wrap.

required

Returns:

Type Description
StableSet[V]

StableSet[V]: A new StableSet instance.

Example
>>> from pyochain.collections import StableSet
>>>
>>> original = {"Alice": 30, "Bob": 25, "Charlie": 35}
>>> set_obj = StableSet.from_ref(original)
>>> set_obj
StableSet('Alice', 'Bob', 'Charlie')
>>> original["David"] = 40
>>> set_obj
StableSet('Alice', 'Bob', 'Charlie', 'David')
Source code in src/pyochain/collections/_stable_set.py
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
@staticmethod
def from_ref[V](data: dict[V, Any]) -> StableSet[V]:  # pyright: ignore[reportExplicitAny]
    """Create a `StableSet` from a reference to an existing `dict`.

    This method wraps the provided `dict` without copying it, allowing for efficient object instanciation.

    This is the recommended way to create a `StableSet` from foreign functions that return `dict` objects.

    Warning:
        Since the `StableSet` directly references the original `dict`, any modifications made to the `StableSet` will also affect the original `dict`, and vice versa.

    Args:
        data (dict[V, Any]): The `dict` to wrap.

    Returns:
        StableSet[V]: A new `StableSet` instance.

    Example:
        ```python
        >>> from pyochain.collections import StableSet
        >>>
        >>> original = {"Alice": 30, "Bob": 25, "Charlie": 35}
        >>> set_obj = StableSet.from_ref(original)
        >>> set_obj
        StableSet('Alice', 'Bob', 'Charlie')
        >>> original["David"] = 40
        >>> set_obj
        StableSet('Alice', 'Bob', 'Charlie', 'David')

        ```
    """
    instance: StableSet[V] = StableSet.__new__(StableSet)  # pyright: ignore[reportUnknownVariableType]
    instance._inner = data
    return instance