Concepts / Working with Lists and Indexing

Working with Lists and Indexing

We can access the items in the tuple by specifying the item's position within a pair of square brackets just like we did for lists. This is called the indexing operator. We access the third item in new_zoo by specifying new_zoo[2] and we access the third item within the third item in the new_zoo tuple by specifying new_zoo[2][2] . This is pretty simple once you've understood the idiom.

  • Programming

What Indexing Means

When you create a list or tuple, you store multiple items in a single container. But how do you get one specific item back out? You use the indexing operator: square brackets with a number inside. This number tells Python exactly which item you want. Think of it like a mailbox with numbered slots—to get the letter from slot 3, you open slot 3. In Python, you write the container's name, then the slot number in square brackets, and Python hands you back what's stored there.

The indexing operator is the square bracket notation: container[index]. It retrieves the item at that index position.

Zero-Based Indexing: Why Position 1 Is Index 0

Python counts positions starting from zero, not one. This is called zero-based indexing. The first item in a list is at index 0, the second item is at index 1, the third item is at index 2, and so on. This might feel backwards at first, but it's a standard convention in most programming languages. Understanding this mapping is crucial: when you want the third item, you do not use 3—you use 2.

First ItemIndex 0Second ItemIndex 1Third ItemIndex 2Fourth ItemIndex 3
Why do we use 2 to access the third item, and how does the numbering system work?

Imagine a row of books on a shelf. If you number the positions starting from 1 (first book, second book, third book), you are using human counting. But if you number them starting from 0 (book at position 0, book at position 1, book at position 2), you are using programming counting. When someone asks for the third book, you reach for the book at position 2. Python always uses programming counting.

Single-Level Indexing in Action

Let's say you have a tuple called new_zoo that contains animal names. To access the third item in new_zoo, you write new_zoo[2]. Python looks at the tuple, counts from zero, and returns the item at position 2 (the third position). This is straightforward once you remember that indexing starts at zero.

Accessing a Single Item from a Tuple

You have a tuple new_zoo = ('lion', 'tiger', 'bear', 'elephant'). What does new_zoo[2] return?

Count the positions starting from zero: Index 0 is 'lion', index 1 is 'tiger', index 2 is 'bear', index 3 is 'elephant'.

Locate the item at index 2: The item at index 2 is 'bear'.

new_zoo[2] returns 'bear'

Nested Indexing: Accessing Items Within Items

Sometimes a list or tuple contains other lists or tuples inside it. When you want to access an item deep inside this nested structure, you chain indexing operations together. You write the first index in brackets to access the inner container, then immediately write another index in brackets to access the item within that inner container. For example, new_zoo[2][2] means: first, get the item at index 2 of new_zoo (which is itself a container), then get the item at index 2 of that inner container.

Nested indexing chains bracket operations: container[index1][index2] first accesses the item at index1, then accesses the item at index2 within that result.

first [2] retrieves this tuplethen [2] retrieves this itemnew_zoo[0]('lion', 'big', 'Africa')new_zoo[2][0]'bear'new_zoo[1]('tiger', 'striped','Asia')new_zoo[2][1]'brown'new_zoo[2]('bear', 'brown', 'forest')new_zoo[2][2]'forest'
What does it mean to index into an item that is itself indexable, and how do the bracket operations chain together?

Accessing a Nested Item

You have new_zoo = (('lion', 'big', 'Africa'), ('tiger', 'striped', 'Asia'), ('bear', 'brown', 'forest')). What does new_zoo[2][2] return?

Apply the first index [2]: new_zoo[2] accesses the third item of new_zoo, which is the tuple ('bear', 'brown', 'forest').

Apply the second index [2] to that result: Now we have ('bear', 'brown', 'forest')[2], which accesses the third item of this inner tuple.

Identify the final item: The third item (index 2) of ('bear', 'brown', 'forest') is 'forest'.

new_zoo[2][2] returns 'forest'

How Indexing Works with Different Container Types

The indexing operator works the same way for lists, tuples, and other indexable containers. Whether you are working with a list or a tuple, you use the same bracket notation to access items by position. The indexing operator is a universal way to retrieve items from any ordered container in Python. This consistency makes it easy to switch between different container types without learning new syntax.

The indexing operator works identically for lists, tuples, and other sequence types. The syntax and behavior are the same regardless of container type.

Common Mistakes with Indexing

  • Using 1 to access the first item instead of 0

    Python uses zero-based indexing. Index 0 is the first item, index 1 is the second item. Using 1 gives you the second item, not the first.

    Fix: Use my_list[0] to access the first item.

  • Forgetting that indexing starts at zero

    If a list has 5 items, their indices are 0, 1, 2, 3, and 4. Index 5 does not exist, so Python raises an IndexError.

    Fix: Remember that the last index is always one less than the length of the list. For a 5-item list, use indices 0 through 4.

  • Misunderstanding nested indexing order

    Nested indexing requires separate bracket pairs for each level. The comma syntax is used for tuples, not for chaining index operations.

    Fix: Use container[2][2] with two separate bracket pairs, not a comma.

  • Assuming the indexing operator works on dictionaries the same way

    Dictionaries use keys, not positions. You cannot access a dictionary item by numeric position; you must use the key.

    Fix: Use the key to access dictionary items: dict[key_name].

The Indexing Operator in Practice

When you write code that uses indexing, always double-check your index value. Remember that the first item is at index 0, not index 1. If you are accessing a nested structure, trace through the indexing step by step: first apply the outer index, see what you get, then apply the inner index to that result. This mental walkthrough prevents mistakes. Also, be aware that if you try to access an index that does not exist, Python will raise an IndexError. Always make sure your index is within the valid range for that container.

Practice: Apply Your Indexing Knowledge

MEDIUM

Given the tuple data = (10, 20, (30, 40, 50), 60), what does data[2][1] return? Work through it step by step: first identify what data[2] is, then identify what index 1 of that result is.

Hints
  • Start by finding data[2]. What is at index 2 of the outer tuple?
  • Once you have that inner tuple, find the item at index 1 within it.
  • Remember that index 1 is the second item.
MEDIUM

Create a mental model of this structure: animals = (('cat', 'pet'), ('dog', 'pet'), ('lion', 'wild')). Without running code, predict what animals[1][0] returns and explain your reasoning.

Hints
  • What is at index 1 of the outer tuple?
  • What is at index 0 of that inner tuple?
  • Trace through the indices carefully.

Summary

You now understand how indexing works in Python. The indexing operator—square brackets with a number inside—retrieves items from lists, tuples, and other containers. Python uses zero-based indexing, so the first item is at index 0, the second at index 1, and so on. When containers are nested, you chain indexing operations together by writing multiple bracket pairs in sequence. Each bracket pair applies to the result of the previous operation. Always remember to count from zero, verify that your index is within the valid range, and trace through nested indexing step by step to avoid mistakes.

Key Takeaways

  • The indexing operator uses square brackets to access individual items in lists and tuples by their position.
  • Python uses zero-based indexing: the first item is at index 0, the second at index 1, and so on.
  • Nested indexing chains bracket operations together: container[index1][index2] first accesses the item at index1, then accesses the item at index2 within that result.
  • The indexing operator works identically for all sequence types (lists, tuples, etc.), making it a universal way to retrieve items.
  • Common mistakes include using 1 for the first item, forgetting that indices start at zero, and misunderstanding how nested indexing chains together.