获取最近的日期到给定的日期 [英] Getting the closest date to a given date

查看:152
本文介绍了获取最近的日期到给定的日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

鉴于此基准日期:

  base_date =10/29 06:58 AM

我想在列表中找到一个元组,其中包含最接近 base_date ,但不能是较早的日期。

  list_date = [('10 / 30 02:18 PM','-103','-107'),( '10 / 30 02:17 PM','+100','-110')$ \\ 
('10 / 29 02:15 AM','-101','-109')$ b所以这里的输出应该是('10/30 02:17 PM',$ b



< '+100','-110')
(它不能是第3个元组,因为发生日期早于基准日期)



我的问题是,是否存在这样的日期比较的任何模块?我试图首先将数据全部更改为 AM 格式,然后进行比较,但是我的代码在很多切片中变得丑陋。



@edit:



要测试的大列表:

  [('10/30 02:18 PM','+ 13 -103','-13 -107'),('10 / 30 02:17 PM','+13 +100','-13 -110'),('10 / 30 02:15 PM','+ 13 -101','-13 -109' 10/30 02:14 PM','+ 13 -103','-13 -107'),('10 / 30 01:59 PM','+ 13 -105','-13 -105'), ('10 / 30 01:46 PM','+ 13 -106','-13 -104'),('10 / 30 01:37 PM','+ 13 -105','-13 -105' ),('10 / 30 01:24 PM','+ 13 -107','-13 -103'),('10 / 30 01:23 PM','+ 13 -106','-13  - 104'),('10 / 30 01:05 PM','+ 13 -103','-13 -107'),('10 / 30 01:02 PM','+13 -104',' 13-106'),('10 / 30 12:55 PM','+ 13 -103','-13 -107'),('10 / 30 12:51 PM','+13.5 -110' '-13.5 +100'),('10 / 30 12:44 PM','+13.5 -108','-13.5 -102'),('10 / 30 12:38 PM','+13.5 -107 ','-13.5〜103'),('10 / 30 12:35 PM','+13〜102' -13 -108'),('10 / 30 12:34 PM','+ 13 -103','-13 -107'),('10 / 30 12:06 PM','+13.5 -110' ,'-13.5 +100'),('10 / 30 11:57 AM','+13.5 -108','-13.5 -102'),('10 / 30 11:36 AM','+13.5  - 107','-13.5 -103'),('10 / 30 09:01 AM','+13.5 -110','-13.5 + 100'),('10 / 30 08:59 AM','+ ('10/30 08:13 AM','+13.5 -105','-13.5 -105'),('10 / 30 06:11 AM', '+13.5 +100','-13.5 -110'),('10 / 30 06:09 AM','+13.5 -105','-13.5 -105'),('10 / 30 06:04 AM ','+13.5 -110','-13.5 + 100'),('10 / 30 05:32 AM','+13.5 -105','-13.5 -105'),('10 / 30 04: ('10 / 30 12:51 AM','+13.5 -110','-13.5 + 100'),('10 / 29 01:31 PM','+13.5 -105','-13.5 -105'),('10 / 29 01:31 PM','+13 +103','-13 -113'),('10 / 29 01:28 PM','+13 -102','-13 -108'),('10 / 29 07:59 AM','+13 -105' ,'-13 -105'),('10 / 29 07:20 AM','+ 13 -103','-13 -107'),('10 / 29 07:14 AM','+13  - 105','-13 -105'),('10 / 29 04:47 AM','+13 + 100','-13 -110'),('10 / 29 04:14 AM','+ 13-105','-13 -105'),('10 / 28 08:17 PM','+12.5 + 100','-12.5 -110'),('10 / 28 12:52 PM' '+12.5 -105','-12.5 -105')] 

大列表test2: / p>

  [('10/30 04:30 PM','+1.5 -111','-1.5 +101'), ('10 / 30 04:24 PM','+1.5 -110','-1.5 + 100'),('10 / 30 04:21 PM','+1.5 -111','-1.5 +101' ),('10 / 30 04:15 PM','+1.5 -112','-1.5 +102'),('10 / 30 04:14 PM','+1.5 -110','-1.5 + 100'),('10 / 30 03:57 PM','+1.5 -111','-1.5 +101'),('10 / 30 03:40 PM','+1.5 -110' 1.5 + 100'),('10 / 30 03:31 PM','+1.5 -111','-1.5 +101'),('10 / 30 03:30 PM','+1.5 -109' '-1.5 -101'),('10 / 30 03:25 PM','+1.5 -107','-1.5〜103'),('10 / 30 03:24 PM','+1.5 -110','-1.5 +100'),('10 / 30 03:23 PM' +1.5 -108','-1.5 -102'),('10 / 30 03:22 PM','+1.5 -106','-1.5 -104'),('10 / 30 02:14 PM' ,'+1.5 -104','-1.5 -106'),('10 / 30 01:41 PM','+1.5 -105','-1.5 -105'),('10 / 30 01:37 ('10 / 30 01:36 PM','+1.5 -105','-1.5 -105'),('10 / 30 01 :06 PM','+1.5 -103','-1.5 -107'),('10 / 30 12:56 PM','+2 -111','-2 + 101'),('10 / 30'12:53 PM','+2 -110','-2 +100'),('10 / 30 12:50 PM','+2 -113','-2 + 103' 10/30 12:49 PM','+2 -112','-2 +102'),('10 / 30 12:46 PM','+ 2 -113','-2 +103'), ('10 / 30 12:45 PM','+2 -110','-2 +100'),('10 / 30 12:43 PM','+ 2 -108','-2 -102' ),('10 / 30 12:38 PM','+2.5 -116','-2.5 + 106'),('10 / 30 12:38 PM','+2.5 -113','-2.5 + 103'),('10 / 30 12:3下午7点,'+2.5 -110','-2.5 + 100'),('10 / 30 10:30 AM','+2.5 -105','-2.5 -105' 10:07 AM','+3 -113','-3 +103'),('10 / 30 09:55 AM','+3 -112','-3 + 102'),('10 / 30 09:51 AM','+3 -110','-3 +100'),('10 / 30 09:32 AM','+3 -109','-3 -101'),( '10 / 30 06:04 AM','+3 -110','-3 +100'),('10 / 30 03:16 AM','+3 -107','-3〜103') ,('10 / 30 03:14 AM','+3.5 -116','-3.5 +106'),('10 / 30 01:03 AM','+3.5 -115','-3.5 +105 '',('10 / 30 12:17 AM','+3.5 -110','-3.5 + 100'),('10 / 29 08:52 PM','+3.5 -108','-3.5 -102'),('10 / 29 01:31 PM','+3.5 -105','-3.5 -105'),('10 / 29 06:48 AM','+3.5 -110' -3.5 +100'),('10 / 29 06:47 AM','+3.5 -109','-3.5 -101'),('10 / 29 05:39 AM','+3.5 -113' ,'-3.5 + 103'),('10 / 29 03:34 AM','+3.5 -108','-3.5 -102'),('10 / 29 12:44 AM','+3.5  - 110','-3.5 +100 '',('10 / 29 12:41 AM','+3.5 -107','-3.5 -103'),('10 / 29 12:40 AM','+3.5 -105','-3.5 -105'),('10 / 28 12:52 PM','+4 -105','-4 -105')] 


解决方案

 >>>来自datetime import timedelta,datetime 
>>>> base_date =10/29 06:58 AM
>>> b_d = datetime.strptime(base_date,%m /%d%I:%M%p)
def func(x):
d = datetime.strptime(x [0],%m /%d%I:%M%p)
delta = d - b_d如果d> b_d else timedelta.max
返回delta
...
>>> min(list_date,key = func)
('10 / 30 02:17 PM','+100','-110')

datetime.strptime 将日期转换为datetime对象,因此 b_d 现在看起来像这样:

 >>> b_d 
datetime.datetime(1900,10,29,6,58)

现在我们可以编写一个可以传递给键的函数参数 min

  delta = d  -  b_d if d> b_d else timedelta.max 

if d> b_d 即如果传递给 min 的日期大于 base_date 然后将其差异 delta else将 timedelta.max 分配给它。

 >>> timedelta.max 
datetime.timedelta(999999999,86399,9999999)

更新:

 >>>来自datetime import timedelta,datetime 
>>>> base_date = '10 / 29 06:59 AM'
>>> b_d = datetime.strptime(base_date,%m /%d%I:%M%p)
>>> def func(x):
... d = datetime.strptime(x [0],%m /%d%I:%M%p)
... delta = b_d如果d> b_d else timedelta.max
...返回delta
...
>>> lis2 = [('10 / 30 04:30 PM','+1.5 -111','-1.5 +101'),('10 / 30 04:24 PM','+1.5 -110','-1.5 +100'),('10 / 30 04:21 PM','+1.5 -111','-1.5 +101'),('10 / 30 04:15 PM','+1.5 -112' -1.5 +102'),('10 / 30 04:14 PM','+1.5 -110','-1.5 + 100'),('10 / 30 03:57 PM','+1.5 -111' ,'-1.5 + 101'),('10 / 30 03:40 PM','+1.5 -110','-1.5 + 100'),('10 / 30 03:31 PM',' 111','-1.5 + 101'),('10 / 30 03:30 PM','+1.5 -109','-1.5 -101'),('10 / 30 03:25 PM','+ (10/30 03:24 PM,+1.5 -110,-1.5 + 100),('10/30 03:23 PM', '+1.5 -108','-1.5 -102'),('10 / 30 03:22 PM','+1.5 -106','-1.5 -104'),('10 / 30 02:14 PM ','+1.5 -104','-1.5 -106'),('10 / 30 01:41 PM','+1.5 -105','-1.5 -105'),('10 / 30 01:下午3点半,'+1.5 -107','-1.5 -103'),('10 / 30 01:36 PM','+1.5 -105','-1.5 -105'),( 10/30 01:06 PM','+1.5 -103','-1.5 -107'),('10 / 30 12:56 PM','+2 -111','-2 + 101'), ('10 / 30 12:53 PM','+2 -110','-2 +100'),('10 / 30 12:50 PM','+2 -113','-2 +103' ),('10 / 30 12:46 PM','+2 -112','-2 + 102'),('10 / 30 12:46 PM','+2 -113',' 103'),('10 / 30 12:45 PM','+2 -110','-2 +100'),('10 / 30 12:43 PM','+ 2 -108' 2 -102'),('10 / 30 12:38 PM','+2.5 -116','-2.5 + 106'),('10 / 30 12:38 PM','+2.5 -113' '-2.5 +103'),('10 / 30 12:37 PM','+2.5 -110','-2.5 + 100'),('10 / 30 10:30 AM','+ 2.5-105 ','-2.5 -105'),('10 / 30 10:07 AM','+3 -113','-3 +103'),('10 / 30 09:55 AM','+3 -112','-3 + 102'),('10 / 30 09:51 AM','+3 -110','-3 +100'),('10 / 30 09:32 AM' +3 -109','-3 -101'),('10 / 30 06:04 AM','+3 -110','-3 +100'),('10 / 30 03:16 AM' ,'+ 3 -107','-3 -103'),('10 / 30 03:14 AM','+3.5 -116','-3.5 +106'),('10 / 30 01:03 AM','+3.5 -115','-3.5 +105'),('10 / 30 12:17 AM','+3.5 -110','-3.5 + 100'),('10 / 29 08:52 PM','+3.5 -108','-3.5 -102'), '10 / 29 01:31 PM','+3.5 -105','-3.5 -105'),('10 / 29 06:48 AM','+3.5 -110','-3.5 + 100') ,('10 / 29 06:47 AM','+3.5 -109','-3.5 -101'),('10 / 29 05:39 AM','+3.5 -113','-3.5 + 103 '',('10 / 29 03:34 AM','+3.5 -108','-3.5 -102'),('10 / 29 12:44 AM','+3.5 -110','-3.5 +100'),('10 / 29 12:41 AM','+3.5 -107','-3.5 -103'),('10 / 29 12:40 AM','+3.5 -105' -3.5 -105'),('10 / 28 12:52 PM','+4 -105','-4 -105')]
>>>> min(lis2,key = func)
('10 / 29 01:31 PM','+3.5 -105','-3.5 -105')
pre>

时间比较:



脚本:

 从datetime import datetime,timedelta 
import sys
import time
list_date = [('10 / 30 04:30 PM','+1.5 -111','-1.5 +101'),('10 / 30 04:24 PM','+1.5 -110','-1.5 + 100'),('10 / 30 04 ('10 / 30 04:15 PM','+1.5 -112','-1.5 + 102'),('10 / 30 04:15 PM','+1.5 -111','-1.5 + 3004:14 PM,'+1.5 -110','-1.5 + 100'),('10 / 30 03:57 PM','+1.5 -111','-1.5 +101' 10/30 03:40 PM','+1.5 -110','-1.5 + 100'),('10 / 30 03:31 PM','+1.5 -111','-1.5 +101'), ('10 / 30 03:30 PM','+1.5 -109','-1.5 -101'),('10 / 30 03:25 PM','+1.5 -107','-1.5 -103' ),('10 / 30 03:24 PM','+1.5 -110','-1.5 +100'),('10 / 30 03:23 PM','+1.5 -108','-1.5 - 102') ,('10 / 30 03:22 PM','+1.5 -106','-1.5 -104'),('10 / 30 02:14 PM','+1.5 -104','-1.5 -106 '',('10 / 30 01:41 PM','+1.5 -105','-1.5 -105'),('10 / 30 01:37 PM','+1.5 -107','-1.5 -103'),('10 / 30 01:36 PM','+1.5 -105','-1.5 -105'),('10 / 30 01:06 PM','+1.5〜103' -1.5 -107'),('10 / 30 12:56 PM','+2 -111','-2 +101'),('10 / 30 12:53 PM','+2 -110' ,'-2 +100'),('10 / 30 12:50 PM','+2 -113','-2 +103'),('10 / 30 12:49 PM',' 112','-2 + 102'),('10 / 30 12:46 PM','+2 -113','-2 +103'),('10 / 30 12:45 PM','+ 2 -110','-2 +100'),('10 / 30 12:43 PM','+ 2 -108','-2 -102'),('10 / 30 12:38 PM' '+2.5 -116','-2.5 + 106'),('10 / 30 12:38 PM','+2.5 -113','-2.5 +103'),('10 / 30 12:37 PM ','+2.5 -110','-2.5 +100'),('10 / 30 10:30 AM','+2.5 -105','-2.5 -105'),('10 / 30 10: 07 AM','+3 -113', -3 +103'),('10 / 30 09:55 AM','+3 -112','-3 + 102'),('10 / 30 09:51 AM','+3 -110' ,'-3 +100'),('10 / 30 09:32 AM','+3 -109','-3 -101'),('10 / 30 06:04 AM','+3 - 110','-3 +100'),('10 / 30 03:16 AM','+ 3 -107','-3 -103'),('10 / 30 03:14 AM','+ ('10/30 01:03 AM','+3.5 -115','-3.5 +105'),('10 / 30 12:17 AM', '+3.5 -110','-3.5 +100'),('10 / 29 08:52 PM','+3.5 -108','-3.5 -102'),('10 / 29 01:31 PM ','+3.5 -105','-3.5 -105'),('10 / 29 06:48 AM','+3.5 -110','-3.5 + 100'),('10 / 29 06:上午五时五十分,'+3.5 -109','-3.5 -101'),('10 / 29 05:39 AM','+3.5 -113','-3.5 +103' 03:34 AM','+3.5 -108','-3.5 -102'),('10 / 29 12:44 AM','+3.5 -110','-3.5 + 100'),('10 / 29 12:41 AM','+3.5 -107','-3.5 -103'),('10 / 29 12:40 AM','+3.5 -105','-3.5 -105'),( '10 / 28 12:52 PM ,'+4 -105','-4 -105')]

base_date =10/29 06:58 AM

def func1(list_date):
#http://stackoverflow.com/a/17249420/846892
get_datetime = lambda s:datetime.strptime(s,%m /%d%I:%M%p)
base = get_datetime(base_date)
later = filter(lambda d:get_datetime(d [0])> base,list_date)
return min(later,key = lambda d:get_datetime(d [0]))

def func2(list_date):
#http:// stackoverflow .com / a / 17249470/846892
b_d = datetime.strptime(base_date,%m /%d%I:%M%p)
def func(x):
d = datetime.strptime(x [0],%m /%d%I:%M%p)
delta = d - b_d如果d> b_d else timedelta.max
return delta
return min(list_date,key = func)

def func3(list_date):
#http://stackoverflow.com / a / 17249529/846892
fmt ='%m /%d%I:%M%p'
d = datetime.strptime(base_date,fmt)
def foo(x):
return(datetime.strptime(x [0],fmt)-d).total_seconds()> 0
返回排序(list_date,key = foo)[ - 1]

def func4(list_date):
#http://stackoverflow.com/a/17249441/846892
fmt ='%m /%d%I:%M%p'
base_d = datetime.strptime(base_date,fmt)
candidates =((datetime.strptime(d,fmt) ,d,x,y)for d,x,y在list_date中)
candidates =对于dt,d,x,y中的dt,d,x,y,如果dt> base_d)
返回候选人[1:]

结果:

 >>>从这样导入* 

#check输出irst
>>> func1(list_date)
('10 / 29 01:31 PM','+3.5 -105','-3.5 -105')
>>> func2(list_date)
('10 / 29 01:31 PM','+3.5 -105','-3.5 -105')
>>> func3(list_date)
('10 / 29 01:31 PM','+3.5 -105','-3.5 -105')
>>> func4(list_date)
('10 / 29 01:31 PM','+3.5 -105','-3.5 -105')

>>> %timeit func1(list_date)
100循环,最好3:3.07 ms每循环
>>>> %timeit func2(list_date)
100循环,最好3:1.59 ms每循环#winner
>>> %timeit func3(list_date)
100循环,最好3:1.91 ms每循环
>>> %timeit func4(list_date)
1000循环,最好3:2.02 ms每循环

#increase输入大小
>>> list_date = list_date * 10 ** 3
>>> len(list_date)
48000
>>> %timeit func1(list_date)
1循环,最佳3:3.6 s每循环
>>>> %timeit func2(list_date)#winner
1循环,最好3:1.99 s每循环
>>>> %timeit func3(list_date)
1循环,最好3:2.09秒每循环
>>> %timeit func4(list_date)
1循环,最好3:2.02 s每循环


#再次增加输入大小

>> ;> list_date = list_date * 10
>>> len(list_date)
480000
>>> %timeit func1(list_date)
1循环,最好3:36.4 s每循环
>>> %timeit func2(list_date)#winner
1循环,最好为3:20.2 s每循环
>>> %timeit func3(list_date)
1循环,最好3:22.8 s每循环
>>> %timeit func4(list_date)
1循环,最好3:22.7 s每循环


Given this base date:

base_date = "10/29 06:58 AM"

I want to find a tuple within the list that contains the closest date to the base_date, but it must not be an earlier date.

list_date = [('10/30 02:18 PM', '-103', '-107'), ('10/30 02:17 PM', '+100', '-110'), \
             ('10/29 02:15 AM', '-101', '-109') 

so here the output should be ('10/30 02:17 PM', '+100', '-110') (it can't be the 3rd tuple because the date there happened earlier than the base date)

My question is, does it exist any module for such date comparison? I tried to first change the data all to AM format and then compare but my code gets ugly with lots of slicing.

@edit:

Big list to test:

[('10/30 02:18 PM', '+13 -103', '-13 -107'), ('10/30 02:17 PM', '+13 +100', '-13 -110'), ('10/30 02:15 PM', '+13 -101', '-13 -109'), ('10/30 02:14 PM', '+13 -103', '-13 -107'), ('10/30 01:59 PM', '+13 -105', '-13 -105'), ('10/30 01:46 PM', '+13 -106', '-13 -104'), ('10/30 01:37 PM', '+13 -105', '-13 -105'), ('10/30 01:24 PM', '+13 -107', '-13 -103'), ('10/30 01:23 PM', '+13 -106', '-13 -104'), ('10/30 01:05 PM', '+13 -103', '-13 -107'), ('10/30 01:02 PM', '+13 -104', '-13 -106'), ('10/30 12:55 PM', '+13 -103', '-13 -107'), ('10/30 12:51 PM', '+13.5 -110', '-13.5 +100'), ('10/30 12:44 PM', '+13.5 -108', '-13.5 -102'), ('10/30 12:38 PM', '+13.5 -107', '-13.5 -103'), ('10/30 12:35 PM', '+13 -102', '-13 -108'), ('10/30 12:34 PM', '+13 -103', '-13 -107'), ('10/30 12:06 PM', '+13.5 -110', '-13.5 +100'), ('10/30 11:57 AM', '+13.5 -108', '-13.5 -102'), ('10/30 11:36 AM', '+13.5 -107', '-13.5 -103'), ('10/30 09:01 AM', '+13.5 -110', '-13.5 +100'), ('10/30 08:59 AM', '+13.5 -108', '-13.5 -102'), ('10/30 08:13 AM', '+13.5 -105', '-13.5 -105'), ('10/30 06:11 AM', '+13.5 +100', '-13.5 -110'), ('10/30 06:09 AM', '+13.5 -105', '-13.5 -105'), ('10/30 06:04 AM', '+13.5 -110', '-13.5 +100'), ('10/30 05:32 AM', '+13.5 -105', '-13.5 -105'), ('10/30 04:48 AM', '+13.5 -107', '-13.5 -103'), ('10/30 12:51 AM', '+13.5 -110', '-13.5 +100'), ('10/29 01:31 PM', '+13.5 -105', '-13.5 -105'), ('10/29 01:31 PM', '+13 +103', '-13 -113'), ('10/29 01:28 PM', '+13 -102', '-13 -108'), ('10/29 07:59 AM', '+13 -105', '-13 -105'), ('10/29 07:20 AM', '+13 -103', '-13 -107'), ('10/29 07:14 AM', '+13 -105', '-13 -105'), ('10/29 04:47 AM', '+13 +100', '-13 -110'), ('10/29 04:14 AM', '+13 -105', '-13 -105'), ('10/28 08:17 PM', '+12.5 +100', '-12.5 -110'), ('10/28 12:52 PM', '+12.5 -105', '-12.5 -105')]

Big list to test2:

[('10/30 04:30 PM', '+1.5 -111', '-1.5 +101'), ('10/30 04:24 PM', '+1.5 -110', '-1.5     +100'), ('10/30 04:21 PM', '+1.5 -111', '-1.5 +101'), ('10/30 04:15 PM', '+1.5 -112', '-1.5 +102'), ('10/30 04:14 PM', '+1.5 -110', '-1.5 +100'), ('10/30 03:57 PM', '+1.5 -111', '-1.5 +101'), ('10/30 03:40 PM', '+1.5 -110', '-1.5 +100'), ('10/30 03:31 PM', '+1.5 -111', '-1.5 +101'), ('10/30 03:30 PM', '+1.5 -109', '-1.5 -101'), ('10/30 03:25 PM', '+1.5 -107', '-1.5 -103'), ('10/30 03:24 PM', '+1.5 -110', '-1.5 +100'), ('10/30 03:23 PM', '+1.5 -108', '-1.5 -102'), ('10/30 03:22 PM', '+1.5 -106', '-1.5 -104'), ('10/30 02:14 PM', '+1.5 -104', '-1.5 -106'), ('10/30 01:41 PM', '+1.5 -105', '-1.5 -105'), ('10/30 01:37 PM', '+1.5 -107', '-1.5 -103'), ('10/30 01:36 PM', '+1.5 -105', '-1.5 -105'), ('10/30 01:06 PM', '+1.5 -103', '-1.5 -107'), ('10/30 12:56 PM', '+2 -111', '-2 +101'), ('10/30 12:53 PM', '+2 -110', '-2 +100'), ('10/30 12:50 PM', '+2 -113', '-2 +103'), ('10/30 12:49 PM', '+2 -112', '-2 +102'), ('10/30 12:46 PM', '+2 -113', '-2 +103'), ('10/30 12:45 PM', '+2 -110', '-2 +100'), ('10/30 12:43 PM', '+2 -108', '-2 -102'), ('10/30 12:38 PM', '+2.5 -116', '-2.5 +106'), ('10/30 12:38 PM', '+2.5 -113', '-2.5 +103'), ('10/30 12:37 PM', '+2.5 -110', '-2.5 +100'), ('10/30 10:30 AM', '+2.5 -105', '-2.5 -105'), ('10/30 10:07 AM', '+3 -113', '-3 +103'), ('10/30 09:55 AM', '+3 -112', '-3 +102'), ('10/30 09:51 AM', '+3 -110', '-3 +100'), ('10/30 09:32 AM', '+3 -109', '-3 -101'), ('10/30 06:04 AM', '+3 -110', '-3 +100'), ('10/30 03:16 AM', '+3 -107', '-3 -103'), ('10/30 03:14 AM', '+3.5 -116', '-3.5 +106'), ('10/30 01:03 AM', '+3.5 -115', '-3.5 +105'), ('10/30 12:17 AM', '+3.5 -110', '-3.5 +100'), ('10/29 08:52 PM', '+3.5 -108', '-3.5 -102'), ('10/29 01:31 PM', '+3.5 -105', '-3.5 -105'), ('10/29 06:48 AM', '+3.5 -110', '-3.5 +100'), ('10/29 06:47 AM', '+3.5 -109', '-3.5 -101'), ('10/29 05:39 AM', '+3.5 -113', '-3.5 +103'), ('10/29 03:34 AM', '+3.5 -108', '-3.5 -102'), ('10/29 12:44 AM', '+3.5 -110', '-3.5 +100'), ('10/29 12:41 AM', '+3.5 -107', '-3.5 -103'), ('10/29 12:40 AM', '+3.5 -105', '-3.5 -105'), ('10/28 12:52 PM', '+4 -105', '-4 -105')]

解决方案

>>> from datetime import timedelta, datetime
>>> base_date = "10/29 06:58 AM"
>>> b_d = datetime.strptime(base_date, "%m/%d %I:%M %p")
def func(x):
    d =  datetime.strptime(x[0], "%m/%d %I:%M %p")
    delta =  d - b_d if d > b_d else timedelta.max
    return delta
... 
>>> min(list_date, key = func)
('10/30 02:17 PM', '+100', '-110')

datetime.strptime converts the date to a datetime object, so b_d now looks something like this :

>>> b_d
datetime.datetime(1900, 10, 29, 6, 58)

Now we can write a function that can be passed to key parameter of min:

delta =  d - b_d if d > b_d else timedelta.max

if d > b_d i.e if the date passed to min is greater than base_date then assign their difference to delta else assign timedelta.max to it.

>>> timedelta.max
datetime.timedelta(999999999, 86399, 999999)

Update:

>>> from datetime import timedelta, datetime
>>> base_date = '10/29 06:59 AM'
>>> b_d = datetime.strptime(base_date, "%m/%d %I:%M %p")
>>> def func(x):
...         d =  datetime.strptime(x[0], "%m/%d %I:%M %p")
...         delta =  d - b_d if d > b_d else timedelta.max
...         return delta
... 
>>> lis2 = [('10/30 04:30 PM', '+1.5 -111', '-1.5 +101'), ('10/30 04:24 PM', '+1.5 -110', '-1.5     +100'), ('10/30 04:21 PM', '+1.5 -111', '-1.5 +101'), ('10/30 04:15 PM', '+1.5 -112', '-1.5 +102'), ('10/30 04:14 PM', '+1.5 -110', '-1.5 +100'), ('10/30 03:57 PM', '+1.5 -111', '-1.5 +101'), ('10/30 03:40 PM', '+1.5 -110', '-1.5 +100'), ('10/30 03:31 PM', '+1.5 -111', '-1.5 +101'), ('10/30 03:30 PM', '+1.5 -109', '-1.5 -101'), ('10/30 03:25 PM', '+1.5 -107', '-1.5 -103'), ('10/30 03:24 PM', '+1.5 -110', '-1.5 +100'), ('10/30 03:23 PM', '+1.5 -108', '-1.5 -102'), ('10/30 03:22 PM', '+1.5 -106', '-1.5 -104'), ('10/30 02:14 PM', '+1.5 -104', '-1.5 -106'), ('10/30 01:41 PM', '+1.5 -105', '-1.5 -105'), ('10/30 01:37 PM', '+1.5 -107', '-1.5 -103'), ('10/30 01:36 PM', '+1.5 -105', '-1.5 -105'), ('10/30 01:06 PM', '+1.5 -103', '-1.5 -107'), ('10/30 12:56 PM', '+2 -111', '-2 +101'), ('10/30 12:53 PM', '+2 -110', '-2 +100'), ('10/30 12:50 PM', '+2 -113', '-2 +103'), ('10/30 12:49 PM', '+2 -112', '-2 +102'), ('10/30 12:46 PM', '+2 -113', '-2 +103'), ('10/30 12:45 PM', '+2 -110', '-2 +100'), ('10/30 12:43 PM', '+2 -108', '-2 -102'), ('10/30 12:38 PM', '+2.5 -116', '-2.5 +106'), ('10/30 12:38 PM', '+2.5 -113', '-2.5 +103'), ('10/30 12:37 PM', '+2.5 -110', '-2.5 +100'), ('10/30 10:30 AM', '+2.5 -105', '-2.5 -105'), ('10/30 10:07 AM', '+3 -113', '-3 +103'), ('10/30 09:55 AM', '+3 -112', '-3 +102'), ('10/30 09:51 AM', '+3 -110', '-3 +100'), ('10/30 09:32 AM', '+3 -109', '-3 -101'), ('10/30 06:04 AM', '+3 -110', '-3 +100'), ('10/30 03:16 AM', '+3 -107', '-3 -103'), ('10/30 03:14 AM', '+3.5 -116', '-3.5 +106'), ('10/30 01:03 AM', '+3.5 -115', '-3.5 +105'), ('10/30 12:17 AM', '+3.5 -110', '-3.5 +100'), ('10/29 08:52 PM', '+3.5 -108', '-3.5 -102'), ('10/29 01:31 PM', '+3.5 -105', '-3.5 -105'), ('10/29 06:48 AM', '+3.5 -110', '-3.5 +100'), ('10/29 06:47 AM', '+3.5 -109', '-3.5 -101'), ('10/29 05:39 AM', '+3.5 -113', '-3.5 +103'), ('10/29 03:34 AM', '+3.5 -108', '-3.5 -102'), ('10/29 12:44 AM', '+3.5 -110', '-3.5 +100'), ('10/29 12:41 AM', '+3.5 -107', '-3.5 -103'), ('10/29 12:40 AM', '+3.5 -105', '-3.5 -105'), ('10/28 12:52 PM', '+4 -105', '-4 -105')]
>>> min(lis2, key = func)
('10/29 01:31 PM', '+3.5 -105', '-3.5 -105')

Timing comparisons:

Script:

from datetime import datetime, timedelta
import sys
import time
list_date = [('10/30 04:30 PM', '+1.5 -111', '-1.5 +101'), ('10/30 04:24 PM', '+1.5 -110', '-1.5     +100'), ('10/30 04:21 PM', '+1.5 -111', '-1.5 +101'), ('10/30 04:15 PM', '+1.5 -112', '-1.5 +102'), ('10/30 04:14 PM', '+1.5 -110', '-1.5 +100'), ('10/30 03:57 PM', '+1.5 -111', '-1.5 +101'), ('10/30 03:40 PM', '+1.5 -110', '-1.5 +100'), ('10/30 03:31 PM', '+1.5 -111', '-1.5 +101'), ('10/30 03:30 PM', '+1.5 -109', '-1.5 -101'), ('10/30 03:25 PM', '+1.5 -107', '-1.5 -103'), ('10/30 03:24 PM', '+1.5 -110', '-1.5 +100'), ('10/30 03:23 PM', '+1.5 -108', '-1.5 -102'), ('10/30 03:22 PM', '+1.5 -106', '-1.5 -104'), ('10/30 02:14 PM', '+1.5 -104', '-1.5 -106'), ('10/30 01:41 PM', '+1.5 -105', '-1.5 -105'), ('10/30 01:37 PM', '+1.5 -107', '-1.5 -103'), ('10/30 01:36 PM', '+1.5 -105', '-1.5 -105'), ('10/30 01:06 PM', '+1.5 -103', '-1.5 -107'), ('10/30 12:56 PM', '+2 -111', '-2 +101'), ('10/30 12:53 PM', '+2 -110', '-2 +100'), ('10/30 12:50 PM', '+2 -113', '-2 +103'), ('10/30 12:49 PM', '+2 -112', '-2 +102'), ('10/30 12:46 PM', '+2 -113', '-2 +103'), ('10/30 12:45 PM', '+2 -110', '-2 +100'), ('10/30 12:43 PM', '+2 -108', '-2 -102'), ('10/30 12:38 PM', '+2.5 -116', '-2.5 +106'), ('10/30 12:38 PM', '+2.5 -113', '-2.5 +103'), ('10/30 12:37 PM', '+2.5 -110', '-2.5 +100'), ('10/30 10:30 AM', '+2.5 -105', '-2.5 -105'), ('10/30 10:07 AM', '+3 -113', '-3 +103'), ('10/30 09:55 AM', '+3 -112', '-3 +102'), ('10/30 09:51 AM', '+3 -110', '-3 +100'), ('10/30 09:32 AM', '+3 -109', '-3 -101'), ('10/30 06:04 AM', '+3 -110', '-3 +100'), ('10/30 03:16 AM', '+3 -107', '-3 -103'), ('10/30 03:14 AM', '+3.5 -116', '-3.5 +106'), ('10/30 01:03 AM', '+3.5 -115', '-3.5 +105'), ('10/30 12:17 AM', '+3.5 -110', '-3.5 +100'), ('10/29 08:52 PM', '+3.5 -108', '-3.5 -102'), ('10/29 01:31 PM', '+3.5 -105', '-3.5 -105'), ('10/29 06:48 AM', '+3.5 -110', '-3.5 +100'), ('10/29 06:47 AM', '+3.5 -109', '-3.5 -101'), ('10/29 05:39 AM', '+3.5 -113', '-3.5 +103'), ('10/29 03:34 AM', '+3.5 -108', '-3.5 -102'), ('10/29 12:44 AM', '+3.5 -110', '-3.5 +100'), ('10/29 12:41 AM', '+3.5 -107', '-3.5 -103'), ('10/29 12:40 AM', '+3.5 -105', '-3.5 -105'), ('10/28 12:52 PM', '+4 -105', '-4 -105')]

base_date = "10/29 06:58 AM"

def func1(list_date):
    #http://stackoverflow.com/a/17249420/846892
    get_datetime = lambda s: datetime.strptime(s, "%m/%d %I:%M %p")
    base = get_datetime(base_date)
    later = filter(lambda d: get_datetime(d[0]) > base, list_date)
    return min(later, key = lambda d: get_datetime(d[0]))

def func2(list_date):
    #http://stackoverflow.com/a/17249470/846892
    b_d = datetime.strptime(base_date, "%m/%d %I:%M %p")
    def func(x):
       d =  datetime.strptime(x[0], "%m/%d %I:%M %p")
       delta =  d - b_d if d > b_d else timedelta.max
       return delta
    return min(list_date, key = func)

def func3(list_date):
    #http://stackoverflow.com/a/17249529/846892
    fmt = '%m/%d %I:%M %p'
    d = datetime.strptime(base_date, fmt)
    def foo(x):
        return (datetime.strptime(x[0],fmt)-d).total_seconds() > 0
    return sorted(list_date, key=foo)[-1]

def func4(list_date):
    #http://stackoverflow.com/a/17249441/846892
    fmt = '%m/%d %I:%M %p'
    base_d = datetime.strptime(base_date, fmt)
    candidates = ((datetime.strptime(d, fmt), d, x, y) for d, x, y in list_date)
    candidates = min((dt, d, x, y) for dt, d, x, y in candidates if dt > base_d)
    return  candidates[1:]

Results:

>>> from so import *

#check output irst
>>> func1(list_date)
('10/29 01:31 PM', '+3.5 -105', '-3.5 -105')
>>> func2(list_date)
('10/29 01:31 PM', '+3.5 -105', '-3.5 -105')
>>> func3(list_date)
('10/29 01:31 PM', '+3.5 -105', '-3.5 -105')
>>> func4(list_date)
('10/29 01:31 PM', '+3.5 -105', '-3.5 -105')

>>> %timeit func1(list_date)
100 loops, best of 3: 3.07 ms per loop
>>> %timeit func2(list_date)
100 loops, best of 3: 1.59 ms per loop      #winner
>>> %timeit func3(list_date)
100 loops, best of 3: 1.91 ms per loop
>>> %timeit func4(list_date)
1000 loops, best of 3: 2.02 ms per loop

#increase the input size
>>> list_date = list_date *10**3
>>> len(list_date)
48000
>>> %timeit func1(list_date)
1 loops, best of 3: 3.6 s per loop
>>> %timeit func2(list_date)            #winner
1 loops, best of 3: 1.99 s per loop      
>>> %timeit func3(list_date)
1 loops, best of 3: 2.09 s per loop
>>> %timeit func4(list_date)
1 loops, best of 3: 2.02 s per loop


#increase the input size again

>>> list_date = list_date *10
>>> len(list_date)
480000
>>> %timeit func1(list_date)
1 loops, best of 3: 36.4 s per loop
>>> %timeit func2(list_date)                  #winner
1 loops, best of 3: 20.2 s per loop           
>>> %timeit func3(list_date)
1 loops, best of 3: 22.8 s per loop
>>> %timeit func4(list_date)
1 loops, best of 3: 22.7 s per loop

这篇关于获取最近的日期到给定的日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