我有一个问题。假设我收到了一个元组列表,其中有一个开始时间和一个结束时间(在视频中观看了几分钟)。 (例如[(0,10),(17,25)])按开始时间排序。给出了视频的总长度(例如30),并要求我找到未观看分钟的不间断时间的最大总分钟。因此,在这种情况下,答案将是7分钟。 (从10到17)。
这是我的解决方法:
#example data
video = [(5,10),(13,18),(15,23),(21,23)]
total_minutes_video = 30
#first row calculate free_minutes from start
free_minutes= video [0][0]
lastend = video [0][1]
for beg,end in video :
if beg>lastend:
free_minutes = max(beg-lastend,free_minutes)
lastend = max(lastend,end)
#last row, have to check how many minutes until end of video
free_minutes= max(free_minutes,total_minutes_video-video[len(video)-1][1])
print(free_minutes)
显然这不是最漂亮的,我觉得我可以做得更好。有什么想法可以避免在顶部和底部进行逻辑运算吗?
答案 0 :(得分:1)
将您的列表转换为未监视间隔的列表:
v = [(0, 0)] + video + [(total_minutes_video, total_minutes_video)]
unwatched = [(a[1], b[0]) for a, b in zip(v[:-1], v[1:])]
然后找到最长的:
worst = max(unwatched, key=lambda x: x[1] - x[0])
如果您担心内存,可以完全使用生成器来做到这一点:
import itertools
v = itertools.chain([(0, 0)], video, [(total_minutes_video, total_minutes_video)])
unwatched = ((a[1], b[0]) for a, b in zip(v[:-1], v[1:]))
worst = max(unwatched, key=lambda x: x[1] - x[0])
答案 1 :(得分:0)
如果您的目标是跳过逻辑,则可以枚举并将范围缩短1,然后采用当前项目的1位置和下一项的0位置之差,我们当然会必须使用*-1
取相反的值并将这些值附加到列表中,我尝试仅反向执行列表以跳过该列表,但我做不到。然后,我们可以抓住最后一个值1位置与总时间之间的差,然后追加。并只取该列表的最大值。
free = [(item[1] - v[idx+1][0])*-1 for idx, item in enumerate(v[:-1])]
free.append(total - v[-1][1])
print(max(free))
7
如果它必须是一行,尽管违反了PEP-8最大行数
free = max([(item[1] - v[idx+1][0])*-1 for idx, item in enumerate(v[:-1])] + [total -v[-1][1]])