在Python条件下从两个列表中创建间隔

时间:2018-04-27 08:32:43

标签: python

如何在Python条件下从两个列表中创建间隔?

这个问题背后的逻辑有点奇怪:

  1. 开始列表中的数字可以在间隔中跳过。与2011年的示例1一样,因为2011年是[2010年,2012年]。

  2. 但是不能跳过结束列表中的数字,并引发错误。与示例2中的2019一样,因为最后一个区间是[2015年,2016],2019年大于2016年。

  3. 如果开始列表中的最后几个数字大于结束列表中的最后一个数字,则从开始到无穷大的最后几个数字的最小数量将有一个间隔。就像2017年,例子3中的2018年一样,所以会有一个间隔[2017,浮动(" inf")]。
  4. 示例1:

    start = [2010, 2011, 2015, 2017, 2018]
    end = [2012, 2016, 2019]
    

    预期结果1:

    [[2010, 2012], [2015, 2016], [2017, 2019]]
    

    示例2:

    start = [2010, 2011, 2015]
    end = [2012, 2016, 2019]
    

    预期结果2:

    错误,因为在创建间隔后,结尾列表中有更多数字。 (2019)

    示例3:

    start = [2010, 2011, 2015, 2017, 2018]
    end = [2012, 2016]
    

    预期结果3:

    [[2010, 2012], [2015, 2016], [2017, float("inf")]]
    

2 个答案:

答案 0 :(得分:0)

我不确定我是否理解你的逻辑100%正确但这至少解决了你的测试用例:

def make_intervals(start, end):
    if not start and not end:
        return []
    if not end:
        return [[start[0], math.inf]]
    if start[0] > end[0]:
        raise ValueError
    intervals = []
    current = start[0]
    i = 1
    j = 0
    while i < len(start) and j < len(end):
        if start[i] > end[j]:
            intervals.append([current, end[j]])
            current = start[i]
            j += 1
        i += 1
    if j < len(end) - 1:
        raise ValueError
    elif j == len(end) - 1:
        intervals.append([current, end[-1]])
    else:
        intervals.append([current, float("inf")])
    return intervals

start = [2010, 2011, 2015, 2017, 2018]
end = [2012, 2016, 2019]
assert make_intervals(start, end) == [[2010, 2012], [2015, 2016], [2017, 2019]]

start = [2010, 2011, 2015]
end = [2012, 2016, 2019]
try:
    make_intervals(start, end)
    assert False
except ValueError: pass

start = [2010, 2011, 2015, 2017, 2018]
end = [2012, 2016]
assert make_intervals(start, end) == [[2010, 2012], [2015, 2016], [2017, float("inf")]]

答案 1 :(得分:0)

我会使用iter ators。

def create_intervals(start, end):
    start_i = iter(start)
    end_i = iter(end)

    res = [list(map(next, (start_i, end_i)))]

    for i in start_i:
        if not i in range(*res[-1]):
            try:
                res.append([i, next(end_i)])
            except StopIteration:
                res.append([i, float('inf')])
                break

    if bool(next(end_i, False)) == True:
        raise AssertionError
    return res

测试:

start = [2010, 2011, 2015, 2017, 2018]
end = [2012, 2016, 2019]
print(create_intervals(start , end))  # -> [[2010, 2012], [2015, 2016], [2017, 2019]]

start = [2010, 2011, 2015, 2017, 2018]
end = [2012, 2016]
print(create_intervals(start , end))  # -> [[2010, 2012], [2015, 2016], [2017, inf]]

start = [2010, 2011, 2015]
end = [2012, 2016, 2019]
print(create_intervals(start , end))  # -> AssertionError