Graeme
Graeme

Reputation: 4592

Is it possible to take a reference to a dictionary item in Python?

I have a function which repeatedly indexes into a dictionary with the same key. Is it possible to take a reference to the item in question?

def my_function(self, event):
    self.__observers[event] ... #this is get is performed multiple times
    observer_ref = self.__observers[event] #can I make this a reference to the value?

Update: The goal is to not take a copy of what is at self.__observers[event]. I am looking for behaviour akin to C++, e.g.

int x = 1
int& y = x #reference to y, not a copy

Upvotes: 1

Views: 163

Answers (3)

Gerrat
Gerrat

Reputation: 29680

It really depends on what you mean by "a reference". ...and it also depends on what you're going to do with the reference. eg.

class Test(object):
    def __init__(self):
        self.__observers = {'event1': {'test':'this'}, 'event2': {'test':'that'}}

    def get_observers(self):
        return self.__observers

    def my_function(self, event):
        observer_ref = self.__observers[event]
        return observer_ref

if __name__ == '__main__':
    t = Test()

    my_event = 'event1'  

    print('From class: {}'.format(t.get_observers()[my_event]))
    my_ref = t.my_function(my_event)
    print('From my_function: {}'.format(my_ref))

    my_ref['something'] = 'else'

    print('From my_function after addition: {}'.format(my_ref))
    print('From class after addition: {}'.format(t.get_observers()[my_event]))

    my_ref = 'something else entirely'

    print('From my_function after re-assignment: {}'.format(my_ref))
    print('From class after re-assignment: {}'.format(t.get_observers()[my_event]))

Results in :

From class: {'test': 'this'}
From my_function: {'test': 'this'}
From my_function after addition: {'test': 'this', 'something': 'else'}
From class after addition: {'test': 'this', 'something': 'else'}
From my_function after re-assignment: something else entirely
From class after re-assignment: {'test': 'this', 'something': 'else'}

Basically, if your reference is to an object of some sort, you can use that reference to manipulate that object. You just can't re-assign the name of the reference to something else and have it reflected back in the original object you pulled your reference from.

Upvotes: 0

Andrew Clark
Andrew Clark

Reputation: 208415

When you assign a value to a name (variable) in Python, the variable is just a reference to the value.

So for example say self.__observers[event] starts as an empty list, the following code would work fine:

assert self.__observers[event] == []
observer_ref = self.__observers[event]
observer_ref.append(1)                    # this modifies self.__observers[event]
assert self.__observers[event] == [1]

However, as pointed out by BrenBarn, if you were to then assign observer_ref a new value, it would not modify self.__observers[event] at all.

Upvotes: 3

BrenBarn
BrenBarn

Reputation: 251355

Of course. Why don't you try it and see?

As pointed out in a comment, though, it depends what you mean by "reference" If you do what you suggest, assigning to your new variable won't alter the dict.

>>> d = {'a': 1}
>>> d['a']
1
>>> x = d['a']
>>> x
1
>>> x = 2
>>> d
{u'a': 1}

Upvotes: 0

Related Questions