Пропустим прелюдия, и не будем объяснять зачем это нужно. Будем прям как математики - сразу перейдем к делу.

Вам нужна структура данных которая и в словарь может и в индексы тоже ? Так вот же она:

(Обращение к элементу по индексу и ключу O(1), Нет большого оверхеда на хранение значений в словаре и в списке, так как это одни и те же объекты)

class IndexDict:
    """
    Словарь к которому можно обращаться по индексу.  
    """
    __slots__ = ['_date', '_index_list', '_index']

    def __init__(self):
        self._date = {}
        self._index_list = []
        self._index = 0

    def add(self, k, v):
        """
        Добавить элемент

        В лучшем O(1)
        В худшем O(N) * если все новые значения повторяются
        """
        # Исключаем дублирование в списке `_index_list`
        if self._date.get(k, None):
            self._index_list.remove(k)

        self._index_list.append(k)
        self._index += 1
        self._date[k] = v

    def removeKey(self, k: str):
        """
        Удаление по ключу

        В лучшем O(1)
        В худшем O(N) * если удаляться с конца массива
        """
        self._date.pop(k)
        self._index_list.remove(k)
        self._index -= 1

    def removeIndex(self, i: int):
        """
        Удаление по индексу

        В любом O(1)
        """
        self._date.pop(self._index_list.pop(i))
        self._index -= 1

    def getFromKey(self, k: str):
        """
        Получить значение по ключу

        В любом O(1)
        """
        return self._date[k]

    def getFromIndex(self, i: int):
        """
        Получит значение по индексу

        В любом O(1)
        """
        return self._date[self._index_list[i]]

Пример использования

if __name__ == '__main__':
    a = IndexDict()
    # ----------
    a.add('СПБ', 'Санкт-Петербург')
    a.add('МСК', 'Москва')
    a.add('ЕКБ', 'Екатеринбург')
    a.add('СО', 'Сочи')
    # ----------
    print(a.getFromIndex(2))
    print(a.getFromKey('ЕКБ'))
    if id(a.getFromIndex(2)) == id(a.getFromKey('ЕКБ')):
        print("Объекты равны")
    # -----------
    a.removeIndex(2)
    a.removeKey('СО')
    # -----------
    print(a.getFromIndex(1))
    print(a.getFromKey('СПБ'))
    # -----------

Комментарии (7)


  1. dopusteam
    21.08.2022 17:18
    +2

    Пропустим прелюдия, и не будем объяснять зачем это нужно

    Эх, пропустили самое интересно


    А зачем нужен _index? Везде только изменение его, но нигде нет чтения

    getFromKey и getFromIndex лучше переименовать в getByKey и getByIndex.

    removeIndex и removeKey не отражают сути, лучше тоже removeByIndex и removeByKey


    1. denisxab Автор
      21.08.2022 17:26
      -3

      ????


  1. abutorin
    21.08.2022 17:48

    А максимальный индекс у вас всегда будет равен размеру вашего контейнера?

    Почему при добавлении нового значения вы всегда увеливаете index на единицу, даже в случае если такое значение уже есть?


  1. Shreedeer
    21.08.2022 18:09
    +4

    Проще уж тогда сделать ещё одну мапу индексов на ключи, если в таковой есть нужда и искать по индексу вот так key_map[index_map[index]] и для этого не нужно делать ещё одну структуру данных, которая противоречит первому принципу в solid


  1. baldr
    21.08.2022 18:34
    +6

    О, опять Денис решил порадовать нас своим велосипедом на колесах с кирпичами. "документацию читать не хочу, там все непонятно" - снова, да?

    Словарь к которому можно обращаться по индексу.

    Словарь, значит? Но перегрузка скобок - это слишком сложно оказалось? А про UserDict надо в документации читать, а это трудно, понимаю.

    Вот это вот что за дичь такая?

    # Исключаем дублирование в списке `_index_list`

    if self._date.get(k, None):

    То есть значение с None у нас уже не считается значением?

    А имя "_date" - это отсылка к тому, что будут храниться только даты?

    И хотелось бы, правда, узнать сценарий, в котором будет реально нужен такой класс.

    Ну доколе это издевательство тут будет публиковаться? Казалось бы - почти каждая статья в глубоком минусе, но нет...


    1. xables
      22.08.2022 15:47

      Молодец, агрументы по факту


  1. randomsimplenumber
    21.08.2022 23:16
    +2

    В тегах юмор. А когда будет смешное?