Python比较日期范围列表

时间:2015-02-12 08:45:32

标签: python list loops date

我有一个日期列表:

dates = [
    {'start': 2015-02-12 08:30, 'end': 2015-02-12 13:30, 'name': 'a'},
    {'start': 2015-02-12 09:00, 'end': 2015-02-12 11:45, 'name': 'b'},
    {'start': 2015-02-12 09:30, 'end': 2015-02-12 10:30, 'name': 'c'},
    {'start': 2015-02-12 10:30, 'end': 2015-02-12 17:30, 'name': 'd'},
    {'start': 2015-02-12 11:00, 'end': 2015-02-12 20:30, 'name': 'e'},
    {'start': 2015-02-12 12:30, 'end': 2015-02-12 18:30, 'name': 'f'},
]

我需要得到输出(将这些日期合并到间隔),如下所示:

output = [
    {'start': 2015-02-12 08:30, 'end': 2015-02-12 09:00, 'name': 'a'},
    {'start': 2015-02-12 09:00, 'end': 2015-02-12 09:30, 'name': 'a + b'},
    {'start': 2015-02-12 09:30, 'end': 2015-02-12 10:30, 'name': 'a + b + c'},
    {'start': 2015-02-12 10:30, 'end': 2015-02-12 11:00, 'name': 'a + b + d'},
    {'start': 2015-02-12 11:00, 'end': 2015-02-12 11:45, 'name': 'a + b + d + e'},
    {'start': 2015-02-12 11:45, 'end': 2015-02-12 12:30, 'name': 'a + d + e'},
    {'start': 2015-02-12 12:30, 'end': 2015-02-12 13:30, 'name': 'a + d + e + f'},
    {'start': 2015-02-12 13:30, 'end': 2015-02-12 17:30, 'name': 'd + e + f '},
    {'start': 2015-02-12 17:30, 'end': 2015-02-12 18:30, 'name': 'e + f'},
    {'start': 2015-02-12 18:30, 'end': 2015-02-12 20:30, 'name': 'f'},
]

每个输出startend日期必须按顺序排列,如果一个项目startend日期相互交叉,则应将它们合并。

我试图在循环中使用循环

for x, left in enumerate(dates):
    for y, right in enumerate(dates):
        # HERE GOES THE LOGIC..
        # Tried to compare each X and Y item with each other
        # But don't know how to keep used items "in mind"
        # And then create new list to output
        continue

但是没有找到解决这个问题的解决方案。 我正在等待帮助答案,谢谢。

2 个答案:

答案 0 :(得分:1)

# To keep the example simple, I'm using floats instead of times.
dates = [
    {'start':  8.30, 'end': 13.30, 'name': 'a'},
    {'start':  9.00, 'end': 11.45, 'name': 'b'},
    {'start':  9.30, 'end': 10.30, 'name': 'c'},
    {'start': 10.30, 'end': 17.30, 'name': 'd'},
    {'start': 11.00, 'end': 20.30, 'name': 'e'},
    {'start': 12.30, 'end': 18.30, 'name': 'f'},
                                                  # A gap.
    {'start': 22.00, 'end': 22.30, 'name': 'g'},
]

# Get list of all times, with a boolean to mark their type.
times = []
for d in dates:
    times.append((d['start'], False, d['name']))
    times.append((d['end'],   True,  d['name']))

# Process them in sorted order.
active = set()
for t, is_end, name in sorted(times):
    if active and t != prev:
        print (prev, t), '+'.join(active)
    prev = t
    if is_end: active.remove(name)
    else:      active.add(name)

输出:

(8.3, 9.0) a
(9.0, 9.3) a+b
(9.3, 10.3) a+c+b
(10.3, 11.0) a+b+d
(11.0, 11.45) a+b+e+d
(11.45, 12.3) a+e+d
(12.3, 13.3) a+e+d+f
(13.3, 17.3) e+d+f
(17.3, 18.3) e+f
(18.3, 20.3) e
(22.0, 22.3) g

答案 1 :(得分:1)

试试这样:

date_ranges = [
    {'start': '2015-02-12 08:30', 'end': '2015-02-12 13:30', 'name': 'a'},
    # Omitting...
    {'start': '2015-02-12 12:30', 'end': '2015-02-12 18:30', 'name': 'f'},
]

edges = set()
for date_range in date_ranges:
    edges.add(date_range['start'])
    edges.add(date_range['end'])
edges = sorted(list(edges))

intervals = []
for i, edge in enumerate(edges):
    if i == 0:
        continue
    previous_edge = edges[i - 1]
    current_edge = edge
    overlaps = [date_range['name']
                for date_range in date_ranges
                if date_range['start'] <= previous_edge and
                   current_edge <= date_range['end']]
    if overlaps:
        interval = {
            'name': ' + '.join(sorted(overlaps)),
            'start': previous_edge,
            'end': current_edge
        }
        intervals.append(interval)

for interval in intervals:
    print interval

输出:

{'start': '2015-02-12 08:30', 'end': '2015-02-12 09:00', 'name': 'a'}
{'start': '2015-02-12 09:00', 'end': '2015-02-12 09:30', 'name': 'a + b'}
{'start': '2015-02-12 09:30', 'end': '2015-02-12 10:30', 'name': 'a + b + c'}
{'start': '2015-02-12 10:30', 'end': '2015-02-12 11:00', 'name': 'a + b + d'}
{'start': '2015-02-12 11:00', 'end': '2015-02-12 11:45', 'name': 'a + b + d + e'}
{'start': '2015-02-12 11:45', 'end': '2015-02-12 12:30', 'name': 'a + d + e'}
{'start': '2015-02-12 12:30', 'end': '2015-02-12 13:30', 'name': 'a + d + e + f'}
{'start': '2015-02-12 13:30', 'end': '2015-02-12 17:30', 'name': 'd + e + f'}
{'start': '2015-02-12 17:30', 'end': '2015-02-12 18:30', 'name': 'e + f'}
{'start': '2015-02-12 18:30', 'end': '2015-02-12 20:30', 'name': 'e'}