简体   繁体   中英

How to iterate unequal nested lists to create a new list Python

I'm stuck on iterating several nested lists in order to calculate Call options by using a Python module, Mibian.

If I use mibian to calculate made up European call options.

import mibian as mb

mb.BS([stock price, strike price, interest rate, days to maturity], volatility)


my_list = [[20, 25, 30, 35, 40, 45], 
           [50, 52, 54, 56, 58, 60, 77, 98, 101],
           [30, 40, 50, 60]]

For calculating multiple call options, first, I create a range. If I select, say the first nested list, my_list[0] , and run a for -loop. I get all the call options for the stock.

range_list = list(range(len(my_list)))
range_list
# [0, 1, 2]

data = dict()
for x in range_list:
    data[x] = option2 = []

    for i in my_list[0]:

        c = mb.BS([120, i, 1, 20 ], 10)

        option2.append(c.callPrice)

option2

This gives the 6 call prices of the first nested list from my_list.

Output:

 [100.01095590221843,
  95.013694877773034,
  90.016433853327641,
  85.019172828882233,
  80.021911804436854,
  75.024650779991447]

What I'm trying to figure out, is how I can iterate all the nested lists in one go, and get a new list of nested lists that contain the call option prices for my_list[0] , my_list[1] , and my_list[2] .

I'd like this output in one go for all three nested lists.

Output:

 [[100.01095590221843,    [70.027389755546068,    [90.016433853327641,
  95.013694877773034,     68.028485345767905,     80.021911804436854, 
  90.016433853327641,     66.029580935989742,     80.021911804436854,
  85.019172828882233,     64.030676526211579,     70.027389755546068,
  80.021911804436854,     62.03177211643343,      ]]
  75.024650779991447]     60.032867706655267,
                          43.042180223540925,
                          22.05368392087027,
                          19.055327306203068]

Can anyone help? I'm sure it's something very simple that I'm missing. Many thanks. PS I can't get the indentation right when editing my code on here.

Let's start with your current approach:

range_list = list(range(len(my_list)))

data = dict()
for x in range_list:
    data[x] = option2 = []
    for i in my_list[0]:
        c = mb.BS([120, i, 1, 20 ], 10)
        option2.append(c.callPrice)

The first thing you should note is that there is enumerate to get the index and the part at the same time, so you can omit the range_list variable:

data = dict()
for x, sublist in enumerate(my_list):
    data[x] = option2 = []
    for i in my_list[0]:
        c = mb.BS([120, i, 1, 20 ], 10)
        option2.append(c.callPrice)

This also takes care of the problem with the "dynamic indexing" because you can just iterate over the sublist :

data = dict()
for x, sublist in enumerate(my_list):
    data[x] = option2 = []
    for i in sublist:
        c = mb.BS([120, i, 1, 20 ], 10)
        option2.append(c.callPrice)

Then you can use a list comprehension to replace the inner loop:

data = dict()
for x, sublist in enumerate(my_list):
    data[x] = [mb.BS([120, i, 1, 20 ], 10).callPrice for i in sublist]

and if you feel like you want this shorter (not recommended but some like it) then use a dict comprehension instead of the outer loop:

data = {x: [mb.BS([120, i, 1, 20 ], 10).callPrice for i in sublist] 
        for x, sublist in enumerate(my_list)}

provided that

my_nested_list = [[1,2,3], [4,5,6,7], [8,9]]
[i for i in my_nested_list]

returns

[[1, 2, 3], [4, 5, 6, 7], [8, 9]]

something along

my_list = [[20, 25, 30, 35, 40, 45], [50, 52, 54, 56, 58, 60, 77, 98, 101],
      [30, 40, 50, 60]]    
[mb.BS([120, i, 1, 20 ], 10) for i in my_list]

shall return what you expect?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM