1

I have a list of values

lst = [75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 185, 186, 187, 188, 189, 190, 191, 192, 193, 195, 196, 197, 198, 199, 221, 222, 223, 224, 225, 226, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 309, 310, 311, 312, 313, 314, 315, 316, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 401, 402, 403, 404, 405, 406, 407, 408, 439, 440]

If you have a close look at the list, you can see that values are incrementing and then there is a big jump and then again values start to increment.

How can I split so in the end I can have

[[75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88], [118, 119, 120, 121, 122, 123, 124, 125, 126, 127], [155, 156, 157, 158, 159, 160, 161, 162, 163, 164]...[439, 440]]
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Sabzaliev Shukur
  • 361
  • 5
  • 12

3 Answers3

3

Here is a solution with itertools. I used as condition to keep consecutive numbers (thanks @KarlKnechtel).

from itertools import groupby
diff = [item - i for i, item in enumerate(lst)]
[[x[1] for x in g] for i,g in groupby((zip(diff,lst)), lambda x: x[0])]

output:

[[75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88],
 [118, 119, 120, 121, 122, 123, 124, 125, 126, 127],
 [155, 156, 157, 158, 159, 160, 161, 162, 163, 164],
 [185, 186, 187, 188, 189, 190, 191, 192, 193],
 [195, 196, 197, 198, 199],
 [221, 222, 223, 224, 225, 226],
 [273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283],
 [309, 310, 311, 312, 313, 314, 315, 316],
 [371, 372, 373, 374, 375, 376, 377, 378, 379, 380],
 [401, 402, 403, 404, 405, 406, 407, 408],
 [439, 440]]
mozway
  • 194,879
  • 13
  • 39
  • 75
  • 3
    We don't need to compare adjacent elements to solve the problem. Based on the potential duplicate found by @don't talk just code, consider what happens if you subtract *the indices* from the values: `diff = [item - i for i, item in enumerate(lst)]`. You should find that it's possible to write a simpler `key` for the `groupby` after that. – Karl Knechtel Sep 16 '21 at 06:23
  • Using the same logic with `enumerate`, but as a one-liner thanks to [`more_itertools.groupby_transform`](https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.groupby_transform): `[g for k,g in more_itertools.groupby_transform(enumerate(lst), keyfunc=lambda p: p[1]-p[0], valuefunc=operator.itemgetter(1), reducefunc=list)]` – Stef Sep 16 '21 at 10:24
  • Actually, your solution is almost identical to the source code of `more_itertools.consecutive_groups`: https://more-itertools.readthedocs.io/en/stable/_modules/more_itertools/more.html#consecutive_groups – Stef Sep 16 '21 at 10:39
2

Try:

data = []
tmp = []
for i, j in zip(lst[:-1], lst[1:]):
    if j - i > 1:
        data.append(tmp)
        tmp = []
    else:
        tmp.append(i)
data.append(tmp + [lst[-1]])

Output:

>>> data
[[75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87],
 [118, 119, 120, 121, 122, 123, 124, 125, 126],
 [155, 156, 157, 158, 159, 160, 161, 162, 163],
 [185, 186, 187, 188, 189, 190, 191, 192],
 [195, 196, 197, 198],
 [221, 222, 223, 224, 225],
 [273, 274, 275, 276, 277, 278, 279, 280, 281, 282],
 [309, 310, 311, 312, 313, 314, 315],
 [371, 372, 373, 374, 375, 376, 377, 378, 379],
 [401, 402, 403, 404, 405, 406, 407],
 [439, 440]]
Corralien
  • 109,409
  • 8
  • 28
  • 52
  • Alternatively `list(more_itertools.split_when(lst, lambda x,y: y-x != 1))`: [documentation](https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.split_when); [source code](https://more-itertools.readthedocs.io/en/stable/_modules/more_itertools/more.html#split_when) – Stef Sep 16 '21 at 10:09
1
ans = [[]]
for a, b in zip(lst[:-1], lst[1:]):
    ans[-1].append(a)
    if b-a > 1:
        ans .append([])
ans[-1].append(lst[-1])

We are checking brute force and then making new list and appending it to another parent list.

user2736738
  • 30,591
  • 5
  • 42
  • 56