Search code examples
pythondictionaryfinancekeyerror

KeyError looping through multiple values per key


(This question may differ from "Iterating over dictionaries using 'for' loops" in that I have multiple entries for each key, and am also having issues 'pointing' to the right one).

There is this empty dictionary:

import .math

instruments = {}

The following simple method populates it:

 def add_instrument(par, T, coup, price, compounding_freq = 2):
      instruments[T] = (par, coup, price, compounding_freq)

add_instrument(100, 0.25, 0., 97.5)
add_instrument(100, 0.5, 0., 94.9)
add_instrument(100, 1.0, 3., 90.)
add_instrument(100, 1.5, 8, 96., 2)

If we check:

instruments.keys()

We obtain: [0.25, 0.5, 1.5, 1.0]

I would then like to loop through the dictionary and if coup == 0, do certain operation, else do something else:

for T in instruments.items():
    (par, coupon, price, freq) = instruments[T]
    if coupon == 0:
          do_something

But I am getting a #KeyError: (0.25, (100, 0.0, 97.5, 2))

Any idea why and how should i re-arrange the loop? TIA.

Edit: using the answer below, the BootstrapYieldCurve class works as planned, on the book 'Mastering Python for Finance', ch5.


Solution

  • T is the key, so you should iterate with for T in instruments:

    import math
    
    instruments = {} 
    
    def add_instrument(par, T, coup, price, compounding_freq = 2):
      instruments[T] = (par, coup, price, compounding_freq)
    
    add_instrument(100, 0.25, 0., 97.5)
    add_instrument(100, 0.5, 0., 94.9)
    add_instrument(100, 1.0, 3., 90.)
    add_instrument(100, 1.5, 8, 96., 2)
    
    for T in instruments:
        par, coupon, price, freq = instruments[T]
        if coupon == 0:
            print(T)
    

    If you use for T in instruments.items(), T becomes a tuple of (key, value). When you then look for instruments[T], there's no such key in the dict.

    You could also unpack the value tuple directly if you insist on using items():

    for t, (par, coup, price, freq) in instruments.items():
        if coup == 0:
            print(t)
    

    It outputs:

    0.25
    0.5