如何获取列表中最近的datetime对象?

2024-09-28 23:35:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个列表,matched_rows_2,看起来像这样:

matched_rows_2 = 
[['1','01-01-2021','10:18:00','100','TTF'],
 ['2','01-01-2021','10:18:00','100','GGY'],
 ['3','01-01-2021','10:22:00','120','HHJ'],
 ['4','01-01-2021','10:23:00','160','JJH'],
 ['5','01-01-2021','10:26:14','160','RRT'],
 ['6','01-01-2021','10:27:59','160','PPO'],
 ['7','01-01-2021','10:29:58','100','KKG'],
 ['8', '01-01-2021','10:30:50','160','PPO']]

现在,对于上面的x中的每一个list,我都试图得到x,它有一个datetime最接近chosen_datetime

这是我的代码:

chosen_datetime = 2021-01-01 10:16:00+00:00 #<--- this is a datetime aware time object.

timezone = "Europe/London"
chosen_datetime = pytz.utc.localize(chose_datetime).astimezone(pytz.timezone(timezone))
timeDiff = chosen_datetime.utcoffset().total_seconds()
chosen_datetime = pytz.utc.localize(chosen_datetime + datetime.timedelta(seconds=timeDiff)


matched_rows_3 = []
for x in matched_rows_2:
    start_traject_time = x[1] + ' ' + x[2]
    start_traject_time = datetime.datetime.strptime(start_traject_time, '%d-%m-%Y %H:%M:%S')
    start_traject_time = pytz.utc.localize(start_traject_time)
    if min(start_traject_time, key=lambda d: abs(d -  chosen_datetime)):
        matched_rows_3.append(x)

这是我当前的输出:

    if min(start_traject_time, key=lambda d: abs(d - chosen_datetime)):
TypeError: 'datetime.datetime' object is not iterable

这是我想要的输出:

1   01-01-2021  10:18:00    100 TTF 
2   01-01-2021  10:18:00    100 GGY 
3   01-01-2021  10:22:00    120 HHJ 
4   01-01-2021  10:23:00    160 JJH  

请注意,我的datetime对象都是datetime aware对象,我希望保持这样


Tags: datetimetimettfstartrowsutctimezonechosen
1条回答
网友
1楼 · 发布于 2024-09-28 23:35:13

min()的第一个参数必须是一个iterable,例如,一个包含所有要与chosen_datetime进行比较的datetime对象的列表。例:

from datetime import datetime, timezone

matched_rows_2 = [
        ['1','01-01-2021','10:18:00','100','TTF'],
        ['2','01-01-2021','10:18:00','100','GGY'],
        ['3','01-01-2021','10:22:00','120','HHJ'],
        ['4','01-01-2021','10:23:00','160','JJH'],
        ['5','01-01-2021','10:26:14','160','RRT'],
        ['6','01-01-2021','10:27:59','160','PPO'],
        ['7','01-01-2021','10:29:58','100','KKG'],
        ['8','01-01-2021','10:30:50','160','PPO']
        ]

# first extract date & time and parse to datetime object. optionally set tzinfo to UTC
dts = []
for row in matched_rows_2:
    dts.append(datetime.strptime(row[1]+row[2], "%d-%m-%Y%H:%M:%S").replace(tzinfo=timezone.utc))
 
# dts 
# [datetime.datetime(2021, 1, 1, 10, 18, tzinfo=datetime.timezone.utc),
#  datetime.datetime(2021, 1, 1, 10, 18, tzinfo=datetime.timezone.utc),
#  datetime.datetime(2021, 1, 1, 10, 22, tzinfo=datetime.timezone.utc),
#  datetime.datetime(2021, 1, 1, 10, 23, tzinfo=datetime.timezone.utc),
#  datetime.datetime(2021, 1, 1, 10, 26, 14, tzinfo=datetime.timezone.utc),
#  datetime.datetime(2021, 1, 1, 10, 27, 59, tzinfo=datetime.timezone.utc),
#  datetime.datetime(2021, 1, 1, 10, 29, 58, tzinfo=datetime.timezone.utc),
#  datetime.datetime(2021, 1, 1, 10, 30, 50, tzinfo=datetime.timezone.utc)]

现在列表中有了所有datetime对象,可以使用min获得与所选日期相差最小的值:

chosen_datetime = datetime.fromisoformat("2021-01-01 10:23:00+00:00")

# now to get the element in l + the index
min_val = min(dts, key=lambda d: abs(d - chosen_datetime))
min_idx = dts.index(min_val)

# or in one line (more efficient but less readable)
min_idx, min_val = min(zip(range(len(dts)), dts), key=lambda d: abs(d[1] - chosen_datetime))

print(min_val, min_idx, matched_rows_2[min_idx])
# 2021-01-01 10:23:00+00:00 3 ['4', '01-01-2021', '10:23:00', '160', 'JJH']

print(matched_rows_2[:min_idx+1])
# [['1', '01-01-2021', '10:18:00', '100', 'TTF'], 
#  ['2', '01-01-2021', '10:18:00', '100', 'GGY'], 
#  ['3', '01-01-2021', '10:22:00', '120', 'HHJ'], 
#  ['4', '01-01-2021', '10:23:00', '160', 'JJH']]

相关问题 更多 >