Словарь Python для ссылки на соседний элемент словаря - PullRequest
7 голосов
/ 20 августа 2010

Я пытаюсь создать что-то следующее:

dictionary = {
   'key1': ['val1','val2'],
   'key2': @key1
}

, где @ key1 - это ссылка на словарь ['key1'].Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 20 августа 2010

Я бы расширил версию Аарона Дигуллы. То, что он имеет сейчас, копируется здесь:

class DictRef(object):
    def __init__(self, d, key): self.d, self.key = d, key

d = {}
d.update({
    'key1': ['val1','val2'],
    'key2': DictRef(d, 'key1')
})

Я предполагаю, что он хочет воспроизвести истинную ссылочную семантику, так что доступ к 'key2' всегда даст вам возможность получить то, что 'key1' имеет в качестве значения. проблема в том, что d['key1'] это list, d['key2'] это DictRef. Таким образом, чтобы получить «значение» 'key1', все что вам нужно сделать, это d['key1'], но для 'key2' вы должны сделать d[d['key2'].key]. Кроме того, вы не можете иметь ссылку на ссылку, которая работает разумно, она станет d[d[d['key2'].key].key]. И как вы различаете ссылку и обычное значение? Вероятно, через проверку типов с помощью isinstance (v, DictReference) ( ew ).

Так что у меня есть предложение исправить все это.

Лично я не понимаю, зачем нужна настоящая ссылочная семантика. Если они кажутся необходимыми, их можно сделать ненужными путем реструктуризации проблемы или решения проблемы. Может даже случиться так, что они никогда не были необходимы, и простой d.update(key2=d['key1']) решил бы проблему.

В любом случае, к предложению:

class DictRef(object):
    def __init__(self, d, key): 
        self.d = d
        self.key = key

    def value(self):
        return self.d[self.key].value()

class DictVal(object):
    def __init__(self, value):
        self._value = value

    def value(self):
        return self._value

d = {}
d.update(
    key1=DictVal(['val1', 'val2']),
    key2=DictRef(d, 'key1')
)

Теперь, чтобы получить значение любого ключа , независимо от того, является ли это ссылкой или нет, нужно просто сделать d[k].value(). Если есть ссылки на ссылки, они будут правильно разыменовываться в цепочке. Если они образуют очень длинную или бесконечную цепочку, Python завершится с ошибкой RuntimeError для чрезмерной рекурсии.

4 голосов
/ 20 августа 2010

Используйте новый класс:

class DictRef(object):
    def __init__(self, d, key): self.d, self.key = d, key

d = {}
d.update({
    'key1': ['val1','val2'],
    'key2': DictRef(d, 'key1')
})

Обратите внимание на странный синтаксис, поскольку у вас нет возможности узнать внутри какого словаря вы создаете DictRef.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...