Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to replace None in the List with previous value

I want to replace the None in the list with the previous variables (for all the consecutive None). I did it with if and for (multiple lines). Is there any way to do this in a single line? i.e., List comprehension, Lambda and or map

And my idea was using the list comprehension but I was not able to assign variables in a list comprehension to set a previous value.

I have got a similar scenario in my project to handle None in such a way, the thing is I don't want to write 10 lines of code for the small functionality.

def none_replace(ls):
    ret = []
    prev_val = None
    for i in ls:
        if i:
            prev_val = i
            ret.append(i)
        else:
            ret.append(prev_val)
    return ret

print('Replaced None List:', none_replace([None, None, 1, 2, None, None, 3, 4, None, 5, None, None]))

Output:

Replaced None List: [None, None, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5]

like image 233
Parvathirajan Natarajan Avatar asked Sep 30 '20 06:09

Parvathirajan Natarajan


2 Answers

You can take advantage of lists being mutable

x =[None, None, 1, 2, None, None, 3, 4, None, 5, None, None]
for i,e in enumerate(x[:-1], 1):
    if x[i] is None:
        x[i] = x[i-1]
print(x)

output

[None, None, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5]
like image 174
Ajay Verma Avatar answered Sep 19 '22 18:09

Ajay Verma


You can use the function accumulate() and the operator or:

from itertools import accumulate

list(accumulate(lst, lambda x, y: y or x))
# [None, None, 1, 2, 2, 2, 3, 4, 4, 5, 5, 5]

In this solution you take the element y and the previous element x and compare them using the operator or. If y is None you take the previous element x; otherweise, you take y. If both are None you get None.

like image 40
Mykola Zotko Avatar answered Sep 23 '22 18:09

Mykola Zotko