Get value at list/array index or "None" if out of range in Python

Python

Python 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionChris DutrowView Question on Stackoverflow
Solution 1 - Pythonthe wolfView Answer on Stackoverflow
Solution 2 - PythonHashkenView Answer on Stackoverflow
Solution 3 - Pythonuser5207081View Answer on Stackoverflow
Solution 4 - PythonAkavallView Answer on Stackoverflow
Solution 5 - PythonAndrzej PiaseckiView Answer on Stackoverflow
Solution 6 - PythonEmmett ButlerView Answer on Stackoverflow
Solution 7 - PythonXerCisView Answer on Stackoverflow