【问题标题】:How to iterate nested lists with another list to create a dictionary of lists Python如何使用另一个列表迭代嵌套列表以创建列表字典 Python
【发布时间】:2017-04-11 00:18:10
【问题描述】:

我正在使用 Mibian 模块来计算看涨期权。我有一个包含三个嵌套列表的列表。每个嵌套列表代表执行价格。每个嵌套列表都有各自的到期天数,即 my_list[2] 还剩 30 天。

     import mibian as mb
     import pandas as pd

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

     days_left = [5, 12, 30]

     my_list[2]
     [30, 40, 50, 60]

     days_left[2]
     30

用于计算看涨期权的 Mibian Black-Scholes 代码的结构。

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

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

给出一个包含 3 个列表的字典的输出,调用价格基于来自 my_list 的三个嵌套列表中的每一个。

        data1

         {0: [100.01095590221843,
              95.013694877773034,
              90.016433853327641,
              85.019172828882233,
              80.021911804436854,
              75.024650779991447],
         1: [70.027389755546068,
             68.028485345767905,
             66.029580935989742,
             64.030676526211579,
             62.03177211643343,
             60.032867706655267,
             43.042180223540925,
             22.05368392087027,
             19.055327306203068],
         2: [90.016433853327641,
             80.021911804436854,
             70.027389755546068,
             60.032867706655267]}

我想要得到的是嵌套列表和要一起迭代的日期

我想创建与上面相同的字典,但它不仅会迭代 my_list,还会按顺序迭代 days_left。

我尝试了 new_list = list(zip(days_left, my_list)) 的 zip 列表,但它给了我一个错误。有人可以帮忙吗?非常感谢。

    new_list = list(zip(my_list, days_left))

    [([20, 25, 30, 35, 40, 45], 5),
     ([50, 52, 54, 56, 58, 60, 77, 98, 101], 12),
     ([30, 40, 50, 60], 30)]

    data5 = dict()
    for x, days_left, my_list in enumerate(new_list):
             data5[x] = option5 = []
             for days_left, my_list in new_list:
                           c = mb.BS([120, my_list, 1, days_left ], 10)
                           option5.append(c.callPrice)

对于像 my_list[2] 这样的单个嵌套列表。输出是:

    range_list = list(range(1))

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

for i in my_list[2]:

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

    option2.append(c.callPrice)

option2


[90.024647403788975,
 80.032863205051967,
 70.041079006314973,
 60.049294807577965]

这些值与 data1[2] 中的值相似,但不同。理想的输出应该与 data1 具有相同的结构,具有三个字典,但由于 days_left,值略有不同。这些差异可能看起来微不足道,但稍后,我必须将它们乘以 100,这样这些差异就会增加。

【问题讨论】:

  • 输出应该是什么样子的?
  • 嗨 Austin,它应该看起来像上面 data1 中的字典,并且值应该看起来相似,但考虑了 days_left。例如,range_list = list(range(1)) data2 = dict() for x in range_list: data2[x] = option2 = [] for i in my_list[2]: c = mb.BS([120, i, 1, 30 ], 10) option2.append(c.callPrice) option2 的输出值将类似于 data1[2]、[90.024647403788975, 80.032863205051967, 70.041079006314973, 60.049294807577965]

标签: python list loops dictionary nested-lists


【解决方案1】:

我认为这可以满足您的需求。请注意,其中大部分是试图模拟您的环境 - 您只关心最后几行。

也就是说,按序号索引的数据结构不应该是字典,而应该是列表。 ;-)

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

Magic_index = 0

def mb(details, volatility):
    class C:
        def __init__(self, n):
            self.callPrice = n

    global Magic_index
    result = C(Magic_numbers[Magic_index])
    Magic_index += 1
    return result

mb.BS = mb

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

days_left = [5, 12, 30]

data99 = {}  # This is silly. A dict indexed by sequential numbers should be a list.

for i, (days, prices) in enumerate(zip(days_left, strike_prices)):
    data99[i] = [mb.BS([120, price, 1, days], 10).callPrice for price in prices]

import pprint
pprint.pprint(data99)

输出如下:

{0: [100.01095590221843,
     95.01369487777303,
     90.01643385332764,
     85.01917282888223,
     80.02191180443685,
     75.02465077999145],
 1: [70.02738975554607,
     68.0284853457679,
     66.02958093598974,
     64.03067652621158,
     62.03177211643343,
     60.03286770665527,
     43.042180223540925,
     22.05368392087027,
     19.05532730620307],
 2: [90.01643385332764,
     80.02191180443685,
     70.02738975554607,
     60.03286770665527]}

【讨论】:

  • 感谢奥斯汀的酷代码。不幸的是,它给出的值与我最初所做的值相同。有点困惑为什么会这样:S 最后4行应该与[90.024647403788975, 80.032863205051967, 70.041079006314973, 60.049294807577965]option2具有完全相同的值
  • 我写的代码只是使用了我从你那里复制和粘贴的数字。你是用你的“真正的”mb.BS 函数,还是我提供的假的?
  • 嗨 Austin,我重新检查了您的代码,但没有使用您创建的函数。我刚刚使用了以data99开头的那行代码,它成功了!真的太棒了! :) 感谢奥斯汀的帮助!
【解决方案2】:

我认为答案可能很简单:

for x, (days_left, my_list) in enumerate(new_list):
     data5[x] = option5 = []
     for days_left, my_list in new_list:
          c = mb.BS([120, my_list, 1, days_left ], 10)
                    option5.append(c.callPrice)

因为enumerate 的输出将采用(i, x) 的形式,在这种情况下x 是一个元组(即(i, (x, y)))。

【讨论】:

  • 嘿 ocasbranson,感谢您的输入,这是有道理的,但它似乎不起作用。继续收到TypeError: float() argument must be a string or a number, not a 'list' 已经为此工作了将近 3 天,所以可能只是认输,继续前进。不过感谢您的帮助。
  • 听起来问题出在cm.BS 的输入之一?但不可能从这些信息中分辨出来。尝试拆开你的循环并在它运行之前让它打印参数,然后你可以找出它失败的地方,以及它传递给函数的参数。
猜你喜欢
  • 1970-01-01
  • 2020-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-22
  • 2021-09-15
相关资源
最近更新 更多