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.
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.Every call below starts from the same list. Watch the bottom pane — it is the one that tells you whether the list was changed.
marks =Nothing worth catching.
🔧 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.
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)[50, 20, 40, 30] [50, 99, 20, 40, 30] [50, 99, 20, 40, 30, 70, 80]
One item, always at the end. The one you will use most.
One item, at the position you pick. Position first, value second.
Many items at the end — every item of the list you hand it.
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))[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.
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)[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.
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.marks = [50, 20, 40]
marks.remove(99) # 99 was never in thereTraceback (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 list4Reordering: 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.
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)[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.
Sorts marks itself. The old order is gone. Gives back None.
Builds a new sorted list and hands it over. marks is left exactly as it was.
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:marks = [50, 20, 40]
marks = marks.sort() # DON'T — sort() gives back None
print(marks)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.
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))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.
marks = [50, 20, 40, 20]
print(len(marks))
print(min(marks))
print(max(marks))
print(sum(marks))
print(sum(marks) / len(marks)) # the average4 20 50 130 32.5
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.
letters = list('hello')
numbers = list((1, 2, 3))
empty = list()
print(letters)
print(numbers)
print(empty)['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.
9Recap
| Call | Does | Gives back |
|---|---|---|
append(x) | adds one item at the end | None |
insert(i, x) | adds one item at position i | None |
extend(list) | adds every item of another list | None |
remove(x) | removes the first x — ERROR if absent | None |
pop() | removes the last item | the item removed |
pop(i) | removes the item at position i | the item removed |
sort() | puts the list in order, in place | None |
reverse() | flips the list end to end, in place | None |
count(x) | how many times x appears | a number |
index(x) | position of the first x — ERROR if absent | a number |
sorted(list) | a NEW sorted list — original untouched | a new list |
len(list) | how many items | a number |
min(list) / max(list) | smallest / biggest item | a value |
sum(list) | adds all the items up | a number |
list(x) | builds a list out of another sequence | a new list |
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.What does marks.sort() give back?
a = [1, 2] and then a.append([3, 4]). What is len(a)?
marks = [50, 20, 40, 20]. What does marks.index(20) give?
Which one leaves the original list untouched?