Lecture: Lists
Lecture script · about 15–20 minutes spoken · Week 9
Opening
Think about the grocery list on your phone. You add milk at the end, slip eggs in at the top, and cross off bread. Through all of that, it's one list with one name, and the list you see is the list you changed.
A biology major logs a week of plant heights. A small-business owner keeps orders in the order they came in. Each keeps a row of values under one name, and each needs to know whether a change shows up everywhere or only where they meant it.
So far in this course every value has lived in its own variable. Week 3 taught you to index and slice a string from 0. Weeks 5 and 6 taught you loops, counters, and accumulators. Week 7 taught you that a function with no return hands back None. Week 8 pulled it all together with the classic-bug checklist. In this lecture, one name starts holding many values, and every one of those earlier ideas comes back.
Here's the plan. We'll make and read a list, slice it, and walk it for a total, an average, and the biggest day. Then we'll change it in place and see what each change hands back. After that comes the surprise that trips up almost everyone, a second name for the same list, and we'll finish with a loop trap and a chatbot check.
1. Making a list: many values under one name
Picture a bus with numbered seats. You don't give each seat its own street address. You say "seat 3 on this bus." The bus is one name, and each seat is a numbered spot inside it.
That's a list. A list is an ordered collection of values kept under one name, written in square brackets with commas between the values, which a program can read by position and change after it is made. Each value inside has its own term. An item is one of the values stored in a list; each item sits at a numbered position, starting from 0 at the front.
Here's the reading log for this week. The list named daily holds seven numbers, the pages read on each day: 12, 40, 25, 0, 33, 17, and 27. Positions start at 0, exactly as they did in a string. So daily at index 0 is 12, the first day. Daily at index negative 1 counts back from the end and gives 27, the last day. The slice from 1 to 3 takes indexes 1 and 2 and gives a list holding 40 and 25. And the length of daily is 7.
Now reach one step too far. The pinned error program makes a list of three items, 12, 40, and 25, and asks for index 3. Nothing prints. The last line of the error names IndexError. The last index of a list with three items is 2, because counting starts at 0.
Pause and try this. The daily list holds 7 items. Why does asking for daily at index 7 raise IndexError instead of giving the last day?
Count the positions from 0, not from 1.
Here's the answer. Counting starts at 0, so the last index is always one less than the length, and index 7 is past the end. To reach the last day, 27, ask for index negative 1.
2. Slicing: every slice is a brand-new list
Think about a photocopy of a recipe page. You can scribble all over the copy, and the cookbook stays clean.
A slice of a list is that photocopy. It follows the same half-open rule you met with strings: it starts at its start index and stops before its stop index. What's new is that the slice is a separate list.
Here's the example. The program takes the slice of daily up to index 3 and names it first_three. That holds 12, 40, and 25. Then it changes first_three at index 0 to 50. When the program prints first_three, you get 50, 40, and 25. When it prints daily at index 0, you still get 12. The week itself was never touched.
The pinned to-do program ends with four slices of a list of tens: 10, 20, 30, 40, and 50. The slice from 1 to 3 gives 20 and 30. The slice up to 2 gives 10 and 20. The slice from 2 to the end gives 30, 40, and 50. And index negative 1 gives a single item, 50, printed with no brackets, because an index is one item and a slice is always a list.
Students often expect the slice from 1 to 3 to include index 3. It doesn't.
Pause and try this. In the list of tens, how many items does the slice from 1 to 3 hold, and which ones?
Subtract the start from the stop.
Here's the answer. It holds 2 items, 20 and 30. The stop 3 minus the start 1 is 2, so the slice takes indexes 1 and 2 and stops before index 3.
3. Walking a list: a total, an average, and the biggest
Picture a cashier adding up a receipt one line at a time, keeping a running total. Now picture a judge at a pie contest who remembers the best pie so far and swaps it out only when a better one comes along.
You already have both tools. Week 6's for loop hands you each item, and Week 5's accumulator starts at 0 and grows on every pass.
This is the reading log's stage for this week. The total starts at 0. A for loop walks daily and adds each day's pages. Then the program prints the total, 154. It divides the total by the length of daily and prints 22.0. Then a second loop keeps the biggest day. It starts the biggest at the first item, 12. When it meets 40, it swaps 12 out, and nothing later beats 40, so it prints 40. Last, it prints the length, 7.
Let's check the arithmetic out loud. Add 12, 40, 25, 0, 33, 17, and 27, and you get 154. Then 154 divided by 7 is 22.0, and it carries a point zero because true division always gives a float.
Here's the trap with the biggest-so-far. It's tempting to start it at 0. That works for the reading log, but think about a week of winter low temperatures, all below zero. No day ever beats 0, so the program reports 0, a temperature that never happened. Start at the list's own first item instead.
Pause and try this. The reading log printed 22.0 for its average. Why does that line carry a point zero instead of printing 22?
Think about which kind of division the program used.
Here's the answer. The program used true division, the single slash, which always gives a float. So 154 divided by 7 prints as 22.0, even though it divides evenly.
4. Changing a list: edits happen in place
Think about a whiteboard by the door that holds the household chores. You can rub out one chore and write another in its spot, add one at the bottom, or wedge one in at the top. It's still the same whiteboard.
That's the big difference between a list and a string. A change in place describes a change made to the existing list itself, so every name that points at that list sees the change, instead of a new list being built. The simplest change is index assignment, a statement that puts a new value at one position of a list, written as the list name, the position in square brackets, an equals sign, and the new value. A weather log holds 18, 21, and 19. Assign 23 to index 1, and the list holds 18, 23, and 19. Try the same move on a string, and Python raises TypeError.
The other changes are methods. A method is a function that belongs to a value and is called with a dot after that value, such as append after a list name, so it can read or change that particular value.
Here's the pinned to-do list. It starts with email and lunch. Append adds gym at the end. Insert at position 0 puts coffee at the front, and the list grows to four items. Pop at position 0 takes coffee back out and hands it back. Remove deletes the value gym, leaving email and lunch. Then the in test asks whether a value is one of the items: lunch is there, so True, and gym is gone, so False.
Pause and try this. The list held email and lunch when the program called insert at position 0 with coffee. Did coffee replace email, or did the list grow?
Picture the whiteboard with a chore wedged in at the top.
Here's the answer. The list grew. Insert makes room, so coffee went in at the front, email moved to position 1, and the list held four items. Index assignment is the move that replaces.
5. Return values: what each method hands back
When you return a library book, the desk hands you a receipt. When you drop a letter in a mailbox, you get nothing back. Both actions did something, but only one handed you a thing to keep.
List methods split the same way. Pop hands back the item it removed. Append, insert, remove, and sort change the list and hand back None. Sort is the list method that rearranges a list into order in place and hands back None, so assigning what it hands back to a name stores None.
Here's the pinned trap. A list named nums holds 3, 1, and 2. Then the program says nums gets nums dot sort, and prints nums. It prints None. The sort worked, then handed back None, and the assignment threw the sorted list away.
The cure has a name. Sorted() is the built-in function that builds and hands back a new list holding the items in order, leaving the original list exactly as it was. In the pinned program, sorted of nums prints 1, 2, 3, while nums itself still prints 3, 1, 2.
Two more pairs. Append adds one item, even a whole list, so appending the list 3, 4 onto 1, 2 gives three items. Extend is the list method that adds every item of another list, one by one, to the end of a list in place and hands back None, so extending gives four items. And remove searches by value: on the list 5, 2, 9, 2, remove 2 deletes the first 2 and leaves 5, 9, 2.
Pause and try this. A program prints whatever append hands back after adding gym to a list. What does it print?
Ask whether append is a receipt or a mailbox.
Here's the answer. It prints None. Append changes the list in place and hands back nothing, so the printed value is None, even though gym really was added.
6. Aliases and copies: identity versus equality
Think about a shared online document with one link. If a friend fixes a typo, you see the fix too, because there was only ever one document. A downloaded copy is different. Their edits never reach yours.
Lists behave like that shared link. An alias is a second name for the very same object, made by an assignment such as b gets a, so a change made through either name shows up through the other. A copy is a separate new list holding the same items as another, made with a full slice such as a colon slice of a, so later changes to one list leave the other untouched.
In the pinned program, a holds 1, 2, 3. Then b gets a, and the program appends 4 through b. Print a, and you see 1, 2, 3, 4. The second half uses the full slice instead, so b is a new list, and a stays 1, 2, 3.
There's a test for this. Is is the operator that gives True only when the names on both sides point at one and the same object, which is a stricter test than equal contents. Two lists built separately, each holding 1 and 2, are equal, so double equals gives True. But they're two lists, so is gives False. In this course you compare values with double equals and save is for the question "is this the very same object?"
Pause and try this. A roster holds Ana and Kofi. The program sets backup to roster with a plain assignment, then appends Mei to roster. What does backup hold?
Ask whether backup is a shared link or a downloaded copy.
Here's the answer. Backup holds Ana, Kofi, and Mei. The plain assignment made an alias, so the append through roster shows up through backup. A full slice would have kept the backup at two names.
7. The mutate-while-iterating trap: never edit the list you walk
Picture a teacher walking down a row of desks, tapping each one. Halfway along, a student leaves, and everyone behind slides one seat forward. The teacher steps on to the next desk and skips the student who slid into the empty seat.
That's the mutate-while-iterating trap: the bug that comes from adding or removing items in a list while a for loop is walking that same list, which makes the loop skip items. Walking a copy or building a new list avoids it.
Here's the pinned trap, told as a practice log. The list holds the minutes practiced on five days: 0, 0, 90, 0, and 85. The loop walks the list, and every time it sees a 0, it removes a 0. You might expect only 90 and 85 to survive. The run prints 90, 0, and 85. One 0 got away, because each removal slid the later items left under the loop, and the loop stepped right past one.
There are two cures. Walk a copy, using the full slice in the for line, and the run prints 90 and 85. Or start from an empty list and append only the items worth keeping, and the run prints 90 and 85 as well.
Pause and try this. The trap ran with no error message at all. Is it a syntax error, a runtime exception, or a logic error?
Think about whether the program finished, and whether its output was right.
Here's the answer. It's a logic error. The program ran to the end with no exception, but it printed the wrong list, 90, 0, and 85, instead of 90 and 85.
8. Checking a chatbot: run the claim about a list
A friend tells you a shared link is a private copy. You don't argue. You open it and check.
Suppose you ask a chatbot how to back up a list before changing it. It answers, with confidence, that b gets a makes a copy, so a stays 1, 2, 3. Run the pinned program that tests that claim: a holds 1, 2, 3, b gets a, and the program appends 4 through b. The run prints 1, 2, 3, 4 for a. The claim was wrong. B gets a made an alias, not a copy, and the fix is the full slice.
A chatbot predicts likely text. It doesn't run your program. Your run is the evidence.
Pause and try this. After the chatbot's version runs, does the test a is b give True or False?
Ask how many lists the program built.
Here's the answer. It gives True. The program built only one list, and a and b are two names for it, so is reports the very same object.
Closing
Let's pull it together. A list keeps many values, in order, under one name, and you read it from 0 at the front or from negative 1 at the back. A slice is a brand-new list. A total starts at 0, and a biggest-so-far starts at the first item. Changes happen in place, through index assignment, append, insert, pop, and remove. Pop hands back an item, while the other changers and sort hand back None, and sorted builds a new list. A plain assignment makes an alias, and a full slice makes a copy. Never edit the list your loop is walking. And when a chatbot makes a claim about a list, run it.
Next in this module come the slide deck, the Readings and Resources page, the lecture tutorial, the practice set, and the quiz, followed by the discussion, the assignment, and the Coding Lab. Next week, in Tuples, Dictionaries and Sets, you'll meet three more containers and learn how to choose the right one.
Built with The Course Maker · samples.thecoursemaker.com