Search code examples
pythonlist

Find longest consecutive range of numbers in list


I have the following list of numbers:

numbers = numbers = [  1, 3, 11,  12,  14,  15,  16, 3, 4, 6]

I would like to get the start and end index of the longest consecutive range of numbers. By consecutive range, I mean an integer range of number without skipping, i.e. 1,2,3,4,5...

This is how I have done it:

def get_longest_consecutive_numbers(numbers):

    # 1. Split the numbers list into sublists of consecutive numbers
    split_list = []
    j = 0
    for i in range(1,len(numbers)-1):
        if numbers[i]+1 is not numbers[i+1]:
            split_list.append(numbers[j:i])
            j = i

    # 2. Find index of longest sublist (of consecutive numbers)
    longest_sublist_index = max((len(l), i) for i, l in enumerate(split_list))[1]

    # 3. Concatenate all sublists up to this index back together
    rest = split_list[:longest_sublist_index]
    concat_list = [j for i in rest for j in i]

    # 4. 
    # Start Index: Length of concatenated list
    # End Index: Start Index + Length of longest sublist in split_list

    start_index = len(concat_list)
    end_index = start_index + len(split_list[longest_sublist_index])

    return start_index, end_index

If I apply my function to the list of numbers:

 get_longest_consecutive_numbers(numbers)

I get:

(3, 6)

which is correct... but...

I was wondering if there is a more straight-forward (better) way to do this ?


Solution

  • Let's have a bit of fun :

    1. Create the range in which the list is included

    2. Symmetric difference of that with the list

    3. Compute the max distance between two following numbers (gives you the max length)

    4. Get the index of the start and end point

    Here is the code :

    def longest_weird(numbers):
        delta = list(set(range(max(numbers))).symmetric_difference(numbers))
        start,end = 0,0
        maxi = 0
        for i,x in enumerate(delta[:-1]):
            aux = max(maxi,delta[i+1]-x)
            if aux != maxi:
                start,end = (x+1,delta[i+1]-1)
                maxi = aux
        return numbers.index(start),numbers.index(end)