Indexing and Slicing Arrays
Reviewed & published by Brayan K
Indexing and slicing are the ways you reach into a NumPy array to read or change specific elements — indexing grabs a single value by its position, while slicing pulls out a whole range with a start:stop:step pattern.
Part of the free NumPy course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll select single elements, use negative indices, slice 1D and 2D arrays, carve out sub-grids, and assign new values straight into a slice.
What You'll Learn in This Lesson
- Indexing single elements with arr[0]
- Using negative indices like arr[-1]
- Slicing ranges with arr[1:4] and arr[::2]
- Indexing 2D arrays with arr[row, col]
- Selecting whole rows and columns
- Assigning new values through a slice
1 Indexing a 1D Array
A one-dimensional array works just like a Python list: each element has a position called an index, and indices start at 0. Put the index in square brackets to read one value.
Negative indices count backwards from the end, so arr[-1] is the last element and arr[-2] is the second-to-last — handy when you don't know the length.
import numpy as np
arr = np.array([10, 20, 30, 40, 50])
print(arr[0]) # 10 -> first element
print(arr[2]) # 30 -> third element
print(arr[-1]) # 50 -> last element
print(arr[-2]) # 40 -> second to last
# ✅ Expected output:
# 10
# 30
# 50
# 40Expected output: 10, 30, 50, then 40.
2 Slicing: start:stop:step
A slice selects a range of elements using start:stop:step. The start is included, the stop is excluded, and step controls how many you skip.
import numpy as np
arr = np.array([0, 1, 2, 3, 4, 5, 6, 7])
print(arr[1:4]) # [1 2 3] -> index 1 up to (not including) 4
print(arr[:3]) # [0 1 2] -> from start to index 3
print(arr[5:]) # [5 6 7] -> from index 5 to the end
print(arr[::2]) # [0 2 4 6] -> every second element
print(arr[::-1]) # [7 6 5 4 3 2 1 0] -> reversed
# ✅ Expected output:
# [1 2 3]
# [0 1 2]
# [5 6 7]
# [0 2 4 6]
# [7 6 5 4 3 2 1 0]Expected output: [1 2 3], [0 1 2], [5 6 7], [0 2 4 6], and the reversed [7 6 5 4 3 2 1 0].
3 Indexing 2D Arrays: Rows and Columns
For a two-dimensional array you give two indices: arr[row, col]. Use a single index like arr[1] to grab a whole row, and a colon like arr[:, 0] to grab a whole column (the colon means "all rows").
import numpy as np
grid = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
print(grid[0, 0]) # 1 -> row 0, column 0
print(grid[1, 2]) # 6 -> row 1, column 2
print(grid[1]) # [4 5 6] -> the whole second row
print(grid[:, 0]) # [1 4 7] -> the whole first column
print(grid[-1, -1]) # 9 -> bottom-right element
# ✅ Expected output:
# 1
# 6
# [4 5 6]
# [1 4 7]
# 9Expected output: 1, 6, [4 5 6], [1 4 7], and 9.
4 Sub-Grids and Assigning Through Slices
Combine slices on both axes to cut out a rectangular sub-grid: arr[0:2, 1:3] takes rows 0–1 and columns 1–2. Because slices are views, you can also assign to them — arr[0:2] = 0 overwrites everything in those rows at once.
import numpy as np
grid = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
# Sub-grid: rows 0..1, columns 1..2
print(grid[0:2, 1:3])
# [[2 3]
# [6 7]]
# Assign through a slice — overwrite the whole first row
arr = np.array([10, 20, 30, 40, 50])
arr[0:2] = 0
print(arr) # [ 0 0 30 40 50]
# ✅ Expected output:
# [[2 3]
# [6 7]]
# [ 0 0 30 40 50]Expected output: the sub-grid [[2 3] [6 7]], then [ 0 0 30 40 50].
🎯 YOUR TURN: Fill in the Blanks
Replace each ___ so the program prints the last element, a middle slice, and the first column.
import numpy as np
arr = np.array([5, 15, 25, 35, 45])
print(arr[___]) # want the LAST element -> 45
print(arr[1:___]) # want [15 25 35] -> stop index goes here
grid = np.array([[1, 2],
[3, 4]])
print(grid[:, ___]) # want the FIRST column -> [1 3]Expected output: 45, [15 25 35], [1 3]. (Answers: -1, 4, 0.)
⚠️ Common Errors & Quick Reference
❌ IndexError: index 5 is out of bounds for axis 0 with size 5
You used an index that's past the end. A size-5 array has valid indices 0 through 4.
✅ Fix: use arr[-1] for the last element, or check arr.shape.
❌ Expected one column but got a single number
Writing arr[0] on a 2D array returns the whole first row, not a column.
✅ Fix: use arr[:, 0] — the colon keeps all rows and picks column 0.
| Task | Code |
|---|---|
| First / last element | arr[0] / arr[-1] |
| Slice a range | arr[1:4] |
| Every second element | arr[::2] |
| A whole row | arr[1] |
| A whole column | arr[:, 0] |
| Assign through slice | arr[0:2] = 0 |
🏆 Mini Challenge: Extract the Center
From a 4×4 grid, slice out the inner 2×2 block and then zero out the top row.
import numpy as np
grid = np.array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]])
# The inner 2x2 block: rows 1..2, columns 1..2
center = grid[1:3, 1:3]
print(center)
# [[ 6 7]
# [10 11]]
# Zero out the entire top row
grid[0] = 0
print(grid[0]) # [0 0 0 0]
# ✅ Expected output:
# [[ 6 7]
# [10 11]]
# [0 0 0 0]❓ Frequently Asked Questions
Lesson complete — you can navigate any array!
You can now index single elements, use negative indices, slice ranges with steps, reach into rows and columns of 2D arrays, carve out sub-grids, and assign values straight through a slice.
Practice quiz
What index does the first element of a NumPy array have?
- 0
- 1
- -1
- It varies
Answer: 0. NumPy indices are zero-based, so the first element is at index 0.
What does arr[-1] return?
- The first element
- An error
- The last element
- The middle element
Answer: The last element. Negative indices count from the end, so -1 is always the last element.
For arr = [0,1,2,3,4,5,6,7], what does arr[1:4] return?
- [1, 2, 3, 4]
- [1, 2, 3]
- [0, 1, 2, 3]
- [2, 3, 4]
Answer: [1, 2, 3]. Slicing includes start (1) and excludes stop (4): indices 1, 2, 3.
In a slice start:stop:step, which is true about stop?
- It is included
- It must be negative
- It is excluded
- It is the step size
Answer: It is excluded. The stop index is exclusive; the slice never includes the stop position.
What does arr[::2] do?
- Reverses the array
- Returns every second element
- Returns the first two elements
- Doubles each element
Answer: Returns every second element. A step of 2 takes every other element starting from the beginning.
For a 2D grid, what does grid[:, 0] select?
- The first row
- The whole first column
- The element (0,0)
- The last column
Answer: The whole first column. The colon means all rows, and 0 picks column 0: the whole first column.
Does a basic slice return a copy or a view?
- A copy
- A view that shares memory
- A new dtype
- Always an error
Answer: A view that shares memory. Basic slicing returns a view; writing to it changes the original array.
What does arr[::-1] return?
- The array unchanged
- Every second element
- The first half
- The array reversed
Answer: The array reversed. A step of -1 walks the array backwards, reversing it.
For grid = [[1,2,3],[4,5,6],[7,8,9]], what is grid[1, 2]?
- 6
- 2
- 8
- 4
Answer: 6. Row 1, column 2 (both zero-based) is the value 6.
How do you make an independent copy instead of a view?
- arr[:]
- arr.view()
- arr.copy()
- arr.slice()
Answer: arr.copy(). arr.copy() returns a separate array that does not share memory with the original.
Continue this course
- Previous: Array Attributes: shape, ndim, size
- Next: Boolean & Fancy Indexing — Select elements with masks and integer index arrays
- Quick reference: NumPy cheat sheet › Indexing & Slicing
Frequently asked questions
What is the difference between indexing and slicing?
Indexing uses a single position to pull out one element, like arr[0]. Slicing uses a start:stop:step range to pull out a whole section, like arr[1:4], and returns a smaller array rather than a single value.
Are NumPy indices zero-based?
Yes. The first element is at index 0, the second at index 1, and so on. Negative indices count from the end, so arr[-1] is always the last element.
Does slicing a NumPy array make a copy?
No — a basic slice returns a 'view' that shares memory with the original array. Writing to a slice changes the original. Use arr.copy() if you need an independent copy.
How do I select a whole column from a 2D array?
Use a colon for the rows and the column index, like arr[:, 0]. The colon means 'all rows', so this gathers the first value from every row into a 1D array.