python: exclude the commons from two dicts

Viewed 49

Scenario:

I have two dicts, one is the factory_dct and the other is the sold_dct The scenario is that, exclude all the items from the factory_dct that are present in the sold_dct The difference is that, the factory dict has a key where as the sold_dct has the key inside the day

The following snippet takes a very long time when the data is huge, is there anyway I can optimise this?

def update_fctr_dct(factory_dct, sold_dct, day):
    for key in (set(factory_dct) & set(sold_dct)):
        if day in sold_dct[key]:
            sold_units = [d for d in factory_dct[key] for k, z in sold_dct[key][day].items() for z1 in z if
                 d['unit_id'] == z1['unit_id']]

            if sold_units:
               factory_dct[key] = [x for x in factory_dct[key] if x not in sold_units]
               factory_dct = {k: v for k, v in factory_dct.items() if v}

            else:
               print("No units sold this day")
2 Answers

The culprit seems to be this triple-loop list comprehension:

sold_units = [d for d in factory_dct[key]
                for k, z in sold_dct[key][day].items() for z1 in z
                if d['unit_id'] == z1['unit_id']]

Here, you basically compare each unit produced in the factory with each unit sold that day. Instead, you should just create a set of sold unit_ids and see if the produced unit's ID is in that set.

def update_fctr_dct(factory_dct, sold_dct, day):
    for key in factory_dct:
        if key in sold_dct and day in sold_dct[key]:
            sold_ids = {z1["unit_id"] for z in sold_dct[key][day].values() for z1 in z}
            
            if sold_ids:
               factory_dct[key] = [x for x in factory_dct[key]
                                     if x["unit_id"] not in sold_ids]
               factory_dct = {k: v for k, v in factory_dct.items() if v}

You might also replace the last line with a single conditional del factory_dct[key].

use symmetric_difference() on keys of your dict or you can also use ^ operator with set.

>>> a = {'1':1,'2':4}
>>> a
{'1': 1, '2': 4}
>>> b =  {'2':4, '3':9}
>>> b
{'2': 4, '3': 9}
>>> set(a)^set(b)
{'3', '1'}
Related