South Plantation High School logo
South Plantation High School · Procedural Programming with Python

List Methods & Functions

append, insert, index, remove · len, sorted, min, max, del · Reversing & merging · List comprehensions · Lesson review

Review the lesson slides, then complete the assignment at the bottom of this page. Your assignment work is saved in this browser on this computer. When you check a task, your name, period, and which tasks are complete are shared with your teacher (your code is not). When you finish, print it or save it as a PDF to turn in.
1 / 17
Lesson Review

List Methods & List Functions

.append().insert().remove()len()sorted()del[n * 2 for n in nums]

Add, find, remove, sort, reverse, and merge list items, then build new lists in one line.

By the end of this lesson you will be able to:

  • Change lists with the methods append, insert, index, remove, and others like pop and count.
  • Use the functions len, sorted, min, and max, and the del statement.
  • Reverse a list with .reverse() or reversed(), and merge two lists with + or .extend().
  • Write a basic list comprehension to build a new list.
How to use this page: Use Next and Back (or the arrow keys). Run the editors, try methods one at a time in the List Lab, and build your own list comprehensions in the Comprehension Builder.

Words you will hear today

WordWhat it meansExample
methodA function that belongs to a value, called with a dotnums.append(5)
argumentThe value you put in the parenthesesthe 5
return valueWhat a function or method gives backlen(nums) gives a number
in placeChanges the original list instead of making a new onenums.sort()
NonePython's value for "nothing"what nums.sort() returns
list comprehensionA one-line way to build a new list from another[n * 2 for n in nums]
  • Methods change a list. Functions report on a list. Comprehensions build a new list.
  • In place = changes the original. None = nothing returned.

Last time we made lists and pulled items out with indexes and slices. Today we change lists: adding, finding, removing, sorting, reversing, and combining. At the end, we learn a short way to build a whole new list in one line, called a list comprehension.

Big Idea

Methods versus functions

MethodFunction
How you write itnums.append(5)
list name, a dot, the method
len(nums)
the list goes inside the parentheses
Belongs tothe listPython (works on many types)
Today's toolsappend insert index remove pop count sort reverse extend clearlen sorted min max sum reversed

And one statement: del nums[0] (no parentheses, no dot).

Big trap: methods that change a list return None. The Python tutorial says methods "like insert, remove or sort that only modify the list have no return value printed – they return the default None."
nums = [3, 1, 2]
nums.sort()          # correct: sorts nums in place
print(nums)          # [1, 2, 3]

nums = nums.sort()   # wrong: nums is now None!
print(nums)          # None
Rule of thumb: call a changing method on its own line. Do not store its result.

Two questions to ask about any tool

  1. Does it change the list? (append, insert, remove, pop, sort, reverse, extend, clear, del)
  2. Does it give something back? (len, min, max, sum, sorted, index, count, and pop)

Most tools do only one of these. pop() is special: it does both. It removes an item and hands it back to you.

Why do changing methods return None? It is a deliberate reminder from Python's designers. If sort() returned the list, you might think it made a new copy. Returning None makes it clear that the original list is the one that changed.

  • Method: list.method(). Function: function(list).
  • Changing methods return None.
  • Ask: does it change the list, or give something back?

There are two kinds of tools today. Methods are attached to the list with a dot, and most of them change the list itself. Functions like len take the list inside the parentheses and give you back an answer. The number one bug with methods is saving their result: methods that change a list give back None.

Adding Items

.append(x): add to the end

The tutorial: "Add an item to the end of the list."

cart = []                # start empty
cart.append("apple")     # ['apple']
cart.append("bread")     # ['apple', 'bread']
  • Great for building a list one item at a time, often inside a loop.
  • append takes exactly one item. cart.append("a", "b") gives TypeError: list.append() takes exactly one argument (2 given).
  • If you append a list, it goes in as one item: a list inside your list.

Step through and watch cart grow. Then change the last item to a list and see what happens to the length.

The "build a list in a loop" pattern

squares = []                 # 1. start empty
for n in range(1, 6):
    squares.append(n * n)    # 2. add one item each time
print(squares)               # 3. use it after the loop
# [1, 4, 9, 16, 25]

This is the list version of the accumulator pattern. The empty list goes before the loop; if it were inside, it would be emptied every time.

Collecting user input: the same pattern can gather several answers: names.append(input("Name: ")) inside a loop.

  • append adds one item to the end.
  • Appending a list nests it.
  • Empty list before the loop, append inside, use after.

