【问题标题】:Python - Algorithm find time slotsPython - 算法查找时隙
【发布时间】:2012-05-22 12:40:08
【问题描述】:

假设我今天从 09:00 工作到 18:00,我有 3 个约会:

  • 10:00 - 10:30
  • 12:00 - 13:00
  • 15:30 - 17:10

我需要找到一天中 1 小时的可用时间段列表。
这是我应该得到的清单

  • 09:00 - 10:00
  • 10:30 - 11:30
  • 13:00 - 14:00
  • 14:00 - 15:00

我已经在 php 中实现了它,我只是尝试将它放在 python 中。
这是我的尝试:

def get_slots(areas, duration):
    slots = []
    for area in areas:
        if area['start'] == area['end']:
            continue
        i = area['start']
        while (i + duration) <= area['end']:
            i += duration
            slots.append({
                'start': (i - duration),
                'end': i,
            })
    return slots

def get_areas(day_start, day_end, appts):
    areas = []
    old_end = day_start
    for appt in appts:
        if appt['start'] > old_end:
            areas.append({
                'start': old_end,
                'end': appt['start'],
            })
        old_end = appt['end']
        if old_end > day_end:
            return areas
    areas.append({
        'start': old_end,
        'end': day_end,
    })
    return areas

测试:

>>> day_start = datetime.datetime(2012, 5, 22, 9)
>>> day_end = datetime.datetime(2012, 5, 22, 18)
>>> appts = [{
    'start': datetime.datetime(2012, 5, 22, 10),
    'end': datetime.datetime(2012, 5, 22, 10, 30),
  },{
    'start': datetime.datetime(2012, 5, 22, 12),
    'end': datetime.datetime(2012, 5, 22, 13),
  },{
    'start': datetime.datetime(2012, 5, 22, 15, 30),
    'end': datetime.datetime(2012, 5, 22, 17, 10),
  },]
>>> duration = datetime.timedelta(hours=1)
>>> pprint.pprint(get_slots(get_areas(day_start, day_end, appts), duration))

它可以工作,但我只是从 php 移植代码。
所以我不确定这是一种pythonist方式。

你能告诉我哪里可以改进吗?

【问题讨论】:

  • 应该考虑11:00-12:00的时间段吗?
  • 不应该只从每个“区域”开始获取顺序时间块

标签: python algorithm datetime


【解决方案1】:
#time_slots.py
from datetime import datetime, timedelta

appointments = [(datetime(2012, 5, 22, 10), datetime(2012, 5, 22, 10, 30)),
                (datetime(2012, 5, 22, 12), datetime(2012, 5, 22, 13)),
                (datetime(2012, 5, 22, 15, 30), datetime(2012, 5, 22, 17, 10))]

hours = (datetime(2012, 5, 22, 9), datetime(2012, 5, 22, 18))

def get_slots(hours, appointments, duration=timedelta(hours=1)):
    slots = sorted([(hours[0], hours[0])] + appointments + [(hours[1], hours[1])])
    for start, end in ((slots[i][1], slots[i+1][0]) for i in range(len(slots)-1)):
        assert start <= end, "Cannot attend all appointments"
        while start + duration <= end:
            print "{:%H:%M} - {:%H:%M}".format(start, start + duration)
            start += duration

if __name__ == "__main__":
    get_slots(hours, appointments)


% python time_slots.py 
09:00 - 10:00
10:30 - 11:30
13:00 - 14:00
14:00 - 15:00

【讨论】:

  • 这确实更pythonic :) 我会尝试使用它
  • 工作正常。但也许get_slots 也应该安排约会以防止错误
  • @PierredeLESPINAY 只是为了好玩,我对插槽进行了一些更改+尝试检查是否可以参加所有约会。排序是个好主意。
猜你喜欢
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多