from typing import TypeVar, Generic, Optional, Iterable, AbstractSet, Union, Iterator, Any, Dict
T = TypeVar("T")
S = TypeVar("S")
class OrderedSet(Generic[T], AbstractSet[T]):
def __init__(self, base: Optional[Union[Dict[T, None], Iterable[T]]] = None):
super().__init__()
self.the_dict: Dict[T, None]
if not base:
self.the_dict = {}
elif isinstance(base, dict):
self.the_dict = base
else:
self.the_dict = dict.fromkeys(base)
def __eq__(self, o: object) -> bool:
return isinstance(o, OrderedSet) and list(self.the_dict) == list(o.the_dict)
def __ne__(self, o: object) -> bool:
return not self.__eq__(o)
def __str__(self) -> str:
return "{" + ", ".join(list(map(str, self.the_dict))) + "}"
def __repr__(self) -> str:
return f"OrderedSet({repr(self.the_dict)})"
def add(self, element: T) -> None:
self.the_dict = {**self.the_dict, **{element: None}}
def clear(self) -> None:
self.the_dict.clear()
def copy(self) -> 'OrderedSet[T]':
return OrderedSet(self.the_dict.copy())
def difference(self, s: Iterable[Any]) -> 'OrderedSet[T]':
return OrderedSet({e: None for e in self.the_dict if e not in s})
def difference_update(self, s: Iterable[Any]) -> None:
self.the_dict = {e: None for e in self.the_dict if e not in s}
def discard(self, element: T) -> None:
del self.the_dict[element]
def intersection(self, s: Iterable[Any]) -> 'OrderedSet[T]':
return OrderedSet({e: None for e in self.the_dict if e in s})
def intersection_update(self, s: Iterable[Any]) -> None:
self.the_dict = {e: None for e in self.the_dict if e in s}
def isdisjoint(self, s: Iterable[Any]) -> bool:
return self.the_dict.keys().isdisjoint(s)
def issubset(self, s: Iterable[Any]) -> bool:
return set(iter(self)).issubset(iter(s))
def issuperset(self, s: Iterable[Any]) -> bool:
return set(iter(self)).issuperset(iter(s))
def pop(self) -> T:
items = list(self.the_dict)
result = items.pop()
self.the_dict = dict.fromkeys(items)
return result
def remove(self, element: T) -> None:
del self.the_dict[element]
def symmetric_difference(self, s: Iterable[T]) -> 'OrderedSet[T]':
return OrderedSet(
dict.fromkeys([e for e in self.the_dict if e not in s] +
[e for e in s if e not in self.the_dict]))
def symmetric_difference_update(self, s: Iterable[T]) -> None:
self.the_dict = self.symmetric_difference(s).the_dict
def union(self, s: Iterable[T]) -> 'OrderedSet[T]':
return OrderedSet({**self.the_dict, **dict.fromkeys(s)})
def update(self, s: Iterable[T]) -> None:
self.the_dict = self.union(s).the_dict
def __len__(self) -> int:
return len(self.the_dict)
def __contains__(self, o: object) -> bool:
return o in self.the_dict
def __iter__(self) -> Iterator[T]:
return iter(self.the_dict)
def __and__(self, s: AbstractSet[object]) -> 'OrderedSet[T]':
return self.intersection(s)
def __iand__(self, s: AbstractSet[object]) -> 'OrderedSet[T]':
result = self.intersection(s)
self.the_dict = result.the_dict
return result
def __or__(self, s: AbstractSet[S]) -> 'OrderedSet[Union[T, S]]':
return self.union(s)
def __ior__(self, s: AbstractSet[S]) -> 'OrderedSet[Union[T, S]]':
result = self.union(s)
self.the_dict = result.the_dict
return result
def __sub__(self, s: AbstractSet[Optional[T]]) -> 'OrderedSet[T]':
return self.difference(s)
def __isub__(self, s: AbstractSet[Optional[T]]) -> 'OrderedSet[T]':
result = self.difference(s)
self.the_dict = result.the_dict
return result
def __xor__(self, s: AbstractSet[S]) -> 'OrderedSet[Union[T, S]]':
return self.symmetric_difference(s)
def __ixor__(self, s: AbstractSet[S]) -> 'OrderedSet[Union[T, S]]':
result = self.symmetric_difference(s)
self.the_dict = result.the_dict
return result
def __le__(self, s: AbstractSet[object]) -> bool:
return self.issubset(s)
def __lt__(self, s: AbstractSet[object]) -> bool:
return self.issubset(s) and len(self) < len(s)
def __ge__(self, s: AbstractSet[object]) -> bool:
return set(iter(self)) >= set(iter(s))
def __gt__(self, s: AbstractSet[object]) -> bool:
return set(iter(self)) > set(iter(s))
obj = OrderedSet()
obj.add(1)
obj.add(2)
obj.add(3)
print(set(obj))