1

How can i split it into sequences/runs/subsequent-numbers, if the run is no longer than 3?

Having an array as follows

[1, 2, 3, 5, 9, 10, 16, 17, 18, 19]

My expected output would be the following arrays:

  1. [1, 2, 3]
  2. [5]
  3. [9, 10]
  4. [16, 17, 18]
  5. [19]

e.g. [[1, 2, 3], [5], [9, 10], [16, 17, 18], [19]]

If it is a run of length 8 e.g. [1, 2, 3, 4, 5, 6, 7, 8] i would like to get 8 / 3 + 1 = 2 lists:

  1. [1, 2, 3]
  2. [4, 5, 6]
  3. [7, 8]

3 Answers 3

2

If you name your current list, x and the new list of output, new_list, you can try (untested and assumes no repeat values in original list)

k = 0
new_list = [[]]
for i in range(len(x) - 1):
    if x[i] not in new_list[max(k - 1, 0)]:
        new_list[k].append(x[i])
        for j in range(i + 1, len(x)):    
            if x[j] - x[i] == j - i and x[j] not in new_list[k]:
               new_list[k].append(x[j])
        k += 1
        new_list.append([])

new_list = [x for x in new_list if x != []] # gets rid of empty list at the end
Sign up to request clarification or add additional context in comments.

1 Comment

IMHO i think on line 3 it it should be range(len(x)) instead of range(len(x) - 1)... Look for example for: x = [1, 2, 3, 5, 9, 10, 16, 17, 18, 19, 21]
1

Here's my version that uses numpy:

import numpy as np
from itertools import chain
def split_list(mylist):
    """Function to do the initial split"""
    # calculate differences
    d = np.diff(mylist)
    # when the differences are not 1 save that location
    # we need a +1 to get make up for the lost element
    breaks = list(np.arange(len(mylist) - 1)[d != 1] + 1)
    slices = zip([0] + breaks, breaks + [len(mylist)])
    # slice up the list
    int_list = [mylist[a:b] for a, b in slices]
    # chop up long sequences
    chopped = [chop(l) for l in int_list]
    # flatten the list once
    return list(chain.from_iterable(chopped))

def chop(sublist, max_len=3):
    """Chops a list into chunks of length max_len"""
    breaks = list(range(0, len(sublist), max_len))
    slices = zip(breaks, breaks[1:] + [len(sublist)])
    return [sublist[a:b] for a, b in slices]

Running this on the list's given:

>>> split_list([1, 2, 3, 5, 9, 10, 16, 17, 18, 19])
[[1, 2, 3], [5], [9, 10], [16, 17, 18], [19]]

Comments

-1

Something like this?

def split_list(list, sub_list_size = 3):
    sublists = []

    for i in range(0, len(list), sub_list_size):
        start = i
        end = i + sub_list_size
        sublists.append(list[start:end])

    return sublists


# your list
mylist = [1,2,3,4,5,6,7,8, 9, 10, 11]

# your output
sublists = split_list(mylist)

print(sublists)

produces the following output

[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11]]

The syntax list[start:end] will work even if end it is larger than the actual list size.

Hope this helps

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.