Python for Programmers: Negative Indexing
Welcome to the Negative Indexing lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
We can get the last element of a list by computing the last index. In a list with 3 elements, the last index is 2.
>
ingredients = ["milk", "flour", "eggs"]ingredients[len(ingredients) - 1]Result:
'eggs'
That works, but Python makes this easier with some syntactic sugar. We can get the last element in a list with
ingredients[-1], without needing to uselenat all.>
ingredients = ["milk", "flour", "eggs"]ingredients[-1]Result:
'eggs'
Take a moment to compare the final lines of the last two code examples:
ingredients[len(ingredients) - 1]vs.ingredients[-1]. Negative indexing syntax is quite terse!Negative indexing works for more than just
-1.some_list[-2]gives us the second-to-last element.some_list[-3]gives us the third-from-the-last element, and so on.>
numbers = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]numbers[-6]Result:
6
Negative indexing also works in assignments. For example, the assignment
some_list[-1] = ...replaces the last element of the list.>
ingredients = ["eggs", "flour", "water"]ingredients[-1] = "milk"ingredientsResult:
['eggs', 'flour', 'milk']
Negative indexing can feel strange at first. Here are two ways to think about it.
The first way is to see negative indexing as "counting backwards" from the end of the list. This is a bit strange, because negative indexing starts at
-1, so it's not the same as zero-indexing. But the fact thatsome_list[-3]gives us the third element from the end is helpful.The second way is to think of an index like
-3as shorthand forlen(some_list) - 3. We can always think ofsome_list[-3]assome_list[len(some_list) - 3].>
letters = ["A", "B", "C", "D"]letters[-2] == letters[len(letters) - 2]Result:
True
Both of these mental models work well. You may prefer one of them, or you may switch between them depending on the situation.
When a negative index doesn't exist in the list, we get an
IndexError. This matches the behavior that we already saw for regular, non-negative indexes. For example, if we have a list of 2 elements,-2is a valid index but-3isn't.>
students = ["Amir", "Betty"]students[-3]Result:
IndexError: list index out of range
The possible indexes for a non-empty list
my_listare:- All non-negative numbers from
0tolen(my_list) - 1. - All negative numbers from
-len(my_list)to-1.
- All non-negative numbers from
If a list is empty, we can't index into it at all. It doesn't matter whether we use positive or negative indexes.
>
students = []students[-1]Result:
IndexError: list index out of range
Here's a code problem:
Finish the
balanced_listfunction below. It should decide whether a list starts and ends with the same value. Only the first and last list element matter here; the rest of the elements can be anything.You can solve this with a single
==comparison that uses negative indexing!You'll also need to handle the case where the list is empty. (In that case, your function should return
True.)def balanced_list(the_list):return len(the_list) == 0 or the_list[0] == the_list[-1]assert balanced_list([]) == Trueassert balanced_list([1]) == Trueassert balanced_list([1, 2]) == Falseassert balanced_list([1, 2, 1]) == Trueassert balanced_list(["d", "r", "i", "e", "d"]) == Trueassert balanced_list(["d", "r", "i", "n", "k"]) == False- Goal:
No errors.
- Yours:
No errors.