Search code examples
pythondictionarydeep-copyshallow-copy

Python - shallow copy is not enough. Deepcopy or any alternative to improve speed?


I have this "template" dictionary:

_premium_per_month = {1: [0.0, []], 2: [0.0, []], 2: [0.0, []], 3: [0.0, []], 4: [0.0, []], 5: [0.0, []], 
        6: [0.0, []], 7: [0.0, []], 8: [0.0, []],
        9: [0.0, []], 10: [0.0, []], 11: [0.0, []], 12: [0.0, []]}

There is method that takes this dictionary and builds adding values. But when values change in shallow copied dictionary it also changes in template dict. So Should I use deepcopy or there some tips/tricks to have an alternative better/faster copy or pattern (maybe my pattern is wrong)?

And to have better understanding what it does, look at this method (it is simplified to just show the core problem)

def test(_premium_per_month):
  #premium_per_month = copy.deepcopy(_premium_per_month) this one works
  premium_per_month = _premium_per_month.copy() #not work
  for i in range(3):
      if i > 0:
        premium_per_month[i][0] += 20
  return premium_per_month

So using simple copy, of course changes original dictionary. Is deepcopy correct way to solve this problem or maybe I should change something else?


Solution

  • I guess this one would be more efficient if I dropped that template approach all together (Note. showing it here that object I mentioned in comments, so it would show why I use values as list, it is called contracts_list and _premium_per_month is not used here at all)?

    from datetime import datetime
    
    def test(self, contracts_list):
        premium_per_month = {}
        for contract in contracts_list:
            dt = datetime.strptime(contract.date_start, self._date_fmt)
            if d.get(dt.month):
                premium_per_month[dt.month][0] += contract.premium
                premium_per_month[dt.month][1].append(contract.id)
            else:
                val_lst = [contract.premium, [contract.id]]
                premium_per_month[dt.month] = val_lst 
        return premium_per_month