-1

I'd like to do something like this (this is a trivial example, but it shows the problem):

a = {'a' : 3, 'b': (lambda x: x * 3)(a['a'])}

but I want the value of a['b'] to get automatically updated when a['a'] changes.

In this case of course a['b'] gets evaluated only at the beginning, so I get this:

>>> a = {'a': 3, 'b': (lambda x: x * 3)(a['a'])}
>>> a
{'a': 3, 'b': 9}
>>> a['a'] = 4
>>> a
{'a': 4, 'b': 9}

What I want is this instead:

>>> a = {'a': 3, 'b':(lambda x: x * 3)(a['a'])}
>>> a
{'a': 3, 'b': 9}
>>> a['a'] = 4
>>> a
{'a': 4, 'b': 16}      <<<<<<<<<< change

Does anyone know if there's an easy/pythonic way to achieve this?

accdias
  • 5,160
  • 3
  • 19
  • 31
Fabri Ba
  • 119
  • 9
  • 1
    The code wouldn't run. Because ```a``` is not finished being declared and you are referencing ```a``` –  Aug 27 '21 at 12:14
  • 1
    To do this you'd have to inherit or compose a dictionary and implement this behaviour in `__getitem__`. – jonrsharpe Aug 27 '21 at 12:16
  • You basically want a `@property` as a dict item, which, TL;DR, isn't really possible. The closest and easiest would be to write a dict-like class. – deceze Aug 27 '21 at 12:18

1 Answers1

1

You can achieve that if you call the function upon retrieval:

a = {'a': 3, 'b': (lambda: a['a']*3)}

a["b"]()
# 9

a["a"] = 5
a["b"]()
# 15

But there are certainly better ways to such property like behavior.

user2390182
  • 72,016
  • 6
  • 67
  • 89
  • this is not bad, interesting that if I add () inside the definition of a it fails to update. Thanks! – Fabri Ba Aug 27 '21 at 12:21
  • 1
    The point is tht there is nothing dynamic left if you call it already upon definition (besides the fact that this doesn't work here). – user2390182 Aug 27 '21 at 12:22