Доступ к словарю в виде списка - PullRequest
5 голосов
/ 21 июня 2011

У меня есть источник данных, который лучше всего моделируется словарем ( - это набор из ключ = значение пар).Для конкретной цели визуализации мне нужно предоставить интерфейс доступа к данным в виде списка (в дополнение к обычному интерфейсу словаря), что означает, что вы должны быть в состоянии сделать следующее:

data["mykey"] # returns the associated value
data[12][0] # returns the 13th key in the dictionary
data[12][1] # returns the 13th value in the dictionary

Я не могу найтисоответствующая реализация фасада - если я сохраню индексы в качестве ключа словаря:

data[12] = ("mykey", "myval")

, я могу легко решить последние два случая, но я теряю способность делать первый.Если я храню данные типа

data["mykey"] = "myval"

, мне нужно перечислить все ключи и значения во временном списке, прежде чем я смогу вернуть элементы.

Обратите внимание, что все эти реализации предполагают, что я использую OrderedDict.

Как бы вы предоставили оба интерфейса?

Если вам интересно, это для создания PyQt QAbstractTableModel, где основным контейнером данных является словарь.

Спасибо.

Ответы [ 4 ]

3 голосов
/ 21 июня 2011

Я должен сделать то же самое, чтобы представить данные в ListCtrl, который должен быть доступен по ключу, а не по индексу (иногда, чтобы его не нужно было искать, если я получаю произвольное значение для поиска).Если у вас есть список словарей, лучшее, что я нашел, было создать еще один словарь со ссылками на те же элементы, но доступный по ключу.Это становится моей загрузкой данных в методе:

  def SetData(self, cols, data):
    for idx, row in enumerate(data):
      item = dict((k, v.rstrip() if hasattr(v, 'rstrip') else v) for k, v in zip(cols, row))

      self.data[idx] = item

      self.byid[row[0]] = item

Итак, у меня есть список словарей, доступных в self.data, а затем другой словарь в self.byid, который содержит те же элементы, но по столбцу idстолбец 0 в моих строках в этом случае).Когда мне нужно обновить, пока я получаю идентификатор, я могу позвонить self.byid[id][field] = newval.Поскольку все в Python является указателем (ссылкой), изменение значения словаря, хранящегося в self.byid, отражается в списке словарей, хранящихся в self.data.Работает как шарм.

1 голос
/ 22 июня 2011

list(data.items())[12] вернет кортеж (key, value) для 13-й пары ключ-значение в вашем OrderedDict. list(data.keys())[12] вернет 13-й ключ сам по себе, а list(data.values())[12] вернет 13-е значение.

Это, вероятно, не очень хорошая идея для больших dict с, так как список воссоздается каждый раз.

(Однако это тот же самый метод, который OrderedDict использовал в своем методе __repr__: return '%s(%r)' % (self.__class__.__name__, list(self.items())))

0 голосов
/ 22 июня 2011

Возьмите ваш dict {} и создайте еще один, в котором ключи являются указателями, а значения являются либо ключами к исходному диктату, либо кортежем / списком из исходного диктанта.

d = {"key1":"value1","key2":"value2","key3":"value3"}
d2 = {1:"key1",2:"key2",3:"key3"}

Тогда:

d[d2[3]]

возвращает

'value3'

Или определяя d2 с помощью следующего:

d2 = {1:["key1","value1"],2:["key2","value2"],3:["key3","value3"]}

Получает вам требуемый доступ с помощью d2 [3] [0] и d2 [3] [1] для ключа и значения соответственно.

0 голосов
/ 22 июня 2011

Подкласс dict, который пытается получить доступ к ключам на основе индекса, но не переключается на доступ к ключу по умолчанию, может выполнить эту работу.Что-то вроде:

from collections import OrderedDict

class IndexableDict(OrderedDict):
    def __getitem__(self, key):
        """Attempt to return based on index, else try key"""
        try:
            _key = self.keys()[key]
            return (_key, super(IndexableDict, self).__getitem__(_key))
        except (IndexError, TypeError):
            return super(IndexableDict, self).__getitem__(key)

d = IndexableDict(spam='eggs', messiah=False)
d['messiah'] ## False
d[1] ## ('messiah', False)
d[0] ## ('spam', 'eggs')

РЕДАКТИРОВАТЬ: Это сломается, если вы используете целые числа в качестве ключей.

...