Collections of Data

📋 Lists & Iteration: Storing and Processing Multiple Values

Master lists - the most important data structure for handling multiple values

🧠 Mental Model: Lists as Ordered Containers

The Shopping Cart Metaphor

Think of lists as shopping carts that can hold multiple items in a specific order:

  • Ordered - Items have specific positions (index 0, 1, 2...)
  • Mutable - You can add, remove, or change items
  • Indexed - Access any item by its position number
  • Dynamic - Can grow or shrink as needed
  • Mixed types - Can hold different kinds of data

List Structure Visualization

fruits = ["apple", "banana", "orange", "grape"]
0
"apple"
1
"banana"
2
"orange"
3
"grape"

fruits[0] = "apple" | fruits[2] = "orange" | fruits[-1] = "grape"

Interactive List Builder

Create and explore your own list:

Your list will appear here

🔄 Metaphor Evolution: From Boxes to Name Tags

🧠 Why Our Mental Model Must Evolve

Remember when we learned about variables as "labeled boxes"? That metaphor worked perfectly for numbers and strings (immutable types). But now with lists (mutable types), we need a more sophisticated understanding.

📦 Simple Types: "Labeled Box"

x = 5 puts the value 5 inside a box labeled 'x'

y = x copies the value to a new box labeled 'y'

🏷️ Mutable Types: "Name Tags"

list1 = [1, 2, 3] puts a name tag on a list object

list2 = list1 puts a second name tag on the SAME object

🎮 Name Tag Visualization

Imagine a list object floating in memory. Variables are like name tags attached to it:

List Object in Memory
[1, 2, 3]
list1 🏷️
list2 🏷️

Both list1 and list2 are name tags on the same object!
Changes through either name affect both because they reference the same object.

⚠️ Critical Pitfall: List References

The #1 List Mistake: Confusing Name Tags with Copying

Dangerous assumption: Thinking that list2 = list1 creates a copy. It doesn't! Using our new "name tag" metaphor: it just puts a second name tag on the same list object. This is why our mental model had to evolve from "labeled boxes" to "name tags."

❌ This Shares the List

list1 = [1, 2, 3]
list2 = list1        # Same list!
list2.append(4)
print(list1)         # [1, 2, 3, 4] 😱

Both variables point to the same list object

✅ This Creates a Copy

list1 = [1, 2, 3]
list2 = list1.copy() # New list!
list2.append(4)
print(list1)         # [1, 2, 3] ✅

Two separate list objects with same values

Reference vs Copy Demo

Click a demo button to see the difference

🔧 Essential List Methods

Lists come with powerful built-in methods for adding, removing, and organizing data. Think of these as different tools for managing your shopping cart:

.append()

Add item to end

items.append("new item")

Most common way to add items

.insert()

Add item at position

items.insert(1, "new item")

Insert at specific index

.remove()

Remove by value

items.remove("apple")

Removes first occurrence

.pop()

Remove and return

last = items.pop()

Remove last item (or by index)

.sort()

Organize in order

items.sort()

Sorts the list in place

len()

Count items

count = len(items)

Returns number of items

List Methods Playground

Start with: ["apple", "banana", "cherry"]

Current list: ["apple", "banana", "cherry"]
Click a method button to see it in action

🔄 Iterating Through Lists

🧠 Two Ways to Process Every Item

Think of processing a list like checking each item in your shopping cart at checkout:

  • For-each style: "For each item in the cart, scan it" (most common)
  • Index style: "Check position 0, then 1, then 2..." (when you need position)

Iteration Patterns

👍 For-Each (Recommended)

fruits = ["apple", "banana", "cherry"]

for fruit in fruits:
    print(f"I like {fruit}")

# Output:
# I like apple
# I like banana  
# I like cherry

✅ Clean, readable, less error-prone

📍 Index-Based (When Needed)

fruits = ["apple", "banana", "cherry"]

for i in range(len(fruits)):
    print(f"{i}: {fruits[i]}")

# Output:
# 0: apple
# 1: banana
# 2: cherry

⚠️ Use only when you need the index

Click a demo button to see iteration in action

🎯 Mastery Check: Lists & Iteration

Question 1: List References

What happens after this code runs?

list1 = [1, 2, 3]
list2 = list1
list2.append(4)
print(len(list1))

Prints 4 (list1 and list2 share the same list)

Prints 3 (list1 is unchanged)

Causes an error

Question 2: Best Iteration Pattern

What's the best way to print all items in a list called names?

for name in names: print(name)

for i in range(len(names)): print(names[i])

Both are equally good

Question 3: List Indexing

What does this code output?

fruits = ["apple", "banana", "cherry"]
print(fruits[-1])
print(fruits[1:3])

cherry
['banana', 'cherry']

apple
['banana', 'cherry']

cherry
['apple', 'banana']

Question 4: List Methods

After this code runs, what does numbers contain?

numbers = [3, 1, 4, 1, 5]
numbers.append(9)
numbers.remove(1)
numbers.sort()

[1, 3, 4, 5, 9]

[3, 4, 5, 9]

[9, 5, 4, 3, 1]

Question 5: List vs String

What's the key difference between these two approaches?

# Approach A
word = "hello"
word[0] = "H"  # Try to change first letter

# Approach B
letters = ["h", "e", "l", "l", "o"]
letters[0] = "H"  # Change first letter

A causes error (strings immutable), B works (lists mutable)

Both work the same way

A works, B causes error

🎯 Ready for Code Recipes!

What You've Mastered

  • ✅ Lists as ordered, mutable containers (shopping cart model)
  • ✅ List indexing and slicing (accessing specific items)
  • ✅ Critical list reference behavior (.copy() vs assignment)
  • ✅ Essential list methods (.append(), .remove(), .pop(), etc.)
  • ✅ Iteration patterns (for-each vs indexed)

Now that you can store and process collections of data, let's learn how to organize your code into reusable functions!

Continue to Code Recipes →