Как еще чуть ускорить алгоритм?
А не проще ли будет сделать в два прохода.
Прямым проходом делаем так: если 0, то счетчик в ноль, иначе счетчик + 1 и элемент приравниваем счетчику.
Потом то же самое делаем обратным проходом, но изменяем элемент только если он больше счетчика.
Отсюда получаем:
lst=[5, 3, 0, 2, 0, 3, 8, 2, 9, 7, 0, 0, 7, 1, 5, 3]
L = len(lst)
# если в начале списка не 0, то мы сможем задать корректные значения только на обратном ходе
# так что ставим заведомо большее значение счетчика
counter = len(lst) if lst[0] != 0 else 0
for i in range(0, L):
  if lst[i] == 0:
    counter = 0
  else:
    counter += 1
    lst[i] = counter
# обратный ход
counter = lst[-1] - 1 #чтобы не запороть последние элементы
for i in range(L-1, -1, -1):
  if lst[i] == 0:
    counter = 0
  else:
    counter += 1
    lst[i] = min(counter, lst[i])

print(lst)
# [2, 1, 0, 1, 0, 1, 2, 3, 2, 1, 0, 0, 1, 2, 3, 4]
Правда, это даст некорректный результат, если список не содержит нулей. Но это можно обнаружить в ходе первого прохода.
Путь действительно странный. А главное, есть какие-то непонятные действия с массивом, которые, возможно, приводят к копированию, например result_arr = result_arr + know_range(number)

Проще всего было бы из строки получить массив с возрастающими ненулевыми интервалами, а потом пройтись по нему справа налево и "посрезать уголки":

строка "5 3 0 4 6 1 5 0 9 2 3 0"
массив после первого обхода: [inf, inf, 0, 1, 2, 3, 4, 0, 1, 2, 3, 0]
после обратного обхода, тот же массив: [2, 1, 0, 1, 2, 2, 1, 0, 1, 2, 1, 0]