赞
踩
bisect实质上是python自带的数组二分查找算法:bisect — 数组二分查找算法【官方文档】
因为本质是二分,所以需满足数组是【有序的】
以下是二分的内置算法:
def index(a, x): 'Locate the leftmost value exactly equal to x' i = bisect_left(a, x) if i != len(a) and a[i] == x: return i raise ValueError def find_lt(a, x): 'Find rightmost value less than x' i = bisect_left(a, x) if i: return a[i-1] raise ValueError def find_le(a, x): 'Find rightmost value less than or equal to x' i = bisect_right(a, x) if i: return a[i-1] raise ValueError def find_gt(a, x): 'Find leftmost value greater than x' i = bisect_right(a, x) if i != len(a): return a[i] raise ValueError def find_ge(a, x): 'Find leftmost item greater than or equal to x' i = bisect_left(a, x) if i != len(a): return a[i] raise ValueError
官方给出的案例:
bisect() 函数对于数字表查询也是适用的。 这个例子使用 bisect() 根据一组有序的数字划分点来查找考试成绩对应的字母等级: (如) 90 及以上为 ‘A’,80 至 89 为 ‘B’,依此类推:
>>>def grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'):
i = bisect(breakpoints, score)
return grades[i]
>>>[grade(score) for score in [33, 99, 77, 70, 89, 90, 100]]
['F', 'A', 'C', 'C', 'B', 'A', 'A']
问题描述:
每天白班是6:45-18:45夜班是18:45-次日6:45
给出当前时间班次和上一班次的开始时间和结束时间
不采用bisect,使用if和else需要考虑0点到6点的情况,单独增加判断,代码if-else分支较多,代码逻辑比较冗余:
def get_shift_times(turn: int) -> TurnTimeVo: current_time = datetime.now() today = current_time.date() yesterday = today - timedelta(days=1) tomorrow = today + timedelta(days=1) # 一天开始的时间 today_start_time = datetime.strptime(Constants.TODAY_START_TIME, "%H:%M:%S").time() # 白班开始时间 day_start = datetime.strptime(Constants.WORK_SHIFT_START_TIME, "%H:%M:%S").time() # 白班结束时间 day_end = datetime.strptime(Constants.WORK_SHIFT_END_TIME, "%H:%M:%S").time() # 时间段分割 today_start = datetime.combine(today, today_start_time) today_day_start = datetime.combine(today, day_start) today_day_end = datetime.combine(today, day_end) yesterday_day_start = datetime.combine(yesterday, day_start) yesterday_day_end = datetime.combine(yesterday, day_end) tomorrow_day_start = datetime.combine(tomorrow, day_start) if turn == TurnShift.now_turn: # 当前班次 if current_time >= today_start and current_time <= today_day_start: shift_start = yesterday_day_end shift_end = today_day_start elif current_time > today_day_start or current_time <= today_day_end: shift_start = today_day_start shift_end = today_day_end else: shift_start = today_day_end shift_end = tomorrow_day_start elif turn == TurnShift.last_turn: # 上一班次 if current_time >= today_start and current_time <= today_day_start: shift_start = yesterday_day_start shift_end = yesterday_day_end elif current_time > today_day_start or current_time <= today_day_end: shift_start = yesterday_day_end shift_end = today_day_start else: shift_start = today_day_start shift_end = today_day_end else: raise ValueError("Invalid turn value. Please provide 1 or 2.") vo = TurnTimeVo(start_time=shift_start, end_time=shift_end) return vo
采用bisect之后逻辑更为清晰:
def get_shift_times(turn: int) -> TurnTimeVo: current_time = datetime.now() today = current_time.date() yesterday = today - timedelta(days=1) tomorrow = today + timedelta(days=1) # 白班开始时间 day_start = datetime.strptime(Constants.WORK_SHIFT_START_TIME, "%H:%M:%S").time() # 白班结束时间 day_end = datetime.strptime(Constants.WORK_SHIFT_END_TIME, "%H:%M:%S").time() # 时间段分割 today_day_start = datetime.combine(today, day_start) today_day_end = datetime.combine(today, day_end) yesterday_day_start = datetime.combine(yesterday, day_start) yesterday_day_end = datetime.combine(yesterday, day_end) tomorrow_day_start = datetime.combine(tomorrow, day_start) brakpoints = [ yesterday_day_start, yesterday_day_end, today_day_start, today_day_end, tomorrow_day_start, ] current_interval_index = bisect.bisect(brakpoints, current_time) if turn == TurnShift.now_turn: # 当前班次 shift_start = brakpoints[current_interval_index - 1] shift_end = brakpoints[current_interval_index] elif turn == TurnShift.last_turn: # 上一班次 shift_start = brakpoints[current_interval_index - 2] shift_end = brakpoints[current_interval_index - 1] else: raise ValueError("Invalid turn value. Please provide 1 or 2.") vo = TurnTimeVo(start_time=shift_start, end_time=shift_end) return vo
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。