Python: как разделить список на неизвестное количество списков меньшего размера на основе делиметра

#python #list #split

#python #Список #разделить

Вопрос:

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

Основной список
’00:00′
’00:01′
’00:02′
’00:03′
’00:04′
’00:00′
’00:01′
’00:02′
’00:03′
’00:04′

Я хотел бы разделить это на меньшее количество списков всякий раз, когда встречается ’00:00′, поскольку ’00: 00′ — это единственный элемент, который не изменится:

Желаемый результат:
Список 1
’00:00′
’00:01′
’00:02′
’00:03′
’00:04′

Список 2
’00:00′
’00:01′
’00:02′
’00:03′
’00:04′

Я попытался посмотреть на нарезку списка, но проблема в том, что последнее значение и, как таковое, количество элементов может измениться. Более того, я не уверен, сколько списков меньшего размера мне понадобится (и как я буду динамически создавать n количество списков меньшего размера?)

Ответ №1:

Обычно я делаю это:

 def splitby( lst, breaker='00:00'):
    current = []
    it = iter(lst)
    first = next(it)
    assert first==breaker, "`lst` must begin with `breaker`"
    current.append(first)
    for item in it:
        if item == breaker:
            yield current
            current = []
        current.append(item)
    yield current
  

Неизбежное решение itertools немного более общее:

 from itertools import groupby

class splitter(object):
    
    def __init__(self, breaker):
        self.breaker = breaker
        self.current_group = 0
        
    def __call__(self, item):
        if item == self.breaker:
            self.current_group =1
        return self.current_group
        
    def group(self, items):
        return (list(v) for k,v in groupby(items,self))
    
print list(splitter('00:00').group(items))
  

Комментарии:

1. Привет всем, я выбрал ваше первое решение — возврат генератора. 🙂 Однако, похоже, я не могу разделить генератор на явные списки? Я запускаю code: for x in splitby(lst): print(x) , но как я могу присвоить каждому объекту списка его собственное уникальное имя, например, в конечном итоге ‘list1’ и ‘list2’ из объекта generator вместо просто x? Спасибо за ответ, генераторы — это то, с чем я никогда раньше не сталкивался!

2. @cbros2008: Просто сделай, splitted = list(splitby(lst)) тогда ты сможешь использовать splitted[0] и т. Д

Ответ №2:

В явном виде вы могли бы сделать так :

 sep = '00:00'
split_list = []
for item in Mainlist:
    if item == sep:
        split_list.append([item])
    else:
        split_list[-1].append(item)

print split_list
  

Комментарии:

1. Мне это нравится, потому что это делает довольно очевидным, что происходит.

Ответ №3:

Понимание — ваш лучший друг :). Всего две строки:

 >>> a=['00:00', '00:01', '00:02', '00:03', '00:00', '00:01', '00:02']
>>> found=[index for index,item in enumerate(a) if item=='00:00']   [len(a)]
>>> [a[found[i]:found[i 1]] for i in range(len(found)-1)]
[['00:00', '00:01', '00:02', '00:03'], ['00:00', '00:01', '00:02']]
  

Вот что мы делаем:

Мы ищем позиции разделителей и получаем список, содержащий индексы разделителей:

 >>> found=[index for index,item in enumerate(a) if item=='00:00']
>>> found
[0, 4]
  

Мы добавляем len(a) для включения последнего dict.

И создание новых списков с разделением a с установленными индексами :

 >>> [a[found[i]:found[i 1]] for i in range(len(found)-1)]
[['00:00', '00:01', '00:02', '00:03'], ['00:00', '00:01', '00:02']]
  

Комментарии:

1. Спасибо за ответ. Мне нравится идея захвата индексов разделителя.

Ответ №4:

Я мог бы придумать другой способ 🙂

 def list_split(a):
    #a=['00:00', '00:01', '00:02', '00:03', '00:00', '00:01', '00:02']
    output = []
    count = 0

    if len(a) < 1:
        output.append(a)
        return output

    for i, item in enumerate(a[1:]):
        if item == a[0]:
            output.append(a[count:i 1])
            count = i   1
    else:
        output.append(a[count:])
        return output