List methods you will actually use
You met several list methods in the last lesson. This one covers the rest, groups them by what they do, and is honest about which you will use weekly and which you will look up every time.
The one distinction that matters
Every list method falls into one of two groups, and mixing them up causes the same bug repeatedly.
Methods that change the list in place and return None:
append, insert, extend, remove, sort, reverse, clear
Functions that leave the list alone and return something new:
sorted, reversed, list, and slicing
So this is wrong:
numbers = [3, 1, 2]
numbers = numbers.sort()
print(numbers)
None
sort() sorted the list and returned None, and you then threw the sorted list
away by assigning None over it. Either:
numbers.sort() # change it in place
or:
numbers = sorted(numbers) # make a new sorted list
If a method changes the thing, it gives you nothing back. That is a consistent rule across Python, not a quirk of lists, and knowing it saves you the same hour repeatedly.
Adding
items = ["a", "b"]
items.append("c") # ['a', 'b', 'c'] — one item at the end
items.insert(0, "z") # ['z', 'a', 'b', 'c'] — at a position
items.extend(["d", "e"]) # ['z', 'a', 'b', 'c', 'd', 'e']
append versus extend catches people:
a = [1, 2]
a.append([3, 4])
print(a) # [1, 2, [3, 4]] — a list inside a list
b = [1, 2]
b.extend([3, 4])
print(b) # [1, 2, 3, 4] — items added individually
append adds one thing, whatever it is. extend adds each item of
something iterable. If a list has mysteriously gained a nested list, you wanted
extend.
+ also joins, producing a new list:
c = [1, 2] + [3, 4] # [1, 2, 3, 4]
And += behaves like extend, modifying in place.
Removing
items = ["a", "b", "c", "b"]
items.remove("b") # removes the FIRST "b" only
last = items.pop() # removes and returns the last
first = items.pop(0) # removes and returns position 0
del items[0] # removes by position, returns nothing
items.clear() # empties it
Two things worth knowing:
remove() removes only the first match. To remove every occurrence, build a new
list without them.
pop() returns what it removed; del does not. When you want the value, use
pop.
Both raise if they cannot do the job:
[].pop() # IndexError: pop from empty list
[1, 2].remove(99) # ValueError: list.remove(x): x not in list
Check first when the value might genuinely be missing:
if "b" in items:
items.remove("b")
Sorting
numbers = [3, 1, 4, 1, 5]
numbers.sort() # in place, ascending
numbers.sort(reverse=True) # in place, descending
new_list = sorted(numbers) # new list, original untouched
Sorting strings sorts alphabetically — and, as the comparison lesson warned, capitals come first:
names = ["priya", "Arjun", "sneha"]
print(sorted(names))
['Arjun', 'priya', 'sneha']
For a human-sensible sort, give it a key:
print(sorted(names, key=str.lower))
['Arjun', 'priya', 'sneha']
Same here by coincidence, but it now ignores case rather than accidentally agreeing with you.
key is the most useful option on sorted. It takes a function applied to each
item, and sorts by the result:
words = ["banana", "fig", "cherry"]
print(sorted(words, key=len))
['fig', 'banana', 'cherry']
You meet lambda properly in the functions module; when you do, key is where
it earns its keep.
numbers.reverse() # in place
print(list(reversed(numbers))) # a new reversed sequence
Searching and counting
items = ["a", "b", "c", "b"]
print("b" in items) # True
print(items.count("b")) # 2
print(items.index("b")) # 1 — the first one
index() raises ValueError if the value is absent, so guard it with in
unless you are certain.
Prefer in to index() when you only care whether something is present. It
says what you mean and cannot raise.
Copying
Covered last lesson, repeated because it matters:
b = a.copy() # clearest
b = a[:] # same thing, terser
b = list(a) # same thing again
All three are shallow. For nested lists, copy.deepcopy.
Unpacking
Assign several items at once:
point = [10, 20]
x, y = point
print(x, y) # 10 20
The counts must match, or you get ValueError: too many values to unpack.
* collects the rest:
numbers = [1, 2, 3, 4, 5]
first, *rest = numbers
print(first) # 1
print(rest) # [2, 3, 4, 5]
first, *middle, last = numbers
print(middle) # [2, 3, 4]
Genuinely useful when handling a header row followed by data.
Two things to be careful with
Multiplying a list of lists.
grid = [[0] * 3] * 3
grid[0][0] = 1
print(grid)
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]
Three labels pointing at the same inner list, so changing one changes all three. The aliasing problem again, in its most confusing costume. Build it properly:
grid = [[0] * 3 for _ in range(3)]
That syntax is a comprehension, which is the next-but-one lesson.
sorted() on mixed types:
sorted([1, "two", 3])
TypeError: '<' not supported between instances of 'str' and 'int'
Python cannot say whether 1 comes before "two", and refuses to guess. One
more reason to keep a list to one kind of thing.
Practice
- Start with
[3, 1, 4]. Useappend, thenextend, theninsertand print after each. Then doa.append([9, 9])and explain the result. - Write code that removes every occurrence of
"b"from["a", "b", "c", "b", "b"]. - Sort
["banana", "Apple", "cherry"]case-sensitively and case-insensitively. Explain the difference in the output. - Sort
["python", "is", "great", "fun"]by length, then by length descending. - Run
numbers = numbers.sort()deliberately, print the result, and say out loud what happened. - Build
grid = [[0] * 3] * 3, change one cell, and see the bug. Then build it correctly and confirm it is fixed. - Using unpacking, split
["Name", "Priya", "Pune", "Engineer"]into a header variable and arestlist.
Next: dictionaries, which are what you actually wanted most of the times you reached for a list.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship