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.

1
  • You could iterate using a while loop. Something like: While not None idx += 1. Commented Mar 10, 2015 at 23:28

2 Answers 2

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...

3
  • The first is a function, right?
    – jkd
    Commented Mar 10, 2015 at 23:34
  • Well, it can be made into a function Commented Mar 10, 2015 at 23:35
  • next(filter(None, [None, None, 'a', 'b', 'c']))
    – user123
    Commented Apr 13, 2020 at 17:21
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

2
  • 1
    How is b the first? :p Commented Mar 10, 2015 at 23:34
  • My mistake. It outputs the first. haha Commented Mar 10, 2015 at 23:34

Not the answer you're looking for? Browse other questions tagged or ask your own question.