Append is the method you will use most. It always adds to the end. Watch the variables panel as each line runs. Then try appending a list: the length only goes up by one, because the whole list becomes a single item.

Adding Items

.insert(i, x): add at a position

The tutorial: "The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x)."

CallWhere "Dee" goes
seats.insert(0, "Dee")the very front
seats.insert(1, "Dee")before the item at index 1
seats.insert(-1, "Dee")before the last item (not at the end!)
seats.insert(len(seats), "Dee")the end (same as append)
seats.insert(10, "Dee")the end (no error for a big index)
The index comes first, then the item: insert(where, what).

What happens to the other items?

When you insert, every item from that position onward shifts one place to the right, and their indexes go up by 1. Starting from ["Ava", "Ben", "Cy"], after seats.insert(1, "Dee"):

index:   0      1      2      3
before: Ava    Ben    Cy
after:  Ava    Dee    Ben    Cy

Ben moved from index 1 to index 2. If your program saved "Ben is at index 1" earlier, that information is now out of date.

  • insert(index, item): the new item lands before that index.
  • insert(-1, x) does not add at the end.
  • insert shifts every later item one place to the right.

Insert lets you choose where the new item goes. The number is the index the new item will have, so everything from that spot shifts one place to the right. Try negative one: many students expect the end of the list, but the item lands just before the last item.

Finding Items

.index(x) and .count(x): find items

  • list.index(x) gives the index of the first item equal to x. The tutorial: it "Raises a ValueError if there is no such item."
  • list.count(x) gives how many times x appears (0 if it is not there, no error).
  • Check with in before calling index to avoid the error.
planets = ["Venus", "Earth", "Mars", "Earth"]
print(planets.index("Earth"))   # 1  (the first one)
print(planets.count("Earth"))   # 2
print(planets.index("Pluto"))   # ValueError: 'Pluto' is not in list

Pick an item to search for. The if on line 3 makes the program safe, but line 7 calls index without checking.

Using in as a safety check

if "Pluto" in planets:
    print(planets.index("Pluto"))
else:
    print("Pluto is not in the list")

This "look before you leap" pattern means index() is only called when it is sure to work.

count() is also a quick yes/no check: planets.count("Earth") > 0 is True when Earth appears at least once, though in reads more clearly for that.

Only the first match: with duplicates, index() always reports the earliest one. Earth is at both 1 and 3, but index("Earth") gives 1.

  • index: first match, ValueError if missing.
  • count: how many, never an error.
  • Check with in before calling index().

Index answers the question: where is it? Count answers: how many are there? Notice that index only reports the first match, even when the item appears twice. If the item is missing, index crashes your program, so check with in first.

Removing Items

Removing: .remove(), .pop(), and del

ToolRemoves byGives backIf it fails
nums.remove(30)value (the first match)NoneValueError: list.remove(x): x not in list
nums.pop()position (the last item)the removed itemIndexError: pop from empty list
nums.pop(0)indexthe removed itemIndexError: pop index out of range
del nums[1]indexnothing (it is a statement)IndexError: list assignment index out of range
del nums[1:3]a slicenothingnever (slices are forgiving)

The tutorial on del: "There is a way to remove an item from a list given its index instead of its value: the del statement. This differs from the pop() method which returns a value."

Which one? Know the value? Use remove. Know the position and need the item? Use pop. Know the position (or a slice) and do not need the item? Use del.

Using the item pop() gives back

to_do = ["wash dishes", "homework", "walk dog"]
task = to_do.pop(0)          # take the first task off the list
print("Now doing:", task)    # Now doing: wash dishes
print(to_do)                 # ['homework', 'walk dog']

This is how a waiting line works in a program: take the first item off, handle it, and repeat.

remove() only removes the first match. With [10, 30, 20, 30], remove(30) leaves the second 30. To remove every 30, build a new list: [n for n in nums if n != 30].

Don't remove while looping over the same list. When an item is removed, the others shift left, and the loop skips the next one. Looping through [1, 2, 2, 3] and removing each 2 leaves [1, 2, 3]. Build a new list instead.
  • remove = by value. pop = by index, returns item. del = by index or slice.
  • pop returns the removed item.
  • Never remove items from a list while looping over it.

There are three ways to take things out of a list, and the difference is what you know. If you know what the item is, use remove. If you know where it is, use pop or del. Pop hands the item back to you, which is handy when you want to use it, like dealing the top card off a deck.

