Why doesn't an out of range index in a slice produce an error?

I stumbled across this issue while working on problem 4 of " Advanced Python Code Challenges: Lists". It involves creating a function that takes a list of numbers and an index as arguments, then doubles the value of $number at position $index inside the list. I expected an error if I called my function with the maximum index because I add 1 to the index later in the function. Instead of throwing an IndexError, it completed gracefully.

I noticed that the addition happens in a slice, so I experimented a bit and discovered that it doesn’t matter how large the numbers in my slices are, they don’t produce an error, while the same index on its own does. i.e. For a given list “lst = [0, 1, 2]”, “new_lst = lst[10]” produces an IndexError while “new_lst = lst[10:]” does not.

Here is my code from the challenge with variables replaced with actual test values

# Function double_index takes a list and doubles the value at the specified index

def double_index(lst, index):  # Test values double_index([0, 1, 2], 2)
    if index >= len(lst):  # if 2 >= 3 (FALSE)
        return "ERROR"  # Doesn't run
    else:
        new_list = lst[:index]  # $new_list = [0, 1]
        new_list.append(lst[index] * 2)  # Append doubled value from index 2
        new_list = new_list + lst[index + 1:]  # Expected an error because index + 1 is 3, but max index is 2
        return new_list  # Returns $new_list without error
1 Like

Aye, you’re quite right it’s just a difference between slicing and indexing. Indexing is a direct look-up so when it can’t find the given index then you get an error. Slicing creates a new object and should nothing be returned within the given range it still returns that object, just an empty one.
py3docs: common-sequence-operations see the notes.

2 Likes