☰

Python Lists Tutorial

Python Lists Tutorial With Examples

Think of a shopping list on your phone. You add items as you remember them, strike off the ones you have bought, move things around, and sometimes sort the list to match the shop aisles. It can hold anything you like, and it grows and shrinks as you go. A Python list is the same idea, and it is the most used data type in the language.

A list is an ordered collection of items, written in square brackets, that you can change after creating it. It can hold numbers, text, other lists, or a mix. Lists hold the rows of a dataset, the results of a search, the names in a class, or the steps in a recipe. Almost every Python program you write will use at least one.

In this tutorial, we explain how to create a list, read items by position, change them and cut out slices. We then go through the list methods one by one, with the real output of every example: append, insert, extend, remove, pop, del, clear, copy, index, count, reverse and sort. We cover the places beginners get stuck, such as reverse and sort returning None, the copy trap, and extend against append. We finish with list comprehension, nested lists, a quick reference table and the full program.

What is a Python List?

A list is an ordered, changeable collection of items written inside square brackets, with commas between the items.

  • Ordered. Items stay in the order you put them, and each has a position.
  • Mutable. You can change, add and remove items after the list is created.
  • Allows duplicates. The same value can appear many times.
  • Can mix types. Numbers, text, true or false values and other lists can share one list.

Every example below was run on Python 3.13, and the output is real.

How to Create a List in Python?

python
L1 = [11, 22, 33, 44]
mixed = [1, "two", 3.5, True]
print(L1, mixed, [], list("abc"))
output
[11, 22, 33, 44] [1, 'two', 3.5, True] [] ['a', 'b', 'c']

The third item shows an empty list, and the fourth shows list() turning a string into a list of its letters.

Reading Items by Index

Each item has a position, called an index, counted from 0. A negative index counts from the end, so minus 1 is the last item.

How L1 is numbered
Value 11 22 33 44
Index 0 1 2 3
Negative index -4 -3 -2 -1
python
L1 = [11, 22, 33, 44]
print(L1[2], L1[-1])
output
33 44

Asking for a position that does not exist raises an error:

python
L1 = [11, 22, 33, 44]
try:
    L1[10]
except IndexError as error:
    print("IndexError:", error)
output
IndexError: list index out of range

Changing an Item

Because lists are mutable, you can assign a new value to a position.

python
L1 = [11, 22, 33, 44]
L1[2] = 55
print(L1)
output
[11, 22, 55, 44]

Slicing a List

A slice takes a section of a list. The pattern is list[start:end:step]. The start is included and the end is not. A step of minus 1 reverses the list.

python
L1 = [11, 22, 55, 44]
print(L1[1:3], L1[::-1])
output
[22, 55] [44, 55, 22, 11]

Looping Through a List

A for loop visits each item in turn. Print the loop variable, and indent the line inside the loop.

python
L1 = [11, 22, 55, 44]
for x in L1:
    print(x, end=" ")
output
11 22 55 44

When you need the position as well, use enumerate:

python
L1 = [11, 22, 55, 44]
for position, value in enumerate(L1):
    print(position, value)
output
0 11
1 22
2 55
3 44

Checking Membership and Length

The in word tells you whether a value is in the list. len counts the items.

python
L1 = [11, 22, 55, 44]
print(22 in L1, 99 in L1, len(L1))
output
True False 4

List Methods in Python

List methods at a glance
Method What it does Returns
append(item) Adds one item at the end None
insert(index, item) Adds an item at a position None
extend(iterable) Adds every item of another collection None
remove(item) Removes the first matching item None
pop(index) Removes and returns the item at a position, the last by default The item
clear() Removes every item None
copy() Makes a shallow copy A new list
index(item) Position of the first match A number
count(item) How many times an item appears A number
reverse() Reverses the list in place None
sort() Sorts the list in place None

append()

append adds a single item at the end.

python
L = ["a", "ab", "aaa", "cc"]
L.append("hg")
print(L)
output
['a', 'ab', 'aaa', 'cc', 'hg']

If you append a list, it goes in as one item, and the list becomes nested:

python
L = ["a", "ab", "aaa", "cc", "hg"]
L.append(["x", "y"])
print(L)
output
['a', 'ab', 'aaa', 'cc', 'hg', ['x', 'y']]

insert()

insert puts an item at the position you choose, and pushes the rest along.

python
L = ["a", "ab", "aaa", "cc"]
L.insert(3, "hg")
print(L)
output
['a', 'ab', 'aaa', 'hg', 'cc']

extend()

extend adds every item of another collection, one by one. A string counts as a collection of letters, which surprises many beginners.