List Functions

len(), min(), max(), and sum()

FunctionGives[72, 95, 88, 64]
len(scores)number of items4
min(scores)smallest item64
max(scores)largest item95
sum(scores)total of all items319
sum(scores) / len(scores)the average79.75
  • min and max also take separate values: min(4, 2, 8) is 2.
  • On strings they compare alphabetically by character code, so every capital letter comes before every lowercase letter: min(["kiwi", "apple", "Banana"]) is 'Banana'.
  • An empty list has no smallest item: max([]) gives ValueError: max() iterable argument is empty.

Computing the average safely

An average divides by the length, so an empty list would cause ZeroDivisionError. Check first:

if len(scores) > 0:
    average = sum(scores) / len(scores)
    print("Average:", round(average, 1))
else:
    print("No scores yet.")

sum() only works on numbers. sum(["a", "b"]) is a TypeError. To join strings, use "".join(...) instead.

These are functions, not methods: write len(scores), not scores.len().

  • len, min, max, sum. Average = sum / len.
  • Empty list: min/max error. Strings: capitals first.
  • Check len() > 0 before dividing for an average.

These functions answer questions about a list without changing it. How many? What is the smallest? The largest? The total? Put sum and len together and you have the average. Try the list of words: the answer for min might surprise you, because capital letters come before all lowercase letters.

Sorting

.sort() versus sorted()

nums.sort()sorted(nums)
Kindmethodfunction
Changes nums?Yes, in placeNo
Gives backNonea new sorted list
Largest firstnums.sort(reverse=True)sorted(nums, reverse=True)
Use sorted() when you want to keep the original order too. Use .sort() when you no longer need the original order.
Python cannot compare numbers with strings: sorted(["b", 2]) gives TypeError: '<' not supported between instances of 'int' and 'str'.

Sorting words without the capital-letter problem

Because capitals come before lowercase, sorted(["kiwi", "apple", "Banana"]) gives ['Banana', 'apple', 'kiwi']. To sort the way a dictionary does, tell Python to compare lowercase versions:

sorted(["kiwi", "apple", "Banana"], key=str.lower)
# ['apple', 'Banana', 'kiwi']

The key= option means "compare using this," but the original words (with their capitals) are kept in the result.

Picking the right one: a high-score table that should always stay in order? .sort(). Showing a sorted view but keeping the order players joined? sorted().

  • sort(): in place, returns None.
  • sorted(): new list, original untouched.
  • key=str.lower sorts words ignoring capitals.

Both put items in order, smallest to largest. The difference is whether your original list changes. Sort rearranges the list itself. Sorted makes a new sorted copy and leaves the original alone. Try the last option to see the None bug from earlier.

Reversing

Reversing: .reverse() versus reversed()

WayChanges the list?Gives back
nums.reverse()Yes, in placeNone
reversed(nums)Noa reverse iterator (not a list)
list(reversed(nums))Noa new reversed list
nums[::-1]Noa new reversed list (from last lesson)
What is an iterator? Something that hands out items one at a time, like a ticket dispenser. A for loop can use it directly: for n in reversed(nums):. To see it as a list, wrap it in list(). And like a ticket roll, it can only be used up once.
print(reversed(nums)) shows something like <list_reverseiterator object at 0x...>, not the items. (The number after 0x is a memory address and changes every run.)

Three ways, one decision

  • Want the list itself flipped for good? nums.reverse()
  • Want to loop backward once without changing anything? for n in reversed(nums):
  • Want a new reversed list to keep? nums[::-1] or list(reversed(nums))

An iterator gets used up. If you save r = reversed(nums), then list(r) works the first time but gives [] the second time. Call reversed() again when you need it again.

reverse is not sort: .reverse() just flips the current order. To get largest-first, use sort(reverse=True).

  • reverse(): in place. reversed(): iterator; wrap in list() to see it.
  • [::-1] also works.
  • reversed() can be used up only once.
  • reverse flips; sort(reverse=True) orders largest first.

Reverse with no d at the end is a method: it flips the list itself. Reversed with a d is a function that gives you the items back in reverse order, one at a time. If you print it directly, you just see a description of the object, not the items. Wrap it in list to see them.

Merging

Merging two lists: + versus .extend()

CodeResultChanges a?
both = a + ba new list with all itemsNo
a.extend(b)adds every item of b to the end of aYes
a += bsame as a.extend(b)Yes
a.append(b)adds b as one item (a nested list)Yes (but probably not what you wanted)

