'Python Error - Float object is not iterable error

I am quite new to python, and am still trying learn the ropes. I am trying to calculate Zero-Coupon bonds, however, seem to get the following error

float' object is not iterable

This is my code so far, I assume there is something wrong with my sum function, but any advice would be much appreciated !


prices = [98828.9817, 97812.0511, 96937.8969,
          96159.9962, 95269.2339, 94353.5669, 
          93276.0334, 92237.8837, 91261.0455, 
          90214.0597, 89083.9301, 87944.5962, 
          86976.3584, 85928.4188, 84982.5065,
          84248.2589, 83540.8304, 82911.5228,
          82417.0923, 82009.0742, 81633.1317,
          81287.3700, 81087.7608, 80919.5136, 
          80780.7515, 80669.7282, 80584.8196,
          80524.5143, 80487.4060, 80472.1856]

ytm = [0.04063, 0.04118, 0.04166, 
          0.04209, 0.04258, 0.04310,
          0.04371, 0.04431, 0.04487,
          0.04549, 0.04616, 0.04684,
          0.04743, 0.04807, 0.04866,
          0.04912, 0.04957, 0.04997,
          0.05028, 0.05054, 0.05079,
          0.05101, 0.05114, 0.05125,
          0.05134, 0.05141, 0.05147,
          0.05151, 0.05153, 0.05154]

iterations = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]

I = range(len(prices))
FV = 100000
CP = 0.04 * FV

# Zero Coupon Bond
for i in I:
    ZCB = sum(CP/(1+ytm[i])**iterations[i]) + (FV+CP)/((1+ytm[i])**iterations[i])
    print(ZCB)


Solution 1:[1]

sum() always take iterable as its argument when you write sum(2) This will raise TypeError and will say 2 is not iterable

similarly in your case sum() is taking float as its argument so the error "Float object is not iterable"

sum([2]) This will work because lists are iterable

Solution 2:[2]

The error comes from passing a single float to sum, which expects an iterable (like a list).

I can't quite tell what your original intent is, since you're mixing both procedural and functional styles. I'd recommend that you either incrementally sum ZCB yourself, using the += operator, or else, since all your arguments are the same length, use numpy to do vector math on them.

The reason I hesitate to rewrite your code in a functional style is because you're only using sum() on the first part of your formula, and I'm not sure whether you meant to sum the entire thing. Leaving your formula alone, the second part will iterate and produce multiple values for ZCB:

import numpy as np
sum(CP/(1+np.array(ytm))**np.array(iterations)) + (FV+CP)/((1+np.array(ytm))**np.array(iterations))
 
array([162407.65073366, 158404.21266146, 154482.50164677, 150656.78642701,
       146896.169642  , 143206.13145474, 139553.99871209, 135986.89550577,
       132528.65334532, 129123.4633484 , 125775.53903412, 122512.19342737,
       119406.9801568 , 116365.77283386, 113461.4536341 , 110755.24145864,
       108160.10924376, 105704.56954205, 103416.55213126, 101263.70203759,
        99213.23619558,  97276.48018957,  95493.00572611,  93807.47916263,
        92215.90751991,  90714.30147789,  89291.81257265,  87951.62415916,
        86689.91102085,  85496.36006465])

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Deepak Tripathi
Solution 2 Derek T. Jones