Как разбить последовательные элементы в списке на подсписки - PullRequest
1 голос
/ 30 апреля 2019

У меня есть следующий список:

indices_to_remove: [0,1,2,3,..,600,800,801,802,....,1200,1600,1601,1602,...,1800]

У меня есть в основном 3 подмножества последовательных индексов:

  1. 0-600
  2. 800-1200
  3. 1600-1800

Я хотел бы создать 3 разных небольших списка, которые будут включать только последовательные номера.

Ожидаемый результат:

indices_to_remove_1 : [0,1,2,3,....,600]
indices_to_remove_2 : [800,801,802,....,1200]
indices_to_remove_3 : [1600,1601,1602,....., 1800]

P.S .: числа являются произвольными и случайными; более того, я могу встретить более 3 подмножеств или меньше.

Ответы [ 3 ]

3 голосов
/ 30 апреля 2019

Мне нравится использовать генераторы для такого рода проблем. Вы можете сделать это следующим образом:

Разделить непоследовательные данные:

def split_non_consequtive(data):
    data = iter(data)
    val = next(data)
    chunk = []
    try:
        while True:
            chunk.append(val)
            val = next(data)
            if val != chunk[-1] + 1:
                yield chunk
                chunk = []
    except StopIteration:
        if chunk:
            yield chunk

Тестовый код:

indices_to_remove = (
        list(range(0, 11)) +
        list(range(80, 91)) +
        list(range(160, 171))
)

for i in split_non_consequtive(indices_to_remove):
    print(i)

Результаты:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90]
[160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170]
1 голос
/ 30 апреля 2019

Другой способ использует more_itertools.consecutive_groups: ( использовал список @ Стивена для примера ):

import more_itertools as mit
for group in mit.consecutive_groups(indices_to_remove):
    print(list(group))

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90]
[160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170]
0 голосов
/ 30 апреля 2019

Не усложняя, вы можете просто решить это примерно так:

def chunk_lists_(data_):

    consecutive_list = []

    for chunks in range(len(data_)):

        try:

            #check consecutiveness
            if data_[chunks + 1] - data_[chunks] == 1:

                #check if it's already in list
                if data_[chunks] not in consecutive_list:
                    consecutive_list.append(data_[chunks])

                #add last one too
                consecutive_list.append(data_[chunks + 1])

            else:

                #yield here and empty list
                yield consecutive_list
                consecutive_list = []
        except Exception:
            pass
    yield consecutive_list

Тест:

#Stephen's list 
print(list(chunk_lists_(list(range(0, 11)) +
        list(range(80, 91)) +
        list(range(160, 171)))))

выход: * +1010 *

[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90], [160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170]]
...