А не проще ли будет сделать в два прохода.
Прямым проходом делаем так: если 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]
Правда, это даст некорректный результат, если список не содержит нулей. Но это можно обнаружить в ходе первого прохода.