indexed_list.py 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. # Copyright (c) 2010-2019 openpyxl
  2. class IndexedList(list):
  3. """
  4. List with optimised access by value
  5. Based on Alex Martelli's recipe
  6. http://code.activestate.com/recipes/52303-the-auxiliary-dictionary-idiom-for-sequences-with-/
  7. """
  8. _dict = {}
  9. def __init__(self, iterable=None):
  10. self.clean = True
  11. self._dict = {}
  12. if iterable is not None:
  13. self.clean = False
  14. for idx, val in enumerate(iterable):
  15. self._dict[val] = idx
  16. list.append(self, val)
  17. def _rebuild_dict(self):
  18. self._dict = {}
  19. idx = 0
  20. for value in self:
  21. if value not in self._dict:
  22. self._dict[value] = idx
  23. idx += 1
  24. self.clean = True
  25. def __contains__(self, value):
  26. if not self.clean:
  27. self._rebuild_dict()
  28. return value in self._dict
  29. def index(self, value):
  30. if value in self:
  31. return self._dict[value]
  32. raise ValueError
  33. def append(self, value):
  34. if value not in self._dict:
  35. self._dict[value] = len(self)
  36. list.append(self, value)
  37. def add(self, value):
  38. self.append(value)
  39. return self._dict[value]