martonbognar
martonbognar

Reputation: 462

Referencing a dictionary value before creation

I want to create a dictionary where one value is dependent on a different value in the same dictionary.

The usual way to do this is something along the lines of:

>>> my_dict = {'quantity': 10}
>>> my_dict.update({'total': my_dict['quantity'] * 20})
>>> my_dict
{'quantity': 10, 'total': 200}

Is there a way to do this with one statement? Here's what I thought might work, but didn't:

>>> my_dict = {'quantity': 10, 'total': my_dict['quantity'] * 20}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'my_dict' is not defined

Upvotes: 1

Views: 213

Answers (2)

Paulo Almeida
Paulo Almeida

Reputation: 8061

You can create your own dictionary:

class MyDict(dict):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if 'quantity' in self:
            self['total'] = self['quantity'] * 20

Then this will work as you want:

>>> d = MyDict(quantity=10)
>>> d
{'quantity': 10, 'total': 200}

Of course, anyone will be able to change total to whatever they want, independently of quantity. You could override update and __setitem__ to prevent direct assignments of total (and automatically update it when quantity is changed), or you may want to look into property.


If you want to pass the function to calculate total when you create the dictionary, as in your example, you can have a parameter for that:

class MyDict(dict):
    def __init__(self, *args, **kwargs):
        self.total_function = kwargs.pop('total_function', lambda x: x)
        super().__init__(*args, **kwargs)
        if 'quantity' in self:
            self['total'] = self.total_function(self['quantity'])

>>> d = MyDict(quantity=10)
>>> d
{'quantity': 10, 'total': 10}
>>> d = MyDict(quantity=10, total_function=lambda x: x * 20)
>>> d
{'quantity': 10, 'total': 200}

Upvotes: 2

Graipher
Graipher

Reputation: 7186

It works if you have/save the value in a variable beforehand and use that:

n = 10
d = {'quantity': n, 'total': n * 20}

Upvotes: 1

Related Questions