Подсчитать количество конкретных элементов между другими элементами в списке

Я читаю файл данных. Строки начинаются с последовательных номеров (шагов), а иногда между каждой строкой есть 0.

Например:

1 0 2 0 3 4 5 0 0 0 6 0 

Как создать список, который подсчитывает количество 0s между каждым шагом.

Мне нужен список:

 finalList = [1,1,0,0,3,1] 

который представляет количество 0, каждый из которых содержит, например: шаг 1 имеет 1 ноль, этап 2 имеет 1 нуль, этап 3 имеет 0 нулей, этап 4 имеет 0 нулей, этап 5 имеет 3 нуля, а этап 6 имеет 1 ноль.

    Следующий код должен работать, если ваш файл данных выглядит точно так, как вы описали (например, нет другого номера, кроме числа шагов и нулей).

     cur = 0 res = [] with open("file.txt") as f: for line in f: if line.strip() == '0': cur += 1 else: res.append(cur) cur = 0 
     a = [1,0,2,0,3,4,5,0,0,0,6,0] finalList = [] count = 0 for i in xrange(len(a)): if i == 0 : continue if a[i] == 0 : count += 1 else : finalList.append(count) count = 0 finalList.append(count) 

    Возможно, слишком умное решение, использующее батареи Python:

     from itertools import chain, groupby with open("file.txt") as f: # Add extra zeroes after non-zero values so we see a group when no padding exists extrazeroes = chain.from_iterable((x, 0) if x else (x,) for x in map(int, f)) # Count elements in group and subtract 1 if not first group to account for padding # The filter condition means we drop non-zero values cheaply zerocounts = [sum(1 for _ in g) - bool(gnum) for gnum, (k, g) in enumerate(groupby(extrazeroes)) if k == 0] # If leading zeroes (before first non-zero line) can't happen, simplify to: zerocounts = [sum(1 for _ in g) - 1 for k, g in groupby(extrazeroes) if k == 0] 

    Да, это немного сложно (если вам не нужно включать нули, где не было никакого промежутка между двумя ненулевыми значениями, это было бы намного проще), но оно кратким и должно быть очень быстрым. Если вы можете опустить 0 с в своих подсчетах, это упростит гораздо более чистый:

     with open("file.txt") as f: zerocounts = [sum(1 for _ in g) for k, g in groupby(map(int, f)) if k == 0] 

    Для записи я использовал бы последний, если бы он соответствовал требованиям. Первый, вероятно, не должен идти в производственном кодексе. 🙂

    Обратите внимание, что в зависимости от вашего groupby использования, использование groupby может быть хорошей идеей для вашей более широкой проблемы; в комментариях вы упоминаете, что вы сохраняете все строки в файле (используя f = f.readlines() ), что подразумевает, что вы будете обращаться к ним, возможно, на основе значений, хранящихся в zerocounts . Если у вас есть какая-то конкретная необходимость обрабатывать каждый «шаг» на основе количества следующих нулей, адаптация вышеприведенного кода может сэкономить вам накладные расходы на хранение файла путем ленивой группировки и обработки.

    Примечание. Чтобы избежать разбиения всего файла на память, в Python 2 вы хотите добавить from future_builtins import map так что map – это ленивая функция генератора, такая как в Py3, вместо того, чтобы загружать весь файл и преобразовывать все его в int спереди. Если вы не хотите копировать map , импортирование и использование itertools.imap по map для преобразования int выполняет ту же цель.

    Я придумал это:

     finalList = [] count = 0 step = None for e in [1, 0, 2, 0, 3, 4, 5, 0, 0, 0, 6, 0]: if e > 0: if step: finalList.append(count) step = e count = 0 else: count += 1 if step: finalList.append(count) 

    Альтернативное решение

     # temp list (copy of l with last element if doesn't exist) _l = l if l[-1] > 0 else l + [max(l) + 1] # _l.index(i) - _l.index(i - 1) - 1 = distance between elements [_l.index(i) - _l.index(i - 1) - 1 for i in range(2, max(_l) + 1)]