4

How would I grab the following:

l=[None, None, 'hello', 'hello']
first(l) ==> 'hello'

l = [None, None, None, None]
first(l) ==> None

I could try doing it with a list comprehension, but that would then error if it had no items.

David542
  • 104,438
  • 178
  • 489
  • 842

2 Answers2

14

Use the following:

first = next((el for el in your_list if el is not None), None)

This builds a gen-exp over your_list and then tries to retrieve the first value that isn't None, where no value is found (it's an empty list/all values are None), it returns None as a default (or change that for whatever you want).

If you want to make this to a function, then:

def first(iterable, func=lambda L: L is not None, **kwargs):
    it = (el for el in iterable if func(el))
    if 'default' in kwargs:
        return next(it, kwargs[default])
    return next(it) # no default so raise `StopIteration`

Then use as:

fval = first([None, None, 'a']) # or
fval = first([3, 4, 1, 6, 7], lambda L: L > 7, default=0)

etc...

Jon Clements
  • 138,671
  • 33
  • 247
  • 280
2

If Im understanding the question correctly

l = [None, None, "a", "b"]

for item in l:
    if item != None:
        first = item
        break

print first

Output:

a

MikeVaughan
  • 1,441
  • 1
  • 11
  • 18