python
L = ["a", "ab", "aaa", "cc"]
L.extend(["qw"])
print(L)
L.extend("qw")
print(L)
output
['a', 'ab', 'aaa', 'cc', 'qw']
['a', 'ab', 'aaa', 'cc', 'qw', 'q', 'w']

Use a list, as in the first call, to add a whole word as one item.

append compared with extend
Point append extend
Adds One item, as it is Each item of a collection
append([1, 2]) Adds one list, so the list is nested Adds 1 and 2 as separate items
Use when You have one thing to add You have many things to add

remove()

remove deletes the first item that matches a value. It raises a ValueError if the value is not there.

python
L = ["a", "ab", "aaa", "cc"]
L.remove("ab")
print(L)
try:
    L.remove("zzz")
except ValueError as error:
    print("ValueError:", error)
output
['a', 'aaa', 'cc']
ValueError: list.remove(x): x not in list

pop()

pop removes an item by position and gives it back. With no position, it takes the last one. It also returns the item, so you can use it.

python
L = ["a", "ab", "aaa", "cc"]
print(L.pop(2), L)
print(L.pop(), L)
output
aaa ['a', 'ab', 'cc']
cc ['a', 'ab']

del

del is a statement, not a method. It removes an item or a slice by position, or the whole list.

python
L = [10, 20, 30, 40, 50]
del L[1]
print(L)
del L[1:3]
print(L)
output
[10, 30, 40, 50]
[10, 50]

Writing del L with no position removes the name itself, and using the list after that raises a NameError.

python
gone = [1, 2]
del gone
try:
    print(gone)
except NameError as error:
    print("NameError:", error)
output
NameError: name 'gone' is not defined

clear()

clear empties the list but keeps it. The list still exists and prints as empty brackets.

python
L = [10, 50]
L.clear()
print(L)
output
[]

copy()

Writing alias = a does not copy a list. Both names point to the same list, so a change through one shows up in the other. copy makes a separate list.

python
a = [1, 2, 3]
alias = a
copy_of = a.copy()
a.append(4)
print("alias:", alias, "copy:", copy_of)
output
alias: [1, 2, 3, 4] copy: [1, 2, 3]

But copy is shallow. If the list holds other lists, those inner lists are still shared. Use copy.deepcopy from the copy module when you need a fully independent copy.

python
nested = [[1, 2], [3]]
shallow = nested.copy()
nested[0].append(99)
print("shallow:", shallow)
output
shallow: [[1, 2, 99], [3]]

index() and count()

index is a method, so call it on the list, as in L.index("a").

python
L = ["a", "ab", "aaa", "cc", "a"]
print(L.index("a"), L.count("a"))
print(L.index("a", 1))
output
0 2
4

The first line shows that a first appears at position 0, and that it appears twice. The second index call starts looking from position 1, so it finds the later a at position 4.

reverse()

reverse flips the list in place. It returns None, so printing the call itself shows None. It is a method, and it gives nothing back.

python
L = ["a", "ab", "aaa", "cc"]
print(L.reverse())
print(L)
output
None
['cc', 'aaa', 'ab', 'a']

sort()

sort puts the list in order, in place, and also returns None. Use reverse=True for a descending order, and key to choose what to sort by.

python
L = ["cc", "a", "aaa", "ab"]
print(L.sort())
print(L)
L.sort(reverse=True)
print(L)
L.sort(key=len)
print(L)
output
None
['a', 'aaa', 'ab', 'cc']
['cc', 'ab', 'aaa', 'a']
['a', 'cc', 'ab', 'aaa']

The last sort is by length. Items with the same length keep their earlier order, which is why cc stays before ab.

sort() Against sorted()

If you want a sorted copy and want to keep the original, use the sorted function. It works on any collection and returns a new list.

python
data = [3, 1, 2]
print(sorted(data), data)
print(sorted("hello"))
output
[1, 2, 3] [3, 1, 2]
['e', 'h', 'l', 'l', 'o']

Joining, Repeating and Summarising Lists

python
print([1, 2] + [3], [0] * 3)
nums = [4, 8, 15, 16, 23, 42]
print(min(nums), max(nums), sum(nums), sum(nums) / len(nums))
output
[1, 2, 3] [0, 0, 0]
4 42 108 18.0

Plus joins two lists into a new one, and star repeats a list. min, max and sum work on lists of numbers.

List Comprehension

A list comprehension builds a new list in one line. Read it as: give me this, for each item in that, if the condition holds.

python
nums = [4, 8, 15, 16, 23, 42]
print([n * n for n in nums if n % 2 == 0])
output
[16, 64, 256, 1764]

It took the even numbers from nums, which are 4, 8, 16 and 42, and squared each one.

Nested Lists

A list can hold other lists, which is how you store rows and columns. Use one index for each level, the row first.

python
grid = [[1, 2, 3], [4, 5, 6]]
print(grid[1][2])
output
6

