0

I know that Python's assignment operator does not copy objects, i.e. assigning a list to two variables does not copy the list. Therefore changing an element with one of the two variables changes 'both lists':

a = [1, 2, 3]
b = a
print(a, b) # output: [1, 2, 3] [1, 2, 3]
b[0] = 0
print(a, b) # output: [0, 2, 3] [0, 2, 3]

Same goes for dictionaries.

Suppose we want to pass a parameter dictionary with string keys and float or Callable values, i.e. params: dict[str, float | Callable] = {'a': lambda t: 0.5, 'b': 0.1} to an object. The object then creates lambda expressions for each non-callable value and stores this dictionary. Further, for every key that does not exist in the passed dictionary an element is added with the default value lambda t: 0.0. The object has a method to access said lambda expressions as well. The code could look like this:

class Parameters:
    params: dict[str, float | int | Callable] = {}

    def __init__(self, parameters: dict[str, float | int | Callable]) -> None:
        valid_keys = ['a', 'b', 'c']
        if len(parameters.keys() - valid_keys):
            raise ValueError(f"Invalid key in parameters! Valid keys are: {valid_keys}.")
        p = parameters.copy()
        # check if keys are callable, fix if not
        for key, value in p.items():
            if not hasattr(value, '__call__'):
                p[key] = lambda t: value
        # check if all keys are given, use 0 as default otherwise
        for key in valid_keys - p.keys():
            p[key] = lambda t: 0
        self.params = p

    def get_values(self, t: int) -> list:
        return [value(t) for value in self.params.values()]

The problem now is as follows: if we pass a dictionary with float values to the contructor, i.e. params = Parameters({'a': 0.5, 'b': 0.1}), print(params.get_values(1)) produces the output [0.1, 0.1, 0] instead of [0.5, 0.1, 0]. This unintended behavior is due to the first loop in the constructor and Python's assignment operator.

How could I do this in a way that the values are correct?

fakl
  • 127
  • 7

0 Answers0