Get value at list/array index or "None" if out of range in Python
PythonPython Problem Overview
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?
Python Solutions
Solution 1 - Python
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
Solution 2 - Python
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.
Solution 3 - Python
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.
Solution 4 - Python
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'>
Solution 5 - Python
Combining slicing and iterating
next(iter(the_list[i:i+1]), None)
Solution 6 - Python
return the_list[i] if len(the_list) > i else None
Solution 7 - Python
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 |