【问题标题】:Extracting slots from list of lists in python从python中的列表列表中提取插槽
【发布时间】:2018-09-16 12:27:27
【问题描述】:

我有以下格式的列表列表,需要传递给 api。

[
    [0, 4, 0, 4, 59], [0, 5, 0, 5, 59], [0, 6, 0, 6, 59], [0, 13, 0, 13, 59],
    [0, 14, 0, 14, 59], [0, 21, 0, 21, 59], [0, 22, 0, 22, 59], 
    [1, 5, 0, 5, 59], [1, 6, 0, 6, 59], [1, 13, 0, 13, 59], [1, 14, 0, 14, 59],
    [1, 21, 0, 21, 59], [1, 22, 0, 22, 59], [2, 5, 0, 5, 59], [2, 6, 0, 6, 59], 
    [2, 13, 0, 13, 59], [2, 14, 0, 14, 59], [2, 21, 0, 21, 59], 
    [2, 22, 0, 22, 59], [3, 5, 0, 5, 59], [3, 6, 0, 6, 59], [3, 13, 0, 13, 59],
    [3, 14, 0, 14, 59], [3, 21, 0, 21, 59], [3, 22, 0, 22, 59], 
    [4, 5, 0, 5, 59], [4, 6, 0, 6, 59], [4, 13, 0, 13, 59], [4, 14, 0, 14, 59],
    [4, 21, 0, 21, 59], [4, 22, 0, 22, 59], [5, 5, 0, 5, 59], [5, 6, 0, 6, 59],
    [5, 13, 0, 13, 59], [5, 14, 0, 14, 59], [5, 21, 0, 21, 59], 
    [5, 22, 0, 22, 59], [6, 5, 0, 5, 59], [6, 6, 0, 6, 59], [6, 13, 0, 13, 59],
    [6, 14, 0, 14, 59], [6, 21, 0, 21, 59], [6, 22, 0, 22, 59] 
]

在每个列表中,第一个元素代表天,后面的元素代表从小时和分钟到小时和分钟。从上面的示例中,对于第 0 天,slot1 是 04:00 到 6:59,slot 2 是 13:00 到 14:59,slot3 是 21:00 至 22:59。

我正在尝试将列表简化如下。

[0, 04:00, 6:59, 13:00, 14:59, 21:00, 22:59]....

基本上将每天的时间段提取并组合到一个列表中,因此最终输出从第 0 天到第 6 天只有 7 个列表。

另外请注意,上述格式可能会发生变化,对于任何一天,可能只有 1 个插槽或可能没有插槽,因此插槽可能每天在 0-3 之间变化。

到目前为止,我设法加入以下时间和分钟 `

 start = float(str(from_hr) + str('.')+ str(from_min))
 end =   float(str(to_hr) + str('.')+ str(to_min))`

【问题讨论】:

  • 在我看来,您的输入是一个小时内正在使用的分钟的列表,而您的插槽概念是将连续的分钟连接成一个单元。所以你应该用不同的连续小时数来测试你的转换函数。不确定您当前的 float 和 str 代码正在尝试做什么。

标签: python list sorting iteration


【解决方案1】:

我还假设您希望: (a) 合并连续的任命(即前一个结束后立即开始的一个) (b) 以上述方式格式化这些 (c) 将这些按天分组到扁平列表中。

如果是这样,您可以使用以下方法解决此问题:

(a) 制作一个辅助函数,将您的日、小时和分钟变量转换为分钟:

def get_minute_val(day_val,hour_val,min_val):
    return (24*60*day_val)+(60*hour_val)+min_val

(b) 创建一个函数,接受两个约会,如果它们是连续的,则将它们组合为一个,如果它们不是连续的,则将它们不组合地返回

def combine_if_consec(first,second):
    #Check whether appointments are consecutive
    if( get_minute_val(first[0],first[3],first[4]) + 1 == 
        get_minute_val(second[0],second[1],second[2])):
        #If so, return list containing combined appointment
        return [[first[0],first[1],first[2],second[3],second[4]]]
    else:
        #Else return uncombined appointments
        return [first,second]

(c) 在列表中的每个约会上迭代地调用它,与最近添加的约会进行比较。对于第一次约会,我有一个稍微老套的方法。

def combine_all_appointments(app_list):
    #Add first appointment to app list
    output_list = [test[0]]

    #Loop through remaining appointments
    for next_app in app_list[1:]:
        #Remove most recent appointment to output list
        prev_app = output_list.pop()

        #Add either 2 combined appointments, or one single appointment to outputlist
        output_list += combine_if_overlap(prev_app,next_app)

    return output_list

(d) 创建一个函数来执行你想要的格式

def format_appointments(app_list):
    return [[x[0],'%d:%02d' % (x[1],x[2]),'%d:%02d' %(x[3],x[4])] for x in app_list]

(e) 和一个单独的按天分组约会,并按天平展。

def group_by_day(app_list):
    output = {}
    #Loop through appointments
    for app in app_list:
        #Create new entry if day not yet in output dict
        if app[0] not in output:
            output[app[0]] = app[1:]
        #Add appointment values to relevant day
        else:
            output[app[0]] += app[1:]
    #Flatten dictionary
    return [[k, *output[k]] for k in output]

在您的输入上进行测试:

