Вы можете использовать следующий класс для достижения того, что вы хотите:
from typing import List, Iterator, Iterable, Union, overload, Optional, \
Callable, Any
class UniqueError(ValueError):
def __init__(self):
super().__init__('all values in a UniqueList must be distinct')
raise self
class UniqueList(list):
def __init__(self, iterable=()) -> None:
super().__init__(iterable)
self.__unique = set(self)
if len(self) != len(self.__unique):
UniqueError()
def clear(self) -> None:
super().clear()
self.__unique.clear()
def copy(self) -> List[Any]:
type_self = type(self)
instance = type_self.__new__(type_self)
super(type_self, instance).__init__(self)
instance.__unique = self.__unique.copy()
return instance
def append(self, obj: Any) -> None:
if obj in self.__unique:
UniqueError()
self.__unique.add(obj)
super().append(obj)
def extend(self, iterable: Iterable[Any]) -> None:
copy = list(iterable)
if any(obj in self.__unique for obj in copy):
UniqueError()
super().extend(copy)
def pop(self, index: int = ...) -> Any:
value = super().pop(index)
self.__unique.remove(value)
return value
def index(self, obj: Any, start: int = ..., stop: int = ...) -> int:
return super().index(obj, start, stop)
def count(self, obj: Any) -> int:
return int(obj in self.__unique)
def insert(self, index: int, obj: Any) -> None:
if obj in self.__unique:
UniqueError()
self.__unique.add(obj)
super().insert(index, obj)
def remove(self, obj: Any) -> None:
super().remove(obj)
self.__unique.remove(obj)
def reverse(self) -> None:
super().reverse()
def sort(self, *, key: Optional[Callable[[Any], Any]] = ...,
reverse: bool = ...) -> None:
super().sort(key=key, reverse=reverse)
def __len__(self) -> int:
return super().__len__()
def __iter__(self) -> Iterator[Any]:
return super().__iter__()
def __str__(self) -> str:
return super().__str__()
def __hash__(self) -> int:
return super().__hash__()
@overload
def __getitem__(self, i: int) -> Any: ...
@overload
def __getitem__(self, s: slice) -> List[Any]: ...
def __getitem__(self, i: int) -> Any:
return super().__getitem__(i)
@overload
def __setitem__(self, i: int, o: Any) -> None: ...
@overload
def __setitem__(self, s: slice, o: Iterable[Any]) -> None: ...
def __setitem__(self, i: int, o: Any) -> None:
current = super().__getitem__(i)
if current == o or o in self.__unique:
UniqueError()
self.__unique.add(o)
self.__unique.remove(current)
super().__setitem__(i, o)
def __delitem__(self, i: Union[int, slice]) -> None:
self.__unique.remove(super().__getitem__(i))
super().__delitem__(i)
def __add__(self, x: List[Any]) -> List[Any]:
copy = self.copy()
copy += x
return copy
def __iadd__(self, x: Iterable[Any]) -> List[Any]:
self.extend(x)
return self
def __mul__(self, n: int) -> List[Any]:
raise NotImplementedError('multiplication is not supported')
def __rmul__(self, n: int) -> List[Any]:
raise NotImplementedError('multiplication is not supported')
def __imul__(self, n: int) -> List[Any]:
raise NotImplementedError('multiplication is not supported')
def __contains__(self, o: object) -> bool:
return super().__contains__(o)
def __reversed__(self) -> Iterator[Any]:
return super().__reversed__()
def __gt__(self, x: List[Any]) -> bool:
return super().__gt__(x)
def __ge__(self, x: List[Any]) -> bool:
return super().__ge__(x)
def __lt__(self, x: List[Any]) -> bool:
return super().__lt__(x)
def __le__(self, x: List[Any]) -> bool:
return super().__le__(x)