4

I have an ordered Python list of forms:

[1, 2, 3, 4, 5, 12, 13, 14, 15, 20, 21, 22, 23, 30, 35, 36, 37, 38, 39, 40]

How can I group together consecutive numbers in a list. A group like this:

[[1, 2, 3, 4, 5], [12, 13, 14, 15], [20, 21, 22, 23,], [30], [35, 36, 37, 38, 39, 40]]

I tried using groupby from here but was not able to tailor it to my need. Thanks,

  • 2
    What have you tried so far? – Olav Aga Dec 15 '21 at 11:42
  • I tried using groupby from [here](https://stackoverflow.com/questions/27306594/python-splitting-a-datetime-list-based-on-missing-days) – Muhammad Anas Raza Dec 15 '21 at 11:43
  • But not able to tailor it to my use – Muhammad Anas Raza Dec 15 '21 at 11:44
  • 1
    loop through the list and update a sublist when array[i-1] = array[i] + 1, then append the sublist when the difference is > 1 –  Dec 15 '21 at 11:45
  • 3
    Perhaps re-phrasing the question as "I want to group together consecutive numbers in a list" might help show how you'd implement it yourself. Without showing any code you've written its hard to suggest what to fix or change – dwb Dec 15 '21 at 11:46
  • 1
    ```res = [ lst[0] ]\ for i in range(1, len(lst)):\ if lst[i] - 1 == lst[i-1]:\ res[-1].append(lst[i])\ else:\ res.append([lst[i]])``` – Eugene Dec 15 '21 at 11:47
  • @user3928155 Please don't put full answers in the comments, if you've written out a solution just create an answer that way op can accept it and we all know he no longer needs help. – Matt Dec 15 '21 at 11:48
  • 1
    Read this: https://stackoverflow.com/questions/2154249/identify-groups-of-continuous-numbers-in-a-list – Gedas Miksenas Dec 15 '21 at 11:49
  • 1
    Do you have a fixed group size? – Jerven Clark Dec 15 '21 at 11:52

2 Answers2

6

You could use negative indexing:

def group_by_missing(seq):
    if not seq:
        return seq
    grouped = [[seq[0]]]
    for x in seq[1:]:
        if x == grouped[-1][-1] + 1:
            grouped[-1].append(x)
        else:
            grouped.append([x])
    return grouped

Example Usage:

>>> lst = [1, 2, 3, 4, 5, 12, 13, 14, 15, 20, 21, 22, 23, 30, 35, 36, 37, 38, 39, 40]
>>> group_by_missing(lst)
[[1, 2, 3, 4, 5], [12, 13, 14, 15], [20, 21, 22, 23], [30], [35, 36, 37, 38, 39, 40]]
Sash Sinha
  • 18,743
  • 3
  • 23
  • 40
1

A fancy pythonic way to do it with less lines would be possible with the reduce function from functools and a lambda function with an inline if as a criteria for the reduce:

import functools
lis = [1, 2, 3, 4, 5, 12, 13, 14, 15, 20, 21, 22, 23, 30, 35, 36, 37, 38, 39, 40]
result = functools.reduce(lambda x,y : x[:-1]+[x[-1]+[y]] if (x[-1][-1]+1==y) else [*x,[y]], lis[1:] , [[lis[0]]] )
print(result)
Yehdhih ANNA
  • 1,222
  • 1
  • 11
  • 22