Pythonic的方式来寻找日期时间最小的时间差异目标从列表?

问题描述:

我有一个日期时间对象target_time。我也有一个列表,例如times_list[i]['time']是日期时间对象。我想遍历这个列表并找到与target_time具有最短时间距离的项目的索引。这些差异将以毫秒为单位,列表中涵盖的时间范围将以分钟为单位。我目前的解决方案是相当笨拙的:Pythonic的方式来寻找日期时间最小的时间差异目标从列表?

best_index = -1 
best_diff = 999999999999.0 
for i in range(len(times_List)): 
    cur_time = times_list[i]['time'] 
    diff = abs((cur_time-target_time).total_seconds())) 
    if diff < best_diff: 
     best_index = i 
     best_diff = diff 
if best_index > -1: 
    result = times_list[best_index]['time'] 

是否有一个更笨拙和更pythonic这样做呢?

+0

请给我们处理样本数据结构,以及这些样本的期望输出。 – timgeb

import operator 
deltas = [abs(ti['time'] - target_time) for ti in times_list] 
min_index, min_delta = min(enumerate(deltas), key=operator.itemgetter(1)) 

替代方法:

temp = sorted(times_list, key=lambda x: abs(abs((x-target_time).total_seconds()))) 
result = times_list.index(temp[0]) 
+0

我喜欢这不需要导入。 –

+0

我永远不会明白为什么人们喜欢lambda而不是列表理解。 – guidot

+0

此方法效率低于其他方法。 'sort()'是O(n log n)_plus_列表需要重新扫描才能找到该项目。其他使用'min()'的解决方案是O(n)。 – mhawke

该功能可以找到最接近的:

from datetime import datetime 

def closest(target, dates):  
    return min(dates, key=lambda date: abs(date-target)) 


print(closest(target1, dates)) 
#2014-12-31 16:00:00 

print(closest(target2, dates)) 
#2015-01-01 12:00:00 
print(abs(target1 - target2)) 
+0

OP还要求项目的索引具有最小的增量。 – mhawke

使用min()找到差异最小。再加上enumerate()保持指数的轨迹:

min_pos, min_diff = min(enumerate(times_list), key=lambda t: abs(target_time - t[1]['time'])) 

无需产生分歧的中间列表。

+0

很确定't [1]'这里是一个错误,因为't [i]'是循环变量。 –

+0

@HalTL否,1是corect。这是传递给lambda表达式的元组的第二项。没有循环变量。 – mhawke