views:

88

answers:

2

Hello! I'm trying to create something following:

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

where @key1 is reference to dictionary['key1']. Thank You in advance.

+3  A: 

Use a new class:

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

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

Note the odd syntax because you have no way to know inside of which dictionary you are creating DictRef.

Aaron Digulla
Well, since it's not possible to do it without referencing d anyway, we might as well do `d = {'key1': [...]}; d.update({'key2': d['key2']})`.
delnan
+1  A: 

I'd expand Aaron Digulla's version. What he has now is replicated here:

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

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

I assume he wishes to replicate true reference semantics, so that accessing 'key2' will always give you a way to get to whatever 'key1' has as a value. the problem is while d['key1'] is a list, d['key2'] is a DictRef. So to get the "value" of 'key1' all you need to do is d['key1'], but for 'key2' you must do d[d['key2'].key]. Furthermore, you can't have a reference to a reference that works sanely, it would become d[d[d['key2'].key].key]. And how do you differentiate between a reference and a regular value? Probably through typechecking with isinstance(v, DictReference) (ew).

So I have a proposal to fix all of this.

Personally, I don't understand why true reference semantics are necessary. If they appear necessary, they can be made unnecessary by restructuring the problem, or the solution to the problem. It may even be that they were never necessary, and a simple d.update(key2=d['key1']) would have solved the issue.

Anyway, to the proposal:

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')
)

Now, in order to get the value of any key, whether it's a reference or not, one would simply do d[k].value(). If there are references to references, they will be dereferenced in a chain correctly. If they form a really long or infinite chain, Python will fail with a RuntimeError for excessive recursion.

Devin Jeanpierre