0

I have a Python list with hours. e.g. [7,8,9,10,17,23,1,2,3] The hours are in 24 hour format ranging from 0 to 23 (0 = midnight, 23 = 11pm).

I like to determine the start and end hour of consecutive hour blocks. So my desired end result should look be a list, with dictionaries containing the block start and end hours.

Especially determining the block start with a block that passes midnight (from 23 to 0) makes it difficult.

Desired result:

hour_blocks = (
            {
                "block_nr": 1,
                "block_start": 7,
                "block_end": 10
            },
            {
                "block_nr": 2,
                "block_start": 17,
                "block_end": 17
            },
            {
                "block_nr": 3,
                "block_start": 23,
                "block_end": 3
            }
        )

I started with a very rough version, but I got stuck (see below). I also couldnt think of any Python libraries that would make this easier (like the datetime or calendar libraries).

    i = 0
    busy_blocks = []
    hour_list = [7,8,9,10,17,23,1,2,3]

    start = False
    next_hour_connected = False

    for hour in hour_list:

        if hour == hour_list[i + 1] -1 and not start:
            # Next hour is connected and no start is defined
            busy_block_start = hour
            start = True
            continue

        if hour == hour_list[i + 1] - 1:
            # Next hour is still connected


            #if the subsequent hour is not connected, we define the block end
            if (hour != hour_list[i + 2] - 2) or next_hour_connected:
                busy_block_end = hour

                # Save block
                busy_blocks.append({
                    "busy_block_start": busy_block_start,
                    "busy_block_end": busy_block_end
                })

                # Reset block
                start = False
                next_hour_connected = False
            else:
                # Remember that next 
                next_hour_connected = True
Richard
  • 3
  • 3
  • Does this answer your question? [Identify groups of continuous numbers in a list](https://stackoverflow.com/questions/2154249/identify-groups-of-continuous-numbers-in-a-list) – Błotosmętek Mar 10 '20 at 10:37

1 Answers1

0

Ok, so I'm not sure if the example you provided is right. Because you said that the time is ranging from 0 to 23, so "23, 1" is not consecutive, unless it is "23, 0".

Anyways, I tried implementing a simple algorithm, which uses a list to temporarily store the consecutive hours. The code is pretty long and definitely not fully optimized, but hopefully you can get an idea of what I'm trying to do here.

hour_blocks = []
hour_list = [7,8,9,10,17,23,1,2,3]

hour_block= []

for i in range(len(hour_list)-1):
    hour = hour_list[i]
    nextHour = hour_list[i+1]
    #get current hour and next hour

    if (not hour_block): #if hour_block is empty, append the time
        hour_block.append(hour)

    if (hour==nextHour-1 or (hour==23 and nextHour==0)): #if hours were consecutive, append to hour_block
        hour_block.append(nextHour)
    else: #if not, add the first and the last element of the hour_block as the beginning time and end time
        hour_blocks.append({"begin":hour_block[0], "end":hour_block[-1]})
        hour_block = [] #clear the hour_block

    if i == len(hour_list)-2 and hour_block: #append hour_block to hour_blocks when loop is finished
        hour_blocks.append({"begin":hour_block[0], "end":hour_block[-1]})
        hour_block = []

print(hour_blocks) 
#prints [{'begin': 7, 'end': 10}, {'begin': 17, 'end': 17}, {'begin': 23, 'end': 23}, {'begin': 1, 'end': 3}]

Błotosmętek's answer also seem to work, so you might want to use that as well (although you will need to implement the cyclic system on your own)

Hope this helped, cheers :)

Kenta Nomoto
  • 839
  • 6
  • 11
  • 1
    Hero! Thanks, this works perfectly. Yes you are right, my list example was incorrect, but your code works good, including cycling through midnight. – Richard Mar 11 '20 at 02:14