first non-null element in a list, otherwise None

  • Thread starter wheres pythonmonks
  • Start date
W

wheres pythonmonks

This should be trivial:


I am looking to extract the first non-None element in a list, and
"None" otherwise. Here's one implementation:
x = reduce(lambda x,y: x or y, [None,None,1,None,2,None], None)
print x
1

I thought maybe a generator expression would be better, to prevent
iterating over the whole list:
x = ( x for x in [None,1,2] if x is not None ).next()
print x
1

However, the generator expression throws if the list is entirely None.

With list comprehensions, a solution is:
x = ([ x for x in [None,1,2] if x is not None ] + [ None ] )[0]

But this can be expensive memory wise. Is there a way to concatenate
generator expressions?

More importantly,

Is there a better way? (In one line?)

Thanks,

W
 
P

Peter Otten

wheres said:
I am looking to extract the first non-None element in a list, and
"None" otherwise. Here's one implementation:
x = reduce(lambda x,y: x or y, [None,None,1,None,2,None], None)
print x
1

I thought maybe a generator expression would be better, to prevent
iterating over the whole list:
x = ( x for x in [None,1,2] if x is not None ).next()
print x
1

However, the generator expression throws if the list is entirely None.

The next() builtin (new in Python 2.6) allows you to provide a default:
next((item for item in [None, None, "found"] if item is not None), "no
match")
'found'
next((item for item in [None, None, None] if item is not None), "no
match")
'no match'

With list comprehensions, a solution is:
x = ([ x for x in [None,1,2] if x is not None ] + [ None ] )[0]

But this can be expensive memory wise. Is there a way to concatenate
generator expressions?

itertools.chain()

Peter
 
A

Arnaud Delobelle

This should be trivial:

I am looking to extract the first non-None element in a list, and
"None" otherwise.  Here's one implementation:
x = reduce(lambda x,y: x or y, [None,None,1,None,2,None], None)
print x

1

I thought maybe a generator expression would be better, to prevent
iterating over the whole list:
x = ( x for x in [None,1,2] if x is not None ).next()
print x

1

However, the generator expression throws if the list is entirely None.

With list comprehensions, a solution is:
x = ([ x for x in [None,1,2] if x is not None ] + [ None ] )[0]

But this can be expensive memory wise.  Is there a way to concatenate
generator expressions?

More importantly,

Is there a better way?  (In one line?)

Thanks,

W

Just for fun:
print min([None, 2, None, None, 1], key=lambda x: x is None) 2
print min([None, None, None], key=lambda x: x is None)
None

Looks clever but:
min([], key=lambda x: x is None) throws an exception.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,072
Latest member
trafficcone

Latest Threads

Top