test = [[0, 4, 0, 4, 59],[0, 5, 0, 5, 59], [0, 6, 0, 6, 59], [0, 13, 0, 13, 59], [0, 14, 0, 14, 59], [0, 21, 0, 21, 59], [0, 22, 0, 22, 59], [1, 5, 0, 5, 59], [1, 6, 0, 6, 59], [1, 13, 0, 13, 59], [1, 14, 0, 14, 59], [1, 21, 0, 21, 59], [1, 22, 0, 22, 59], [2, 5, 0, 5, 59], [2, 6, 0, 6, 59], [2, 13, 0, 13, 59], [2, 14, 0, 14, 59], [2, 21, 0, 21, 59], [2, 22, 0, 22, 59], [3, 5, 0, 5, 59], [3, 6, 0, 6, 59], [3, 13, 0, 13, 59], [3, 14, 0, 14, 59], [3, 21, 0, 21, 59], [3, 22, 0, 22, 59], [4, 5, 0, 5, 59], [4, 6, 0, 6, 59], [4, 13, 0, 13, 59], [4, 14, 0, 14, 59], [4, 21, 0, 21, 59], [4, 22, 0, 22, 59], [5, 5, 0, 5, 59], [5, 6, 0, 6, 59], [5, 13, 0, 13, 59], [5, 14, 0, 14, 59], [5, 21, 0, 21, 59], [5, 22, 0, 22, 59], [6, 5, 0, 5, 59], [6, 6, 0, 6, 59], [6, 13, 0, 13, 59], [6, 14, 0, 14, 59], [6, 21, 0, 21, 59], [6, 22, 0, 22, 59]]

app_list = combine_all_appointments(test)
formatted = format_appointments(app_list)
grouped = group_by_day(formatted)

返回

[[0, '4:00', '6:59', '13:00', '14:59', '21:00', '22:59'], [1, '5:00', '6:59', '13:00', '14:59', '21:00', '22:59'], [2, '5:00', '6:59', '13:00', '14:59', '21:00', '22:59'], [3, '5:00', '6:59', '13:00', '14:59', '21:00', '22:59'], [4, '5:00', '6:59', '13:00', '14:59', '21:00', '22:59'], [5, '5:00', '6:59', '13:00', '14:59', '21:00', '22:59'], [6, '5:00', '6:59', '13:00', '14:59', '21:00', '22:59']]

【讨论】:

  • 是的,我的示例中有错字,我已修复。你的第二个假设是正确的,我想结合连续的。但我在某一天的最终清单应该是 [0, 4.00, 6:59, 13:00, 14:59, 21:00, 22:59]
  • 好的,我的答案是你想要的吗?
  • ['0', '4:00', '4:59', '5:00', '5:59', '6:00', '6:59', ' 13:00'、'13:59'、'14:00'、'14:59'、'21:00'、'21:59'、'22:00'、'22:59']。我已经到了这一点,但仍然出现了一些连续的值。
  • 好的,我在上面的示例中看不到任何连续的约会。哪一个是问题?
  • 是否可以将每一天分成一个列表,输出将只包含 0-6 7 每天和约会的列表。
【解决方案2】:

你可以这样做:

input = [[0, 4, 0, 5, 59],[0, 5, 0, 5, 59], [0, 6, 0, 6, 59], [0, 13, 0, 13, 59], [0, 14, 0, 14, 59], [0, 21, 0, 21, 59], [0, 22, 0, 22, 59], [1, 5, 0, 5, 59], [1, 6, 0, 6, 59], [1, 13, 0, 13, 59], [1, 14, 0, 14, 59], [1, 21, 0, 21, 59], [1, 22, 0, 22, 59], [2, 5, 0, 5, 59], [2, 6, 0, 6, 59], [2, 13, 0, 13, 59], [2, 14, 0, 14, 59], [2, 21, 0, 21, 59], [2, 22, 0, 22, 59], [3, 5, 0, 5, 59], [3, 6, 0, 6, 59], [3, 13, 0, 13, 59], [3, 14, 0, 14, 59], [3, 21, 0, 21, 59], [3, 22, 0, 22, 59], [4, 5, 0, 5, 59], [4, 6, 0, 6, 59], [4, 13, 0, 13, 59], [4, 14, 0, 14, 59], [4, 21, 0, 21, 59], [4, 22, 0, 22, 59], [5, 5, 0, 5, 59], [5, 6, 0, 6, 59], [5, 13, 0, 13, 59], [5, 14, 0, 14, 59], [5, 21, 0, 21, 59], [5, 22, 0, 22, 59], [6, 5, 0, 5, 59], [6, 6, 0, 6, 59], [6, 13, 0, 13, 59], [6, 14, 0, 14, 59], [6, 21, 0, 21, 59], [6, 22, 0, 22, 59]]

output = {}
for row in input:
    key = row[0]
    output.setdefault(key, [str(key)])
    output[key].append('%d:%02d' % (row[1], row[2]))
    output[key].append('%d:%02d' % (row[3], row[4]))

result = output.values()

【讨论】:

  • 这解决了 75% 的问题,我得到的每个列表都像 ['0', '4:00', '5:59', '5:00', '5:59', ' 6:00'、'6:59'、'13:00'、'13:59'、'14:00'、'14:59'、'21:00'、'21:59'、'22: 00', '22:59'],但我希望它像 ['0','4:00,'5:59','13:00','14:59','21:00 ','22:59']
  • 请说明您在列表中包含或排除时间段的标准是什么?从您的示例中不清楚需要包含哪些时隙。
  • ['1', '5:00', '5:59', '6:00', '6:59', '13:00', '13:59', ' 14:00'、'14:59'、'21:00'、'21:59'、'22:00'、'22:59']。在这个例子中,我在 6:59 和 13:00 之间有一个间隔。因此,我的第一个时段将在 5 点开始,在 6:69 结束。第二个将从 13 点开始,到 14:59 结束,因为在 14:59 和 21:00 之间有休息时间。基本上,如果有顺序中断。
猜你喜欢
  • 2020-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-10
  • 1970-01-01
  • 2011-02-13
  • 2018-03-23
相关资源
最近更新 更多