- The problem is the list - lgets smaller after calling- l.remove(value), but subscript 'i' still try to index the original- l.
 
- Based on the above analysis, one solution is to keep - lunchanged in the inner loop, the other is to keep the unseen- ireduced along with- l.
 
# Create new lists to keep `l` unchanged in the inner loop
def method1():
    l = [0, 1, 0, 0, 1, 1]
    removed= []
    while l:
      next_l = []
      [next_l.append(v) if v <= 0 else removed.append(i) for i, v in enumerate(l)]
      l = [x+1 for x in next_l]
    return removed
def method2():
    l = [0, 1, 0, 0, 1, 1]
    removed= []
    while l:
        num_del = 0  # record number of deletions in the inner loop
        for i in range(len(l)):
            if l[i-num_del]>0:
                l.remove(l[i-num_del])
                num_del += 1
                # store the index processing order
                removed.append(i)
            else:
                continue
        l = [x+1 for x in l]
    return removed
assert method1() == method2()
# output [1, 4, 5, 0, 1, 2]
But I guess you expect the result [1, 4, 5, 0, 2, 3], i.e., record the processing order with subscript in the original list. If so, try this:
l = [0, 1, 0, 0, 1, 1]
el = list(enumerate(l))
removed = []
bound = 0
while len(removed) != len(l):
    removed.extend(list(filter(lambda iv: iv[1] > bound, el)))
    el = list(filter(lambda iv: iv[1] <= bound, el))
    bound -= 1
removed, _ = zip(*removed)