一个列表,一个字典的字典,如下所示,我想做一些查询。
列表中的每个元素都是人名和query_date(字符串格式)
字典有人名的键,它的值是一个使用announcement_date(字符串格式)作为键,并使用bonus作为值的字典。
从给定人名和query_date的列表中,我想找出人们的奖金,即当announcement_date最接近(并且早于)query_date时。
例如,"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
出了什么问题,我该如何改正?
实际上,您应该附加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
由于您正在导入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