Is there clean way to get the value at a list index or None
if the index is out or range in Python?
The obvious way to do it would be this:
if len(the_list) > i:
return the_list[i]
else:
return None
However, the verbosity reduces code readability. Is there a clean, simple, one-liner that can be used instead?
-
1I don't think this is a good idea. What about slices? Negative indexes? The ambiguity of a list with a None in it?user648852– user6488522012年08月29日 22:41:07 +00:00Commented Aug 29, 2012 at 22:41
-
2Possible duplicate of How to get the nth element of a python list or a default if not availableRotareti– Rotareti2018年03月01日 19:54:22 +00:00Commented Mar 1, 2018 at 19:54
9 Answers 9
Try:
try:
return the_list[i]
except IndexError:
return None
Or, one liner:
l[i] if i < len(l) else None
Example:
>>> l=list(range(5))
>>> i=6
>>> print(l[i] if i < len(l) else None)
None
>>> i=2
>>> print(l[i] if i < len(l) else None)
2
8 Comments
I find list slices good for this:
>>> x = [1, 2, 3]
>>> a = x [1:2]
>>> a
[2]
>>> b = x [4:5]
>>> b
[]
So, always access x[i:i+1], if you want x[i]. You'll get a list with the required element if it exists. Otherwise, you get an empty list.
6 Comments
my_list[idx: idx+1] or "Default_value"
. Readable and succinct! :)a = [1,3,5,7,9]; b = [num for num in a if num % 2 == 0][0:1] or "No evens found"; print(b) No evens found
(my_list[idx: idx+1] or ["Default_value"])[0]
x[1:2]
, you could assign it to var
via many forms of unpacking. Tuple unpacking: (var,) = x[1:2]
or var, = x[1:2]
or var, *_ = x[1:2]
. List unpacking: [var] = x[1:2]
. Whilst I normally don't use brackets for tuple unpacking, in this case I'd prefer (var,) = x[1:2]
as it's both short and (IMHO) explicit, since the tuple form should be more recognisable.If you are dealing with small lists, you do not need to add an if statement or something of the sorts. An easy solution is to transform the list into a dict. Then you can use dict.get
:
table = dict(enumerate(the_list))
return table.get(i)
You can even set another default value than None
, using the second argument to dict.get
. For example, use table.get(i, 'unknown')
to return 'unknown'
if the index is out of range.
Note that this method does not work with negative indices.
Comments
For your purposes you can exclude the else
part as None
is return by default if a given condition is not met.
def return_ele(x, i):
if len(x) > i: return x[i]
Result
>>> x = [2,3,4]
>>> b = return_ele(x, 2)
>>> b
4
>>> b = return_ele(x, 5)
>>> b
>>> type(b)
<type 'NoneType'>
Comments
Combining slicing and iterating
next(iter(the_list[i:i+1]), None)
3 Comments
1. if...else...
l = [1, 2, 3, 4, 5]
for i, current in enumerate(l):
following = l[i + 1] if i + 1 < len(l) else None
print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None
2. try...except...
l = [1, 2, 3, 4, 5]
for i, current in enumerate(l):
try:
following = l[i + 1]
except IndexError:
following = None
print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None
3. dict
suitable for small list
l = [1, 2, 3, 4, 5]
dl = dict(enumerate(l))
for i, current in enumerate(l):
following = dl.get(i + 1)
print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None
4. List slicing
l = [1, 2, 3, 4, 5]
for i, current in enumerate(l):
following = next(iter(l[i + 1:i + 2]), None)
print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None
5. itertools.zip_longest
from itertools import zip_longest
l = [1, 2, 3, 4, 5]
for i, (current, following) in enumerate(zip_longest(l, l[1:])):
print(current, following)
# 1 2
# 2 3
# 3 4
# 4 5
# 5 None
Using Jupyter magic command of %%timeit
init
from itertools import zip_longest
l = list(range(10000000))
Result
Method | Consume |
---|---|
if...else... | 2.62 s |
try...except... | 1.14 s |
dict | 2.61 s |
List slicing | 3.75 s |
itertools.zip_longest | 1.14 s |
1 Comment
return the_list[i] if len(the_list) > i else None
2 Comments
Another one-liner:
return((the_list + [None] * i)[i])
3 Comments
the_list
once.. def getItemOrNone(lst,index):
return [None,*lst[index:-~index]][~0]