The tutorial: extend will "Extend the list by appending all the items from the iterable."

[1, 2] + 3 gives TypeError: can only concatenate list (not "int") to list. Put the number in a list: [1, 2] + [3].

See the difference

a = [1, 2]
a.append([3, 4])
print(a, len(a))     # [1, 2, [3, 4]] 3

a = [1, 2]
a.extend([3, 4])
print(a, len(a))     # [1, 2, 3, 4] 4

The length tells the story: append added one item (a whole list), while extend added each item separately.

When to use +: when you need both original lists unchanged, for example combining two class rosters into a school list while keeping each class list as it was.

  • + makes a new list. extend changes the first list.
  • append(list) nests; extend(list) merges.
  • append adds 1 item; extend adds each item.

To combine two lists, plus builds a brand new list and leaves both originals alone. Extend pours the second list into the first one. Compare extend with append in the editor: extend adds two items, while append adds one item that happens to be a list.

Practice

List Lab: try every method

Pick a method, fill in the value or index, and click Run. Each line runs on the same list, so you can build up a history. Put text in quotes, like "kiwi". Nothing is recorded.

Questions to answer in the lab

  • After insert(0, ...), what happened to every other item's index?
  • Which methods showed a value when you ran them, and which showed None?
  • What error do you get if you remove something that is not there? How would you prevent it?
  • Can you get the list back to its original order using only sort and reverse?
  • Predict the list before each Run.
  • Notice which methods give back a value and which give None.

This is your sandbox. Before you click Run, say out loud what the list will look like afterward. Try to cause each error on purpose too: remove something that is not there, pop from an empty list, or ask for the index of a missing item.

List Comprehensions

List comprehensions: a new list in one line

The tutorial: "List comprehensions provide a concise way to create lists."

The long way: a loop and append
doubled = []
for n in nums:
    doubled.append(n * 2)
The comprehension: same result, one line
doubled = [n * 2 for n in nums]
[n * 2what to put in the new listfornthe name for each iteminnumswhere items come from]

Pick a comprehension. The editor runs the long way and the comprehension, so you can see they match.

How to read a comprehension

Start in the middle, then go to the front:

  1. for n in nums: "take each n from nums..."
  2. n * 2: "...and put n × 2 in the new list."

The square brackets on the outside tell you the result is a list.

More examples

ComprehensionResult
[n * n for n in range(1, 5)][1, 4, 9, 16]
[w.upper() for w in ["hi", "yo"]]['HI', 'YO']
[len(w) for w in ["cat", "horse"]][3, 5]

The original list is never changed. A comprehension always makes a new list.

  • [expression for item in iterable]
  • Read it as: "n times 2, for each n in nums."
  • Read a comprehension from the for, then the expression.

A list comprehension is a shortcut for a very common pattern: start with an empty list, loop through something, and append a result each time. Read it out loud like a sentence: n times two, for each n in nums. The part before for is what goes into the new list.

List Comprehensions

Adding an if to filter

The tutorial: a list comprehension has "brackets containing an expression followed by a for clause, then zero or more for or if clauses."

The long way
passing = []
for s in scores:
    if s >= 70:
        passing.append(s)
The comprehension
passing = [s for s in scores if s >= 70]
The if goes at the end. Only items that make the condition True get into the new list. The original list does not change.

Two different "if"s

An if at the end filters: it decides which items get in. To change every item based on a condition, put an if/else at the front instead:

[s for s in scores if s >= 70]                    # keep only passing scores
["pass" if s >= 70 else "fail" for s in scores]   # label every score

The first can give a shorter list. The second always gives a list the same length as scores.

When to skip comprehensions: if the logic needs several steps or is hard to read in one line, a normal loop with append is perfectly good code.

  • [expression for item in iterable if condition]
  • The if keeps only matching items.
  • if at the end filters; if/else at the front transforms.

Add an if at the end and the comprehension becomes a filter. Read it as: s, for each s in scores, if s is at least 70. Try the last option: it filters and changes the values at the same time, adding a five point curve to the scores below 70.

Practice

Comprehension Builder

Fill in the parts and click Build. You will see your comprehension, the loop it replaces, and the result of both. Try the challenges below the builder. Nothing is recorded.

