【问题标题】:Query from a list, to return from a dictionary of dictionary从列表中查询,从字典的字典中返回
【发布时间】:2021-01-25 09:56:28
【问题描述】:

一个列表和一个字典,如下,我想做一些查询。

列表中的每个元素都是人名和查询日期(字符串格式)

字典有人名key,value是一个以announcement_date(字符串格式)为key,bonus为value的字典。

从给定人员姓名和查询日期的列表中,我想找出人员的奖金,即公告日期最接近(并且早于)查询日期的时间。

例如,“Mike 20191022”将返回 Mike 在 20190630 宣布的奖金(即 105794.62)。

我尝试的是找出每个announcement_date的差异,并将它们与query_date进行比较。从最小的差异,我得到一个索引,并使用该索引返回对应的奖金。

import numpy as np

to_do = ["Mike 20191022"]

bonus = {'Mike': {'20200630': '105794.62', '20191231': '105794.62', '20190630': '105794.62', '20181231': '105794.62', '20180630': '95122.25', '20171231': '95122.25', '20170630': '95122.25'}}

for ox in to_do:
    to_do_people = ox.split(' ')[0]"
    to_do_date = ox.split(' ')[1]"
    for key, s_dict in bonus.items():"
        if to_do_people == key:"
            tem_list = []"
            for k, v in (s_dict.items()):"
                tem_list.append(int(to_do_date) - int(k))"
            idx = np.argmin(tem_list)"
            print (ox + '@Bonus@'  + list(s_dict.keys())[idx] + '@' + list(s_dict.values())[idx])"

但是它不起作用。输出是:

Mike 20191022@Bonus@20200630@105794.62

出了什么问题,我该如何纠正?谢谢。

【问题讨论】:

    标签: python list loops dictionary


    【解决方案1】:

    实际上,您应该附加abs 值。

    因为min(-1000, 100, 0)-1000,但你想要的是0

    tem_list.append(abs(int(to_do_date) - int(k)))
    

    输出为

    Mike 20191022@Bonus@20191231@105794.62
    

    但这并不能解决您的结果日期应该在查询日期之前的问题。通过将查询日期之后的所有日期设置为一个非常大的数字,可以轻松解决此问题。

    tem_list.append(abs(int(to_do_date) - int(k)) if (int(to_do_date)>=int(k)) else float('inf'))
    

    它的作用是为查询日期之后的所有日期设置infinity

    所以,解决方案变成了

    import numpy as np
    
    to_do = ["Mike 20191022"]
    
    bonus = {'Mike': {'20200630': '105794.62', '20191231': '105794.62', '20190630': '105794.62', '20181231': '105794.62', '20180630': '95122.25', '20171231': '95122.25', '20170630': '95122.25'}}
    
    for ox in to_do:
        to_do_people = ox.split(' ')[0]
        to_do_date = ox.split(' ')[1]
        for key, s_dict in bonus.items():
            if to_do_people == key:
                tem_list = []
                for k, v in (s_dict.items()):
                    tem_list.append(abs(int(to_do_date) - int(k)) if (int(to_do_date)>=int(k)) else float('inf'))
                idx = np.argmin(tem_list)
                print (ox + '@Bonus@'  + list(s_dict.keys())[idx] + '@' + list(s_dict.values())[idx])
    

    输出

    Mike 20191022@Bonus@20190630@105794.62
    

    【讨论】:

      【解决方案2】:

      由于您要导入numpy,请使用numpy.searchsorted

      >>> for query in to_do:
             name, date = query.split()
             keys = sorted(map(int,bonus[name].keys()))
             ix = np.searchsorted(keys, int(date), side='right') - 1
             print(f"{name} {date}@bonus@{keys[ix]}@{bonus[name][str(keys[ix])]}")
      
      Mike 20191022@bonus@20190630@105794.62
      

      解释:

      For first iteration, query == "Mike 20191022"
      >>> name, date = query.split()
      >>> name
      "Mike"
      >>> date
      "20191022"
      # then we sort the keys of the dict:
      >>> sorted(map(int,bonus[name].keys()))
      [20170630, 20171231, 20180630, 20181231, 20190630, 20191231, 20200630]
      # Now we search for the index of the first date >= query_date
      >>> np.searchsorted(keys, int(date), side='right')
      5
      # So 5th index is first date >= query_date
      # If we check, we will find: keys[5] == 20191231 > 20191022
      
      # However, we want the date before that, so subtract 1 from index
      >>> ix = np.searchsorted(keys, int(date), side='right') - 1
      >>> ix
      4
      # Now we first get the required date:
      >>> keys[ix] # == keys[4]
      20190630
      # And then we access the bonus:
      >>> bonus[name][str(keys[ix])]
      "105794.62"
      

      现在我们使用f-strings 打印它

      【讨论】:

      • 感谢您的帮助!你介意我选择另一个提供更详细指南的答案作为答案吗(你的高级,不是每个初学者都能赶上。:))
      • 当然,这是您的决定,无论您认为哪个更合适/有帮助。这个应该更快,但是,我同意初学者友好部分。我已经提供了numpy.searchsorted的文档,你可以点击关注官方指南,它会有所帮助。同时,我将添加一些解释。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-17
      • 2021-02-27
      • 2017-05-05
      相关资源
      最近更新 更多