A Classic Mistake: append Returns None

Methods like append, sort and reverse change the list and return None. If you write the result into a variable, you lose your list:

python
result = [1, 2].append(3)
print(result)
output
None

Call the method on its own line, and then use the list.

Quick Reference: List, Tuple, Set and Dictionary

Four collection types compared
Type Written as Ordered Changeable Duplicates
List [1, 2, 3] Yes Yes Allowed
Tuple (1, 2, 3) Yes No Allowed
Set {1, 2, 3} No Yes Not allowed
Dictionary {“a”: 1} Yes Yes Keys must be unique

Common Mistakes to Avoid

  • Printing the result of sort or reverse. They return None. Call them, then print the list.
  • Writing index or sort as a plain function. They are methods, so write L.index and L.sort. The built in sorted is a function, and it works as sorted(L).
  • Using extend with a string. It adds each letter. Use append, or extend with a list.
  • Thinking b = a makes a copy. It makes a second name for the same list. Use a.copy().
  • Asking for an index past the end. It raises an IndexError. The last index is len minus 1.
  • Removing a value that is not there. remove raises a ValueError. Check with in first.
  • Changing a list while looping over it. Items can be skipped. Loop over a copy or build a new list.
  • Forgetting that append adds one item. Appending a list nests it.

Try It Yourself: The Full Program

The program below holds every example in this tutorial. Copy it into a file, run it, and compare the output with what you see above.

python
import sys
print("Python", sys.version_info.major, sys.version_info.minor)

# Creating lists
L1 = [11, 22, 33, 44]
mixed = [1, "two", 3.5, True]
print(L1, mixed, [], list("abc"))

# Indexing, changing and slicing
print(L1[2], L1[-1])
L1[2] = 55
print(L1)
print(L1[1:3], L1[::-1])
try:
    L1[10]
except IndexError as error:
    print("IndexError:", error)

# Looping and membership
for x in L1:
    print(x, end=" ")
print()
for position, value in enumerate(L1):
    print(position, value)
print(22 in L1, 99 in L1, len(L1))

# Adding
L = ["a", "ab", "aaa", "cc"]
L.append("hg")
print(L)
L = ["a", "ab", "aaa", "cc"]
L.insert(3, "hg")
print(L)
L.append(["x", "y"])
print(L)

# extend with a list and with a string
L = ["a", "ab", "aaa", "cc"]
L.extend(["qw"])
print(L)
L.extend("qw")
print(L)

# Removing
L = ["a", "ab", "aaa", "cc"]
L.remove("ab")
print(L)
L = ["a", "ab", "aaa", "cc"]
print(L.pop(2), L)
print(L.pop(), L)
try:
    L.remove("zzz")
except ValueError as error:
    print("ValueError:", error)
L = [10, 20, 30, 40, 50]
del L[1]
print(L)
del L[1:3]
print(L)
L.clear()
print(L)
gone = [1, 2]
del gone
try:
    print(gone)
except NameError as error:
    print("NameError:", error)

# Copy against alias
a = [1, 2, 3]
alias = a
copy_of = a.copy()
a.append(4)
print("alias:", alias, "copy:", copy_of)
nested = [[1, 2], [3]]
shallow = nested.copy()
nested[0].append(99)
print("shallow:", shallow)

# Searching and counting
L = ["a", "ab", "aaa", "cc", "a"]
print(L.index("a"), L.count("a"))
print(L.index("a", 1))

# Reverse and sort work in place and return None
L = ["a", "ab", "aaa", "cc"]
print(L.reverse())
print(L)
L = ["cc", "a", "aaa", "ab"]
print(L.sort())
print(L)
L.sort(reverse=True)
print(L)
L.sort(key=len)
print(L)
print(sorted([3, 1, 2]), sorted("hello"))
data = [3, 1, 2]
print(sorted(data), data)

# Joining, repeating and summary functions
print([1, 2] + [3], [0] * 3)
nums = [4, 8, 15, 16, 23, 42]
print(min(nums), max(nums), sum(nums), sum(nums) / len(nums))

# Comprehension and nested lists
print([n * n for n in nums if n % 2 == 0])
grid = [[1, 2, 3], [4, 5, 6]]
print(grid[1][2])

# A classic mistake: append returns None
result = [1, 2].append(3)
print(result)

Lists are the workhorse of Python. Learn to read them by index, slice them, and change them with append, insert, remove and sort, and you can handle most everyday data. Run the examples, break them on purpose, and read the errors, because they teach as much as the successes. Then move on to tuples, sets and dictionaries to see how each one differs.

Popular Tags:

Modifying Python Lists Python List Tutorial Python List Tutorial with Examples Python Sets Understanding Sets in Python Programming