How to create sublists with numerical elements that are in a sequence?

Asked

Viewed 811 times

1

Friends, imagine a list:

lista = [1, 2, 2, 3, 3, 3, 6, 6, 7, 11, 12, 12, 13, 14, 14]

Could I create sublists only with the elements that are in sequence? For example, in this case it would be:

lista = [[1, 2, 2, 3, 3, 3], [6, 6, 7], [11, 12, 12, 13, 14, 14]]

The number of sub-lists may vary according to the number of items in the list.

I await and thank you in advance.

  • 2

    Friend, could you give more details? What language? What is the logic for separating the elements into sublists? You refer to List<T> when you say "list" or refer to a Array?

  • If one of the answers solved your problem, could you mark it as accepted/correct by clicking on the side of the answer that contains the best solution? If you do this, your question will also be marked as solved/solved.

2 answers

3

Initially the question did not specify the desired language, and so had done only in Javascript. Now that the author specified that he wants Python, I have implementations in Python, Javascript and Java.

Python

def dividir(array):
    resultado = []
    nada = {}
    parte = []
    ultima = nada
    for elemento in array:
        if len(parte) > 0 and (ultima == nada or (elemento != ultima and elemento != ultima + 1)):
           resultado.append(parte)
           parte = []
        parte.append(elemento)
        ultima = elemento
    if len(parte) > 0:
        resultado.append(parte)
    return resultado

# Teste
array = [1, 2, 2, 3, 3, 3, 6, 6, 7, 11, 12, 12, 13, 14, 14]
lista = dividir(array)
print(lista);

See here working on ideone.

Javascript

function dividir(array) {
    var resultado = [];
    var nada = {};
    var parte = [];
    var ultima = nada;
    for (var idx in array) {
        var elemento = array[idx];
        if (parte.length > 0 && (ultima === nada || (elemento !== ultima && elemento !== ultima + 1))) {
           resultado.push(parte);
           parte = [];
        }
        parte.push(elemento);
        ultima = elemento;
    }
    if (parte.length > 0) resultado.push(parte);
    return resultado;
}

// Teste
var array = [1, 2, 2, 3, 3, 3, 6, 6, 7, 11, 12, 12, 13, 14, 14];
var lista = dividir(array);
console.log(lista);

Click on the blue "Run" button above to test.

Java

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Main {

    private static List<List<Integer>> dividir(int... array) {
        List<Integer> lista = IntStream.of(array).boxed().collect(Collectors.toList());
        return dividir(lista);
    }

    private static List<List<Integer>> dividir(List<Integer> lista) {
        List<List<Integer>> resultado = new ArrayList<>();
        List<Integer> parte = new ArrayList<>();
        Integer ultima = null;
        for (Integer i : lista) {
            int elemento = i;
            if (!parte.isEmpty() && (ultima == null || (elemento != ultima && elemento != ultima + 1))) {
                resultado.add(parte);
                parte = new ArrayList<>();
            }
            parte.add(elemento);
            ultima = elemento;
        }
        if (!parte.isEmpty()) resultado.add(parte);
        return resultado;
    }

    public static void main(String[] args) {
        int[] array = {1, 2, 2, 3, 3, 3, 6, 6, 7, 11, 12, 12, 13, 14, 14};
        List<List<Integer>> lista = dividir(array);
        System.out.println(lista);
    }
}

See here working on ideone.

  • Vixe amigo, I need in python, but thank you very much.

  • @Franciscogerson Ok. I added the [python] tag to your question to make that clear.

  • @Franciscogerson Updated response.

2

If you can use the library Numpy (which I strongly advise), a way very simple to achieve this is with the following code:

# Sua lista original
lista = [1, 2, 2, 3, 3, 3, 6, 6, 7, 11, 12, 12, 13, 14, 14]

# Importa a biblioteca NumPy
import numpy as np

# Separa em grupos usando como índices da separação os locais onde ocorre uma
# diferença entre o item atual e o próximo maior do que 1
grupos = np.split(lista, [i+1 for i,j in enumerate(np.diff(lista)) if j > 1])

# Imprime os grupos produzidos
for i, g in enumerate(grupos):
    print('Grupo #{}: {}'.format(i, g.tolist()))

It produces the following output:

Grupo #0: [1, 2, 2, 3, 3, 3]
Grupo #1: [6, 6, 7]
Grupo #2: [11, 12, 12, 13, 14, 14]

The essential part of the code is the line with the call to np.split. It takes as parameter the list to be divided and another list with the indexes where the division should occur. These indices are located using another Numpy function which is np.diff, that automatically calculates the differences between one item in the list and the next. Basically you only need that line (other than importing).

See working on Ideone.

  • Luiz, appeared one more but here boy, your code worked beauty, it happens that I am working with coordinates x e y, actually my list is a list of lists, where I want to separate the sublists by the first element (x) but need then the second element (y) to do a calculation, you know? So the list would be this: list = [(13, 38), (14, 35), (14, 36), (15, 33), (15, 34), (15, 35), (15, 36), (18, 31), (18, 32), (19, 33), (22, 34), (22, 29), (23, 30), (23, 31), (24, 32)]. So: "list[I have to separate sublists based on this] [but I need this later]"

  • Colleague, two things: 1) That seems to be a totally different question than the one you asked. I answered what you asked. If that wasn’t your question, you should have asked what you wanted to know directly. If you have another question, ask another question. 2) I did not understand what you are asking now and, mainly, did not understand the relationship of the two questions (if there is one) because the format and content have nothing to do with the example you used before.

  • 1

    OK I’ll open another post and explain myself better, sorry.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.