Разбивка списка номеров на диапазоны
Есть список номеров в Excel-файле, необходимо сократить его до диапазонов номеров, но только до полных 10, 100, 1000 и т.д.
Например, из
3012275120
3012275121
3012275122
3012275123
3012275124
3012275125
3012275126
3012275127
3012275128
3012275129
Надо сделать 301227512*
А номера, которые не попадают в диапазоны оставить как есть.
Желательно на Python
Ответы (1 шт):
Достаточно сложное решение получилось. Проще не придумал. Пока значения из seq
следуют без разрывов, очередь queue
накапливает значения. Например, предыдущее число было 2987 и содержимое очереди:
queue == [ [2980, 2981, 2982, 2983, 2984, 2985, 2986, 2987], [290, 291, 292, 293, 294, 295, 296, 297], [20, 21, 22, 23, 24, 25, 26, 27, 28], [] ]
Нулевая строка очереди хранит накопленные значения для единиц, следующая для десятков, дальше сотни и так далее. Например значение 21 в разряде сотен соответствует группе 21**.
Следующее значение 2988 добавляется в разряд единиц:
queue == [ [2980, 2981, 2982, 2983, 2984, 2985, 2986, 2987, 2988], [290, 291, 292, 293, 294, 295, 296, 297], [20, 21, 22, 23, 24, 25, 26, 27, 28], [] ]
Если значение заканчивается на девятку и разряд заполнился до десяти значений, он удаляется, в следующий разряд добавляется значение. Следующее значение 2989 меняет очередь:
queue == [ [], [290, 291, 292, 293, 294, 295, 296, 297, 298], [20, 21, 22, 23, 24, 25, 26, 27, 28], [] ]
Эта группировка и перенос делается в цикле. В случае разрыва нумерации или окончания последовательности группы из очереди печатаются, сама очередь очищается.
def ranges(seq):
queue = []
def drop_queue():
for i in range(len(queue))[::-1]:
for r in queue[i]:
yield f'{r}{"*" * i}'
queue[:] = []
prev = 0
for v in seq:
if v != prev + 1:
yield from drop_queue()
prev = v
if not queue or queue[-1]:
queue.append([])
for line in queue:
line.append(v)
if v % 10 != 9:
break
if len(line) == 10:
line[:] = []
v //= 10
else:
yield from drop_queue()
break
yield from drop_queue()
Примеры:
for r in ranges([
3012275120, 3012275121, 3012275122, 3012275123, 3012275124,
3012275125, 3012275126, 3012275127, 3012275128, 3012275129
]):
print(r)
301227512*
for r in ranges(range(1888, 3222)):
print(r)
1888 1889 189* 19** 2*** 30** 31** 320* 321* 3220 3221