Возможно, слишком умное решение с использованием включенных в 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
может быть хорошей идеей для вашей более широкой проблемы; в комментариях вы упоминаете, что сохраняете все строки в файле (используя f = f.readlines()
), что означает, что вы будете обращаться к ним, возможно, на основе значений, хранящихся в zerocounts
. Если у вас есть какая-то конкретная потребность в обработке каждого «шага» на основе количества следующих нулей, адаптация приведенного выше кода может сэкономить вам накладные расходы памяти на глотание файла путем ленивой группировки и обработки.
Примечание. Чтобы избежать загрузки всего файла в память, в Python 2 вам нужно добавить from future_builtins import map
, поэтому map
является функцией ленивого генератора, как в Py3, а не загрузкой всего файла и преобразованием все это int
вперед. Если вы не хотите топать map
, импорт и использование itertools.imap
вместо map
для int
преобразования достигает той же цели.
person
ShadowRanger
schedule
21.12.2015