Every program you will ever write works with collections of things.
A list of users. A list of prices. A list of predictions your model made. A list of words in a sentence. A list of images to process.
You cannot avoid lists. They are everywhere. Learn them well now and everything else gets easier.
Making a List
Square brackets. Items separated by commas.
fruits = ["apple", "banana", "mango", "grape"]
scores = [95, 82, 67, 54, 71]
mixed = ["Alex", 25, True, 3.14]
empty = []
A list can hold anything. Strings, numbers, booleans, even other lists. And yes, mixing types in one list is allowed, though in practice most lists hold one type of thing.
Getting Items Out
Every item in a list has a position number called an index. And here is the thing that trips up almost everyone at the start.
Indexes start at 0, not 1.
fruits = ["apple", "banana", "mango", "grape"]
print(fruits[0]) # apple
print(fruits[1]) # banana
print(fruits[2]) # mango
print(fruits[3]) # grape
Output:
apple
banana
mango
grape
First item is index 0. Second is index 1. Always one less than you expect.
Negative indexes count from the end. -1 is always the last item.
print(fruits[-1]) # grape
print(fruits[-2]) # mango
Incredibly useful when you need the last item and don't know how long the list is.
Try to access an index that doesn't exist and Python tells you clearly.
print(fruits[10])
IndexError: list index out of range
The list has 4 items. Index 10 does not exist.
Changing Items
Lists are mutable. That means you can change them after creating them.
fruits = ["apple", "banana", "mango", "grape"]
fruits[1] = "orange"
print(fruits)
Output:
['apple', 'orange', 'mango', 'grape']
Banana is gone. Orange took its place at index 1.
Adding and Removing
fruits = ["apple", "banana", "mango"]
fruits.append("grape") # adds to the end
print(fruits)
fruits.insert(1, "orange") # inserts at index 1
print(fruits)
fruits.remove("banana") # removes by value
print(fruits)
last = fruits.pop() # removes and returns last item
print(last)
print(fruits)
Output:
['apple', 'banana', 'mango', 'grape']
['apple', 'orange', 'banana', 'mango', 'grape']
['apple', 'orange', 'mango', 'grape']
grape
['apple', 'orange', 'mango']
append is the one you'll use most. Every time you build a list dynamically, you start with an empty list and append to it.
Useful Things to Know About Your List
numbers = [4, 2, 8, 1, 9, 3, 7]
print(len(numbers)) # 7, how many items
print(min(numbers)) # 1, smallest
print(max(numbers)) # 9, largest
print(sum(numbers)) # 34, total
print(sorted(numbers)) # [1, 2, 3, 4, 7, 8, 9], sorted copy
print(7 in numbers) # True, is 7 in the list?
print(5 in numbers) # False
Output:
7
1
9
34
[1, 2, 3, 4, 7, 8, 9]
True
False
in is one of the cleaner bits of Python. Check if something exists in a list in plain English.
Slicing: Getting a Chunk
You can grab a section of a list using slicing. Start index and end index separated by a colon inside brackets.
numbers = [10, 20, 30, 40, 50, 60, 70]
print(numbers[1:4]) # index 1 up to but not including 4
print(numbers[:3]) # from the start up to index 3
print(numbers[4:]) # from index 4 to the end
print(numbers[-3:]) # last three items
Output:
[20, 30, 40]
[10, 20, 30]
[50, 60, 70]
[50, 60, 70]
Same rule as range: the end number is not included. [1:4] gives you indexes 1, 2, and 3.
Looping Over a List
You saw this in the loops post. Now it makes more sense.
names = ["Alex", "Priya", "Sam", "Jordan"]
for name in names:
print(f"Hello, {name}!")
Output:
Hello, Alex!
Hello, Priya!
Hello, Sam!
Hello, Jordan!
If you also need the index, use enumerate.
for index, name in enumerate(names):
print(f"{index}: {name}")
Output:
0: Alex
1: Priya
2: Sam
3: Jordan
enumerate gives you both the position and the value on every pass. You'll use this more than you think.
Building a List Dynamically
The most common real-world pattern. Start empty, add things as you go.
scores = [45, 92, 78, 61, 88, 55, 97]
passing = []
for score in scores:
if score >= 60:
passing.append(score)
print(passing)
Output:
[92, 78, 61, 88, 97]
Start with an empty list. Loop through the original. Check the condition. Append if it passes. End up with a filtered list. This pattern is everywhere in data processing.
One Mistake That Gets Everyone
Copying a list the wrong way.
original = [1, 2, 3]
copy = original # this is NOT a copy
copy.append(4)
print(original) # [1, 2, 3, 4] -- original changed too!
When you do copy = original, you're not creating a second list. Both variables point to the exact same list in memory. Change one, both change.
To make a real copy:
original = [1, 2, 3]
copy = original.copy() # actual copy
copy.append(4)
print(original) # [1, 2, 3] -- original unchanged
print(copy) # [1, 2, 3, 4]
This trips people up badly in data work. Always use .copy() when you need an independent copy of a list.
Try This
Create lists_practice.py.
Start with this list of temperatures in Celsius:
temps = [38, 22, 41, 19, 35, 27, 44, 16, 30, 23]
Write code that does all of these without using any built-in shortcut functions where noted:
First: print the highest and lowest temperature using max() and min().
Second: build a new list containing only temperatures above 30. Use a loop and append.
Third: convert every temperature to Fahrenheit and store in a new list. Formula: (c * 9/5) + 32. Use the function you wrote in post 5 if you saved it.
Fourth: print how many temperatures are above 30 without using len() on your filtered list. Count them with a counter variable inside a loop.
Run it. Check the outputs make sense.
What's Next
Lists hold items in order with a numeric index. But sometimes you need to label your data with names instead of numbers. That's what dictionaries are for and they're coming up next.
Top comments (0)