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

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
# 40

Expected 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]
# 9

Expected 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.

TaskCode
First / last elementarr[0] / arr[-1]
Slice a rangearr[1:4]
Every second elementarr[::2]
A whole rowarr[1]
A whole columnarr[:, 0]
Assign through slicearr[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

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.