# -*- coding: utf-8 -*-
"""
"""
from typing import Dict, List, Any, Tuple
[文档]
class IntKeyDict(dict):
"""
关键字只能为整数(Integer)类型的字典,已经存在的键值无法通过赋值方法(__setitem__)更改。
"""
__slots__: Tuple = ('indices_to_ids',
'ids_to_indices')
def __init__(self) -> None:
super().__init__()
self.indices_to_ids: Dict[int, int] = {}
self.ids_to_indices: Dict[int, int] = {}
self.update_indices()
def __setitem__(self, key: int, value: Any) -> None:
if isinstance(key, int):
if key in self:
raise KeyError(f"Key {key} already exists")
else:
super().__setitem__(key, value)
else:
raise TypeError("Key must be an integer")
[文档]
def update_indices(self) -> None:
list_of_keys = list(self.keys())
self.ids_to_indices = {key: i for i, key in enumerate(list_of_keys)}
self.indices_to_ids = {i: key for i, key in enumerate(list_of_keys)}
[文档]
def add_item_by_id(self, id_: int, item: Any) -> None:
self[id_] = item
[文档]
def get_items_by_ids(self, ids: List[int]) -> List[Any]:
if isinstance(ids, list):
return [self[id_] for id_ in ids]
else:
raise TypeError("Argument to get_items_by_ids() must be a list")
[文档]
def get_indices_by_ids(self, ids: List[int]) -> List[int]:
if isinstance(ids, list):
if len(self.ids_to_indices) != len(self):
self.update_indices()
return [self.ids_to_indices[id] for id in ids]
else:
raise TypeError("Argument to get_indices_by_ids() must be a list")
[文档]
def get_ids_by_indices(self, indices: List[int]) -> List[int]:
if isinstance(indices, list):
if len(self.ids_to_indices) != len(self):
self.update_indices()
return [self.indices_to_ids[index] for index in indices]
else:
raise TypeError("Argument to get_ids_by_indices() must be a list")
if __name__ == "__main__":
a = IntKeyDict()
# a[1] = f'x{1}'
# a[100] = f'x{100}'
# a[10] = f'x{10}'
for i in range(0, 1000000, 2):
a[i] = f'x{i}'
a.update_indices()
print(a.get_indices_by_ids([0, 2, 4]))
print(a.get_ids_by_indices([1, 3, 5]))