Update list that contains multiple 0's

Viewed 47

I'm attempting to write a function that given a list will update the 0 values to contain the nearest non zero value. If zeros are at beginning of list then the closest non zero value should be used to replace the zero value.

In other words the following list :

[0 , 0 , 10 , 25 , 30 , 0 , 0 , 0, 55 , 55 , 55 , 55 , 60 , 60 , 60 , 60]

should be updated to :

[10 , 10 , 10 , 25 , 30 , 30 , 30, 30, 55 , 55 , 55 , 55 , 60 , 60 , 60 , 60]

Here is the code I've written so far :

data = [0 , 0 , 10 , 25 , 30 , 0 , 0 , 0, 55 , 55 , 55 , 55 , 60 , 60 , 60 , 60]

index_to_update = []
for index, item in enumerate(data) :
    updated_value = None
    if item == 0 :
        index_to_update.append(index)
    else :
        updated_value = item
        break

for index in index_to_update :
    data[index] = updated_value

updated_list = data.copy()

for index, item in enumerate(data) :
    if item == 0 :
        updated_list[index] = data[index - 1]

print(updated_list)

which prints :

[10, 25, 30, 55, 55, 55, 60, 60, 0, 60, 60, 0, 0]

If I use a list [0 , 0 , 10 , 25 , 30 , 0 , 55 , 55 , 55 , 55 , 60 , 60 , 60 , 60] then it works as expected :

data = [0 , 0 , 10 , 25 , 30 , 0 , 55 , 55 , 55 , 55 , 60 , 60 , 60 , 60]

index_to_update = []
for index, item in enumerate(data) :
    updated_value = None
    if item == 0 :
        index_to_update.append(index)
    else :
        updated_value = item
        break

for index in index_to_update :
    data[index] = updated_value

updated_list = data.copy()

for index, item in enumerate(data) :
    if item == 0 :
        updated_list[index] = data[index - 1]

print(updated_list)

prints :

[10, 10, 10, 25, 30, 30, 55, 55, 55, 55, 60, 60, 60, 60]

0's at positions 0 and 1 are replaced with 10. 0 at position 5 is replaced with 30.

My algorithm breaks when there are multiple 0's contained :

[0 , 0 , 10 , 25 , 30 , 0 , 0 , 0, 55 , 55 , 55 , 55 , 60 , 60 , 60 , 60]

What modification(s) is required to my algo in order to convert a list containing elements

[0 , 0 , 10 , 25 , 30 , 0 , 0 , 0, 55 , 55 , 55 , 55 , 60 , 60 , 60 , 60]

to :

[10 , 10 , 10 , 25 , 30 , 30 , 30 , 30, 55 , 55 , 55 , 55 , 60 , 60 , 60 , 60]
3 Answers

This is my approach to this problem:

lst = [0, 0, 10, 25, 30, 0, 0, 0, 55, 55, 55, 55, 60, 60, 60, 60]

fnz, lnz = None, None

for i, v in enumerate(lst):
    if v != 0:
        if fnz is None:
            fnz = v, i
        lnz = v
    else:
        if lnz is not None:
            lst[i] = lnz
if fnz is not None and (offset := fnz[1]) > 0:
    lst[:offset] = [fnz[0]] * offset
print(lst)

Output:

[10, 10, 10, 25, 30, 30, 30, 30, 55, 55, 55, 55, 60, 60, 60, 60]

You don't need the update_list. I find your algorithm works just fine, because you have found a way to 'fix' the leading zeroes and then it goes on to fix any remaining zeroes by just copying a previous value (which will have been fixed).

I changed your code to eliminate update_list and it seems to work just fine:

data = [0 , 0 , 10 , 25 , 30 , 0 , 0 , 0, 55 , 55 , 0 , 55 , 60 , 0 , 60 , 60]

index_to_update = []
for index, item in enumerate(data):
    updated_value = None
    if item == 0:
        index_to_update.append(index)
    else:
        updated_value = item
        break

for index in index_to_update:
    data[index] = updated_value

for index, item in enumerate(data):
    if item == 0:
        data[index] = data[index - 1]

print(data)

Output:

[10, 10, 10, 25, 30, 30, 30, 30, 55, 55, 55, 55, 60, 60, 60, 60]

You can add a simple while loop so that the code will continue until there are no 0's in the list anymore. Something like this:

data = [0 , 0 , 10 , 25 , 30 , 0 , 55 , 55 , 55 , 55 , 60 , 60 , 60 , 60]

while 0 in data:
    index_to_update = []
    for index, item in enumerate(data) :
        updated_value = None
        if item == 0 :
            index_to_update.append(index)
        else:
            updated_value = item
            break

    for index in index_to_update :
        data[index] = updated_value

    updated_list = data.copy()

    for index, item in enumerate(data) :
        if item == 0 :
            updated_list[index] = data[index - 1]

print(updated_list)
Related