LambdaLabTM
Computer Science · Class 11 · Data Types
Data TypesSequences⏱️ 12 min read

List Methods

The last lesson ended on a promise: a list can be changed, and Python gives you proper tools for doing it. Here they are. There are a dozen of them, and they sort themselves into two piles by asking one question — does this change the list, or does it hand me an answer?

1The question that sorts them all

On the Strings page, every method handed back a brand-new string and left the original alone — it had no choice, because a string cannot be changed. A list can. So a list method has a second option open to it: instead of building you a new list, it can reach into the one you already have and rearrange it.

Methods that do that are said to work in place. They change the list, and then they hand back None — Python's word for nothing at all. The change is the answer, so there is nothing left to give you.

Key Takeaway
In place, or a new answer. If a method changes the list, it gives back None and you simply print the list afterwards. If it gives back an answer, catch it in a variable or print it. Keep that one line in your head and half of this lesson is already done.
🧪 The list method lab

Every call below starts from the same list. Watch the bottom pane — it is the one that tells you whether the list was changed.

you start with
marks =
[50,20,40,20]
>>> marks.append(30)
it gave back
None

Nothing worth catching.

marks is now
[50,20,40,20,30]

🔧 the list was changed

Adds ONE item at the end. It hands back None — the answer is the change itself, not something you catch.

2Adding: append(), insert(), extend()

Three ways to put something in, and they differ in where and how many.

adding.py
marks = [50, 20, 40]

marks.append(30)          # one item, at the end
print(marks)

marks.insert(1, 99)       # one item, at position 1
print(marks)

marks.extend([70, 80])    # every item of another list
print(marks)
Output
[50, 20, 40, 30]
[50, 99, 20, 40, 30]
[50, 99, 20, 40, 30, 70, 80]
append(x)

One item, always at the end. The one you will use most.

insert(i, x)

One item, at the position you pick. Position first, value second.

extend(list)

Many items at the end — every item of the list you hand it.

Watch Out
append() and extend() are not the same thing. Give both of them the same list and watch what happens:
append_vs_extend.py
a = [1, 2]
b = [1, 2]

a.append([3, 4])     # goes in as ONE item
b.extend([3, 4])     # goes in as TWO items

print(a)
print(b)
print(len(a))
print(len(b))
Output
[1, 2, [3, 4]]
[1, 2, 3, 4]
3
4

a now has a list inside a list, and its length is 3, not 4 — because as far as a is concerned, [3, 4] is a single item that happens to be a list. append() adds the thing you gave it. extend() adds what is inside the thing you gave it.

3Removing: remove() and pop()

Two ways to take something out, and the difference is what you know about it. Use remove() when you know the value. Use pop() when you know the position — or when you want the item back.

removing.py
marks = [50, 20, 40, 20]

marks.remove(20)      # by VALUE — the first 20 only
print(marks)

last = marks.pop()    # by POSITION — the last one, and it hands it back
print(last)
print(marks)

first = marks.pop(0)  # position 0
print(first)
print(marks)
Output
[50, 40, 20]
20
[50, 40]
50
[40]

Two things are worth pausing on. remove(20) took out only the first 20 — the second one survived. And pop() is the odd one out of every method on this page: it changes the list and hands back the item it removed, which is why last holds 20.

Watch Out
Both complain when they cannot do the job. remove() on a value that is not in the list raises ValueError: list.remove(x): x not in list, and pop() on an empty list raises IndexError: pop from empty list. Neither one shrugs the way find() did on a string.
removing_error.py
marks = [50, 20, 40]

marks.remove(99)      # 99 was never in there
Output
Traceback (most recent call last):
  File "removing_error.py", line 3, in <module>
    marks.remove(99)      # 99 was never in there
ValueError: list.remove(x): x not in list

4Reordering: sort(), reverse() — and sorted()

sort() puts the list in order, smallest first. reverse() flips it end to end — it does not sort, it just turns the list back to front. Both work in place.

ordering.py
marks = [50, 20, 40]

