DanielTheRocketMan
DanielTheRocketMan

Reputation: 3249

Python: DIvide items of a dictionary by a value that depends on the first key

I believe that this questions is very similar to Divide each python dictionary by total value, however I am not able to deal with multidimentional key.

So I have this first dictionary:

x={'SBGL': 0.2631678018921199, 'SBAR': 0.00017329658914466182, 'SBKP': 0.05787906885949929, 'SBRJ': 0.01686853063415596, 'SBFZ': 0.002151268003175112, 'SBCH': 0.0, 'SBRF': 0.0010995369794006128, 'SBFI': 0.0, 'SBGR': 0.3555667545433087, 'SBCT': 0.12645173241811486, 'SBFL': 0.0020536641771051302, 'SBSP': 0.12206752790423671, 'SBSV': 0.002883296698699977, 'SBMG': 0.0, 'SBCA': 0.0, 'SBPA': 0.024485612897250063, 'SBPS': 0.0006125138064595806, 'SBCF': 0.005023609170377438, 'SBMO': 0.0020686035382382908, 'SBBR': 0.01744718188871371, 'SBJV': 0.0}

I have this second dictionary:

   y= {('SBCF', 'TAM'): 294.0, ('SBCH', 'GLO'): 0.0, ('SBSP', 'ONE'): 0.0, ('SBGL', 'TAM'): 114094.0, ('SBCA', 'PTB'): 0.0, ('SBKP', 'GLO'): 0.0, ('SBMG', 'AZU'): 0.0, ('SBRF', 'GLO'): 1104.0, ('SBPA', 'AZU'): 23367.0, ('SBGR', 'AZU'): 313.0, ('SBGR', 'GLO'): 105170.0, ('SBCT', 'ONE'): 0.0, ('SBKP', 'TAM'): 160.0, ('SBGL', 'ONE'): 25330.0, ('SBGR', 'ONE'): 69043.0, ('SBCT', 'PTB'): 0.0, ('SBRJ', 'TAM'): 8118.0, ('SBPS', 'GLO'): 615.0, ('SBPA', 'TAM'): 1218.0, ('SBSV', 'GLO'): 1691.0, ('SBFI', 'AZU'): 0.0, ('SBSP', 'TAM'): 62158.0, ('SBKP', 'ONE'): 0.0, ('SBGR', 'PTB'): 0.0, ('SBGR', 'TAM'): 182484.0, ('SBCT', 'AZU'): 85180.0, ('SBBR', 'TAM'): 12685.0, ('SBBR', 'GLO'): 4833.0, ('SBGL', 'GLO'): 124812.0, ('SBJV', 'GLO'): 0.0, ('SBCT', 'TAM'): 11374.0, ('SBCT', 'GLO'): 30411.0, ('SBMO', 'GLO'): 1822.0, ('SBCF', 'AZU'): 4750.0, ('SBPA', 'GLO'): 0.0, ('SBCF', 'GLO'): 0.0, ('SBMO', 'TAM'): 255.0, ('SBFL', 'AZU'): 2062.0, ('SBFL', 'GLO'): 0.0, ('SBCA', 'AZU'): 0.0, ('SBRJ', 'GLO'): 7426.0, ('SBFI', 'ONE'): 0.0, ('SBKP', 'AZU'): 57954.0, ('SBFZ', 'TAM'): 97.0, ('SBSP', 'GLO'): 60405.0, ('SBRJ', 'AZU'): 1393.0, ('SBFZ', 'GLO'): 2063.0, ('SBSV', 'TAM'): 1204.0, ('SBAR', 'TAM'): 174.0, ('SBFI', 'GLO'): 0.0}

I want to divide all the items of y by a value that depends on the first key and comes from x. To be more precise, all the items of y that has the first key equal to 'SBCF' will be divided by x['SBCF']. All the items of y that has the first key equal to has the first key equal to 'SBCH' should be divided by x['SBCH'] and so on...

I tried something like this:

y = {[i,j]: v / (x[i]) for i,j,v in y.items()} 

I have got the error

 not enough values to unpack (expected 3, got 2)

Upvotes: 1

Views: 210

Answers (4)

Ripp_
Ripp_

Reputation: 2726

The error is due to the part i,j,v in y.items(). y.items() returns a enumerable collection of 2 item types of the form (<key>,<value>).
Since here your key is itself a tuple, you can unpack it further by wrapping the i,j in brackets so: (i,j),v in y.items() which will unpack the key item pair and then unpack the compound key.

Overall this gives: y = {[i,j]: v / (x[i]) for (i,j),v in y.items()}

You may also encounter the issue that the key cannot be a list, as lists cannot be hash, so you will have to substitute [i,j] for (i,j).

Upvotes: 1

cs95
cs95

Reputation: 402603

Wrap i and j with an additional set of parentheses, since y.items() returns something of the form <(k1, k2), v>.

Some things to account for:

  1. Division by 0
  2. How to handle missing entries in x

{(i, j) : v / max(x.get(i, 1), 1) for (i, j), v in y.items()}

You can either choose to handle the division by 0, or let an exception be thrown. Additionally, if i is missing in x, you should think how you'd want to handle that. I've assumed nothing is done (i.e., division by 1).

Upvotes: 3

user8060120
user8060120

Reputation:

you can try:

{k: v / (x[k[0]] or 1) for k,v in y.items()}

where x[k[0]] or 1 fix ZeroDivisionError

Upvotes: 1

Sunitha
Sunitha

Reputation: 12015

You can try something like this

y = {k: v / (x[k[0]]) for k,v in y.items() if x[k[0]]}

Upvotes: 0

Related Questions