Python idiom to return first item or None
I'm sure there's a simpler way of doing this that's just not occurring to me.
I'm calling a bunch of methods that return a list. The list may be empty. If the list is non-empty, I want to return the first item; otherwise, I want to return None. This code works:
my_list = get_list() if len(my_list) > 0: return my_list return None
It seems to me that there should be a simple one-line idiom for doing this, but for the life of me I can't think of it. Is there?
The reason that I'm looking for a one-line expression here is not that I like incredibly terse code, but because I'm having to write a lot of code like this:
x = get_first_list() if x: # do something with x # inevitably forget the  part, and have a bug to fix y = get_second_list() if y: # do something with y # inevitably forget the  part AGAIN, and have another bug to fix
What I'd like to be doing can certainly be accomplished with a function (and probably will be):
def first_item(list_or_none): if list_or_none: return list_or_none x = first_item(get_first_list()) if x: # do something with x y = first_item(get_second_list()) if y: # do something with y
I posted the question because I'm frequently surprised by what simple expressions in Python can do, and I thought that writing a function was a silly thing to do if there was a simple expression could do the trick. But seeing these answers, it seems like a function is the simple solution.
your_list can be
next(iter(your_list or ), None)
def get_first(iterable, default=None): if iterable: for item in iterable: return item return default
x = get_first(get_first_list()) if x: ... y = get_first(get_second_list()) if y: ...
Another option is to inline the above function:
for x in get_first_list() or : # process x break # process at most one item for y in get_second_list() or : # process y break
break you could write:
for x in yield_first(get_first_list()): x # process x for y in yield_first(get_second_list()): y # process y
def yield_first(iterable): for item in iterable or : yield item return
The best way is this:
a = get_list() return a if a else None
You could also do it in one line, but it's much harder for the programmer to read:
return (get_list()[:1] or [None])
Read more... Read less...
(get_list() or [None])
That should work.
BTW I didn't use the variable
list, because that overwrites the builtin
Edit: I had a slightly simpler, but wrong version here earlier.
The most python idiomatic way is to use the next() on a iterator since list is iterable. just like what @J.F.Sebastian put in the comment on Dec 13, 2011.
next(iter(the_list), None) This returns None if
the_list is empty. see next() Python 2.6+
or if you know for sure
the_list is not empty:
iter(the_list).next() see iterator.next() Python 2.2+
If you find yourself trying to pluck the first thing (or None) from a list comprehension you can switch to a generator to do it like:
next((x for x in blah if cond), None)
Pro: works if blah isn't indexable Con: it's unfamiliar syntax. It's useful while hacking around and filtering stuff in ipython though.
The OP's solution is nearly there, there are just a few things to make it more Pythonic.
For one, there's no need to get the length of the list. Empty lists in Python evaluate to False in an if check. Just simply say
Additionally, it's a very Bad Idea to assign to variables that overlap with reserved words. "list" is a reserved word in Python.
So let's change that to
some_list = get_list() if some_list:
A really important point that a lot of solutions here miss is that all Python functions/methods return None by default. Try the following below.
def does_nothing(): pass foo = does_nothing() print foo
Unless you need to return None to terminate a function early, it's unnecessary to explicitly return None. Quite succinctly, just return the first entry, should it exist.
some_list = get_list() if some_list: return list
And finally, perhaps this was implied, but just to be explicit (because explicit is better than implicit), you should not have your function get the list from another function; just pass it in as a parameter. So, the final result would be
def get_first_item(some_list): if some_list: return list my_list = get_list() first_item = get_first_item(my_list)
As I said, the OP was nearly there, and just a few touches give it the Python flavor you're looking for.
for item in get_list(): return item