Hints for the challenges

  • Squares of 1 to 10: the source is range(1, 11); the expression is the item times itself.
  • Words longer than 3 letters: the expression is just the word; the filter uses len().
  • Even numbers only: the filter uses %. An even number has a remainder of 0 when divided by 2.
  • Challenges: squares of 1-10, words longer than 3 letters, even numbers only.

Now you write them. Start with the challenges. For the squares, the expression is n to the power of two and the source is range one to eleven. For the long words, the variable is w, and the condition uses len.

Debugging

Common mistakes

MistakeCodeWhat happens (Python 3.13)Fix
Saving the result of a changing methodnums = nums.sort()No error. nums becomes Nonenums.sort()
Forgetting the parenthesesnums.sortNo error. Nothing happensnums.sort()
Appending two itemsnums.append(4, 5)TypeError: list.append() takes exactly one argument (2 given)nums.extend([4, 5])
append instead of extenda.append(b)No error. A list inside a lista.extend(b)
Removing a missing itemnums.remove(99)ValueError: list.remove(x): x not in listif 99 in nums: first
Finding a missing itemnums.index(99)ValueError: 99 is not in listif 99 in nums: first
Popping an empty list[].pop()IndexError: pop from empty listCheck len() first
max or min of an empty listmax([])ValueError: max() iterable argument is emptyCheck len() first
Printing reversed() directlyprint(reversed(nums))No error. Prints <list_reverseiterator object at 0x...>list(reversed(nums))
Sorting mixed typessorted(["b", 2])TypeError: '<' not supported between instances of 'int' and 'str'Keep one type per list
A method lists do not havenums.add(3)AttributeError: 'list' object has no attribute 'add'nums.append(3)

Try these at the prompt. Start with the first line:

  • nums = [3, 1, 2]
  • nums.sort()
  • nums
  • nums = nums.sort()
  • print(nums)
  • [].pop()
  • reversed([1, 2])
  • [x * x for x in range(5)]

The two silent bugs

  • nums = nums.sort() throws away your list and leaves None. You will find out later, when something like len(nums) fails with TypeError: object of type 'NoneType' has no len(). If you ever see NoneType in an error, look for a saved result of a changing method.
  • nums.sort without parentheses only names the method; it does not call it. Always include ().

"Look before you leap" prevents most of the other errors: check in before remove/index, and len() before pop/min/max.

  • The None trap and the missing-parentheses trap give no error.
  • NoneType in an error often means a saved result of sort/append.

Three of these give no error at all, so watch for them: storing the result of sort, forgetting the parentheses, and using append when you meant extend. For the rest, the error message names the exact problem. Use in and len to check before you remove, index, or pop.

Practice

Check yourself

Choose an answer, then click Check. This is practice only. Nothing is graded or recorded.

For each question, ask:
  • Does this tool change the original list, or give back something new?
  • If it changes the list, does it return the item (pop) or None (everything else)?
  • Is it a method (list.tool()) or a function (tool(list))?
  • Ask: does this change the list, or give back something new?

For each question, first decide whether the tool changes the list in place or gives back something new. That one question answers most of these.

Summary

Cheat sheet

Change the list (return None)

nums.append(5)      # add to end
nums.insert(0, 9)   # add at index
nums.remove(9)      # by value
nums.extend([6, 7]) # merge in
nums.sort()         # in place
nums.reverse()      # in place
del nums[0]         # by index

nums.pop() removes and returns the item.

Ask questions (list unchanged)

len(nums)         # how many
min(nums)         # smallest
max(nums)         # largest
sum(nums)         # total
nums.index(5)     # where
nums.count(5)     # how many 5s
sorted(nums)      # new sorted list
list(reversed(nums))
a + b             # new merged list

List comprehensions

[n * 2 for n in nums]
[s for s in scores if s >= 70]
[w.upper() for w in words]

Read it as: "expression, for each item in list, if condition."

Remember:

  • Never write nums = nums.sort(); methods that change a list return None
  • Check with in before remove() or index(), and with len() before pop(), min(), or max()
  • extend merges; append adds one item
  • Wrap reversed() in list() to see the items

Key words to know

method · function · in place · return value · None · append / extend · remove / pop / del · sort / sorted · iterator · list comprehension · filter

  • Change vs. ask vs. build.
  • Know the key words: in place, return value, None, iterator, comprehension.

Let's wrap up with three groups. Methods like append, insert, remove, sort, and reverse change the list and give back None. Functions like len, min, max, sum, and sorted answer questions and leave the list alone. And list comprehensions build a brand new list in a single line.