根据两个值在列表中组合字典

我希望在词典列表中合并词典。我的字典列表如下所示:


opt = [{'expiry': '2020-06-26', 'strike': 138.5, 'p_bid': 0.4375, 'p_ask': 0.46875}, 

       {'expiry': '2020-06-26', 'strike': 139.0, 'p_bid': 0.6875, 'p_ask': 0.71875}, 

       {'expiry': '2020-07-22', 'strike': 139.0, 'p_bid': 1.015625, 'p_ask': 1.0625}, 

       {'expiry': '2020-06-26', 'strike': 138.5, 'c_bid': 0.6875, 'c_ask': 0.734375}, 

       {'expiry': '2020-06-26', 'strike': 139.0, 'c_bid': 0.4375, 'c_ask': 0.484375}, 

       {'expiry': '2020-07-22', 'strike': 139.0, 'c_bid': 0.28125, 'c_ask': 0.3125}]

字典需要成对组合,其中“expiry”和“strike”相同。所需的输出如下所示:


[{'expiry': '2020-06-26', 'strike': 138.5, 'p_bid': 0.4375, 'p_ask': 0.46875, 'c_bid': 0.6875, 'c_ask': 0.734375}, 

 {'expiry': '2020-06-26', 'strike': 139.0, 'p_bid': 0.6875, 'p_ask': 0.71875, 'c_bid': 0.4375, 'c_ask': 0.484375}, 

 {'expiry': '2020-07-22', 'strike': 139.0, 'p_bid': 1.015625, 'p_ask': 1.0625, 'c_bid': 0.28125, 'c_ask': 0.3125}}]



墨色风雨
浏览 126回答 2
2回答

婷婷同学_

“天真的”方法:将字典添加到新的结果列表中。对于每个新的字典,检查它是否与列表中已有的字典匹配。如果是这样,请合并它们。如果没有,将其添加到列表中:res = [opt[0]]for d_new in opt[1:]:    for d in res:        if d['expiry'] == d_new['expiry'] and d['strike'] == d_new['strike']:       #if (d['expiry'], d['strike']) == (d_new['expiry'], d_new['strike']):            d.update(d_new)            break    else:        res.append(d_new)这使用了for/else在这里很有用的结构,因为我们只想在结果列表中没有与任何其他字典匹配的情况下将新字典添加到列表中。如果找到匹配项,我们将合并它们,break并且else不会执行。略有改进:上述方法导致O(n^2)for 循环每个 dict 的所有 dicts 的时间复杂度(不完全是,但学术上这仍然是O(n^2))。expiry为了尝试改进这一点,第二种方法可以是将具有相似且一次性的字典组合在一起strike( O(n)):from collections import defaultdictmerged_dicts = defaultdict(dict)for d in opt:    merged_dicts[(d['expiry'], d['strike'])].update(d)res = list(merged_dicts.values())这使用了collections.defaultdict在没有太多if条件的情况下轻松合并字典。我们还使用dict的update方法实际合并它们。

SMILET

一种相当简单的方法是使用 pandas:df = pd.DataFrame(opt)df = df.drop_duplicates(subset = ["expiry", "strike"])[ v.dropna().to_dict() for k,v in df.iterrows() ]结果是 :[{'expiry': '2020-06-26', 'strike': 138.5, 'p_bid': 0.4375, 'p_ask': 0.46875}, {'expiry': '2020-06-26', 'strike': 139.0, 'p_bid': 0.6875, 'p_ask': 0.71875}, {'expiry': '2020-07-22', 'strike': 139.0, 'p_bid': 1.015625, 'p_ask': 1.0625}]请注意,在删除重复项时,我保留了第一个元素。如果你想要的话,可以很容易地留下最后一个元素,但是使用:df = df.drop_duplicates(subset = ["expiry", "strike"], keep="last")在这种情况下,结果是:[{'expiry': '2020-06-26', 'strike': 138.5, 'c_bid': 0.6875, 'c_ask': 0.734375}, {'expiry': '2020-06-26', 'strike': 139.0, 'c_bid': 0.4375, 'c_ask': 0.484375}, {'expiry': '2020-07-22', 'strike': 139.0, 'c_bid': 0.28125, 'c_ask': 0.3125}]另一种方法是使用字典来减少“相似”值:reduction_dict = {(x["expiry"], x["strike"]):x for x in opt }list(reduction_dict.values())
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python