# Python NumPy For Your Grandma - 2.4 Indexing 1-D Arrays

Contents

In this section, we’ll look at how to index a 1d array to access and modify its elements.

We’ll start by making a 1d array called `foo` with five elements.

``````import numpy as np
foo = np.array([10, 20, 30, 40, 50])
print(foo)
## [10 20 30 40 50]
``````

We can access the ith element just like a python list using square bracket notation where the first element starts at index 0, the second element starts at index 1, and so on.

``````foo[0]  # 1st element
## 10
foo[1]  # 2nd element
## 20
``````

If we want to modify an element, say we want to change the 2nd element to 99, then we can just do

``````foo[1] = 99
print(foo)
## [10 99 30 40 50]
``````

Since we know `foo` has five elements, if we wanted to access the last element, we can do

``````foo[4]
## 50
``````

If we want to make that more dynamic, we can replace the index, 4, with `len(foo) - 1`

``````foo[len(foo) - 1]
## 50
``````

But we can make that even simpler with negative indexing. Just like python lists, the index -1 returns the last element in the array, -2 returns the second to last element, and so on.

``````foo[-1]
## 50
``````

And if we try to access an element outside the bounds of the array, we’ll get an “out of bounds” error.

``````foo[999]  # error: out of bounds
``````

If we want to access multiple elements at once, we can do that too, using a list or numpy array of indices. For example, we could do

``````foo[[0, 1, 4]]
## array([10, 99, 50])
``````

Or we could do

``````foo[[0,1,0,1]]
## array([10, 99, 10, 99])
``````

Notice, the indices don’t need to be unique. We could even pass in something like this.

``````foo[np.zeros(shape=3)]  # error
``````

Well, maybe not. The problem is that the `zeros()` function returns an array of floating point zeros by default, and indices need to be integers. So we make a slight tweak and set the `dtype` argument to int64 and we’re all good.

``````foo[np.zeros(shape=3, dtype='int64')]
## array([10, 10, 10])
``````

We can also use slicing just like python lists. The signature here is basically `foo[start index : end index : step size]`. And there are a lot of shorthands to this, so let’s look at some examples.

If we do `foo[:2]`, we get every element from the beginning of the array to index 2 exclusive.

``````foo[:2]
## array([10, 99])
``````

If we do `foo[2:]`, we get every element from index 2 to the end of the array.

``````foo[2:]
## array([30, 40, 50])
``````

And if we do `foo[::2]`, we get every other element from the beginning to the end. In other words we get the elements at indices 0, 2, 4, ….

``````foo[::2]
## array([10, 30, 50])
``````

Another thing we can do is modify multiple elements at once. For example,

``````foo[[0, 1, 4]] = [100, 200, 400]
print(foo)
## [100 200  30  40 400]
``````

In this case, our list of values needs to be the same size as our list of indices, unless we assign to a single value in which case it gets applied to every index. For example, if we do `foo[[0,1,4]] = [1,2]`, we’ll get a “shape mismatch” error.

But if we do `foo[[0,1,4]] = 77`, it gets assigned to each of those indices.

``````foo[[0,1,4]] = 77
print(foo)
## [77 77 30 40 77]
``````