Python Lists for Beginners, Create, Index, Slice, and Change
How Python lists work for beginners, including indexing, slicing, adding and removing items, sorting, and the copy mistake that surprises everyone.
Almost every useful program works with more than one thing at a time: a set of tasks, a column of scores, a batch of file names. In Python, the first tool you reach for is the list. This guide covers how to create one, read items out of it, change it, and avoid the two mistakes beginners make most often. Every example below was run in Python 3.13, and the output shown is what it printed.
Creating a list and reading items
A list is a sequence of values inside square brackets, separated by commas.
tasks = ["email Dana", "fix report", "book room"]
print(tasks[0])
print(tasks[-1])
print(len(tasks))
Output:
email Dana
book room
3
Positions, called indexes, start at 0, so tasks[0] is the first item. Negative indexes count from the end, so tasks[-1] is the last item. The official tutorial explains this for strings, and lists follow the same rules: the Data Structures chapter notes that lists and strings share properties such as indexing and slicing.
len() tells you how many items the list holds.
Slicing: taking part of a list
A slice uses a colon to grab a range of items. The start position is included and the end position is not.
scores = [72, 85, 90, 64, 88]
print(scores[1:3])
print(scores[:2])
print(scores[-2:])
print(scores[1:100])
Output:
[85, 90]
[72, 85]
[64, 88]
[85, 90, 64, 88]
scores[1:3] gives positions 1 and 2. Leaving out the start means "from the beginning," and leaving out the end means "to the end." The last line shows something forgiving: a slice that runs past the end does not crash, it just stops at the last item. Asking for a single position that does not exist is different. scores[5] raises IndexError: list index out of range.
Changing a list
Unlike strings, lists can be changed in place. You can replace an item by assigning to its index:
scores[0] = 75
print(scores)
Output:
[75, 85, 90, 64, 88]
The Data Structures chapter lists every method a list has. These are the ones you will use constantly:
| Method | What it does |
|---|---|
append(x) |
Adds an item to the end |
insert(i, x) |
Inserts an item before position i |
remove(x) |
Removes the first item equal to x |
pop() |
Removes and returns the last item |
count(x) |
Counts how many times x appears |
index(x) |
Returns the position of the first x |
sort() |
Sorts the list in place |
Here they are working on the task list from earlier:
tasks.append("call vendor")
tasks.insert(0, "check calendar")
print(tasks)
tasks.remove("fix report")
finished = tasks.pop()
print(finished)
print(tasks)
Output:
['check calendar', 'email Dana', 'fix report', 'book room', 'call vendor']
call vendor
['check calendar', 'email Dana', 'book room']
insert(0, ...) put the new task at the front. pop() both removed the last task and handed it back, so it could be stored in finished.
Two of these can raise errors, and the tutorial documents both. remove() raises a ValueError if the item is not in the list, and pop() raises an IndexError if the list is empty. Running them confirms the messages: ValueError: list.remove(x): x not in list and IndexError: pop from empty list.
Checking what is in a list
The in keyword answers "is this value in the list?" with True or False.
print(85 in scores, 100 in scores)
print(scores.count(85), scores.index(90))
Output:
True False
1 2
Mistake 1: saving the result of sort()
There are two ways to sort. sorted(scores) returns a new, sorted list and leaves the original alone. scores.sort() sorts the original list itself and returns nothing.
print(sorted(scores))
print(scores)
result = scores.sort()
print(result)
print(scores)
Output:
[64, 75, 85, 88, 90]
[75, 85, 90, 64, 88]
None
[64, 75, 85, 88, 90]
The official tutorial explains why result is None: methods like insert, remove and sort that only modify the list return the default None, and the tutorial calls this a design principle for all mutable data structures in Python. So scores = scores.sort() is a classic bug: it sorts the list and then replaces it with None. Use scores.sort() on its own line, or scores = sorted(scores).
Mistake 2: thinking = makes a copy
This one surprises almost everyone.
a = ["x", "y"]
b = a
b.append("z")
print(a)
Output:
['x', 'y', 'z']
You only changed b, but a changed too. That is because b = a does not create a second list. It gives the same list a second name. When you need an independent copy, use the copy() method, which the tutorial describes as returning a shallow copy of the list:
c = a.copy()
c.append("w")
print(a, c)
Output:
['x', 'y', 'z'] ['x', 'y', 'z', 'w']
Now changing c leaves a alone.
Key takeaways
- A list holds an ordered sequence of values in square brackets; indexes start at 0, and -1 means the last item.
- Slices like
scores[1:3]include the start and exclude the end, and they never crash for running past the end. append,insert,removeandpopchange the list in place;removeandpopcan raise errors if the item or list is missing.sort()returnsNone, so never writex = x.sort(); usesorted()if you want a new list.b = ashares one list between two names; usea.copy()for a real copy.