Moh-Spark
Moh-Spark

Reputation: 181

Return the last not null, nan, and non empty value from a python list

How can I return the last not null, not empty, and not nan from a list? if not exists, then return "null" or a customized message!

I have tried these pieces of codes and none of them is bullet proof:

import numpy as np

listF=[0.0,np. NaN,2,0,0.0,""]
print([j for j in listF if j][-1])#returns 2 while should retrun 0

listF=[0.0,np. NaN,np. NaN,0,0.0,np. NaN]
print([j for j in listF if j][-1])#returns nan while should return 0


listF=[]
print([j for j in listF if j][-1])#returns Index out of range


listF=[1,np. NaN,np. NaN,0,0.0,np. NaN]
print([j for j in listF if j][-1])#returns nan while should return 0 

listF=[np. NaN,np. NaN,np. NaN]
print([j for j in listF if j][-1])#returns nan while should return "null"

Upvotes: 1

Views: 933

Answers (3)

mozway
mozway

Reputation: 261890

You can use math.isnan (or numpy.isnan) to check the NA status. Combine it with a generator and next with a default value to handle cases without valid value:

from math import isnan

def last_valid(lst):
    return next((x for x in reversed(lst) if x and not isnan(x)), None) # or 'null'

last_valid([])
# None

last_valid([0.0,np. NaN,2,0,0.0,""])
# 2

last_valid([1,np. NaN,np. NaN,0,0.0,np. NaN])
# 1

last_valid([0.0,np. NaN,np. NaN,0,0.0,np. NaN])
# None

accepting 0 as valid:

Given your update of the rule (0 was initially described as non-valid), you can convert to string in the first test to consider 0 valid:

from math import isnan
def last_valid(lst):
    return next((x for x in reversed(lst) if str(x) and not isnan(x)), '"null"')

last_valid([]))
# '"null"'

last_valid([0.0,np. NaN,2,0,0.0,""])
# 0.0

last_valid([1,np. NaN,np. NaN,0,0.0,np. NaN])
# 0.0

last_valid([0.0,np. NaN,np. NaN,0,0.0,np. NaN])
# 0.0

last_valid([np. NaN,np. NaN,np. NaN])
# '"null"'

Upvotes: 3

Indiano
Indiano

Reputation: 712

This is the oneliner you almost got. You have to keep in mind that nan is not false when in a bolean expression! But always returns false if compared to itself :)

print([i for i in list if i and not i!=i][-1])

Upvotes: 0

Ricardo
Ricardo

Reputation: 691

import numpy as np
import pandas as pd

listF=[0.0,np. NaN,2,0,0.0,""]

output = 'empty list'
for tmp in listF[::-1]:
    if not tmp or pd.isna(tmp):
        continue
    else:
        output = tmp
        break
output

Upvotes: 1

Related Questions