print(sorted(marks))       # a NEW sorted list
print(marks)               # ...and marks has not moved

marks.sort()               # now change marks itself
print(marks)

marks.reverse()            # flip it end to end
print(marks)

marks.sort(reverse=True)   # sort, biggest first
print(marks)
Output
[20, 40, 50]
[50, 20, 40]
[20, 40, 50]
[50, 40, 20]
[50, 40, 20]

Read the first two lines together, because they are the whole point. sorted(marks) printed a sorted list — and the very next line shows marks still in its original order. Nothing was changed. Two lines later, marks.sort() changed it for good.

marks.sort() — a method

Sorts marks itself. The old order is gone. Gives back None.

sorted(marks) — a function

Builds a new sorted list and hands it over. marks is left exactly as it was.

Watch Out
The mistake almost everybody makes once: marks = marks.sort() It looks sensible — sort the list, store the result. But sort() gives back None, so that line throws the sorted list away and puts None into marks:
the_none_trap.py
marks = [50, 20, 40]

marks = marks.sort()   # DON'T — sort() gives back None
print(marks)
Output
None

Write marks.sort() on its own line and then use marks. Or, if you want to keep the original order too, use ordered = sorted(marks) — that is exactly what sorted() is for.

5Asking: count() and index()

You have met both of these already, on strings. They behave the same way on a list — and, like every question, they leave the list alone.

asking.py
marks = [50, 20, 40, 20]

print(marks.count(20))   # how many 20s?
print(marks.index(20))   # where is the first 20?
print(marks.index(40))
Output
2
1
2

count() answers how many. index() answers where — and only ever reports the first match, which is why two 20s still give the single answer 1. Ask for something that is not there and index() raises a ValueError, exactly as it did on a string.

6The functions: len(), min(), max(), sum()

These are functions, not methods — the list goes inside the parentheses, with no dot. None of them changes anything.

functions.py
marks = [50, 20, 40, 20]

print(len(marks))
print(min(marks))
print(max(marks))
print(sum(marks))
print(sum(marks) / len(marks))   # the average
Output
4
20
50
130
32.5
Tip
That last line is worth keeping. sum() over len() is how you average a list of any size — and unlike the average program you wrote earlier, it does not care whether there are three marks or three hundred.

7list(): building a list out of something else

list() is one more function, and it does what int() and str() did in the casting lesson: it takes a value and gives you the list version of it. Hand it any sequence and it lays the items out one by one.

making.py
letters = list('hello')
numbers = list((1, 2, 3))
empty = list()

print(letters)
print(numbers)
print(empty)
Output
['h', 'e', 'l', 'l', 'o']
[1, 2, 3]
[]

list('hello') is the useful one: it splits the word into its five separate characters, and now they sit in something you can change — which the string itself would never allow.

8Try it

Change the list, print it, break it. The methods need a name to work on, so this one is a real program rather than a single prompt line.

playing.py

9Recap

CallDoesGives back
append(x)adds one item at the endNone
insert(i, x)adds one item at position iNone
extend(list)adds every item of another listNone
remove(x)removes the first x — ERROR if absentNone
pop()removes the last itemthe item removed
pop(i)removes the item at position ithe item removed
sort()puts the list in order, in placeNone
reverse()flips the list end to end, in placeNone
count(x)how many times x appearsa number
index(x)position of the first x — ERROR if absenta number
sorted(list)a NEW sorted list — original untoucheda new list
len(list)how many itemsa number
min(list) / max(list)smallest / biggest itema value
sum(list)adds all the items upa number
list(x)builds a list out of another sequencea new list
Key Takeaway
Everything in the first eight rows changes the list and gives back None — except pop(), which does both. Everything below them answers a question and leaves the list exactly as it was. When you are stuck, that is the question to ask.
Quick Check

What does marks.sort() give back?

Quick Check

a = [1, 2] and then a.append([3, 4]). What is len(a)?

Quick Check

marks = [50, 20, 40, 20]. What does marks.index(20) give?

Quick Check

Which one leaves the original list untouched?