Lists
A list is Python’s general-purpose container for an ordered collection of values. Unlike arrays in many other languages, a Python list can hold items of different types at once, grows and shrinks as you add or remove elements, and is one of the most frequently used data structures in everyday code — from storing a handful of numbers to building up rows of data read from a file.
Creating a List
You create a list with square brackets, separating items with commas. Lists can be empty, hold a single type, or mix types freely.
fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = ["Ada", 36, True, 3.14]
empty = []
print(fruits) # ['apple', 'banana', 'cherry']
print(mixed) # ['Ada', 36, True, 3.14]
# You can also build a list from any iterable with list()
letters = list("abc")
print(letters) # ['a', 'b', 'c']Lists Are Mutable
The defining feature of a list is that it can be changed after creation — you can add, remove, or replace items without creating a new list object. This is different from strings and tuples, which cannot be modified in place.
scores = [10, 20, 30] scores[1] = 99 # replace an item by position print(scores) # [10, 99, 30] scores.append(40) # add an item at the end print(scores) # [10, 99, 30, 40] original = scores original.append(50) print(scores is original) # True - same list object print(scores) # [10, 99, 30, 40, 50] - visible through both names
Indexing
Every item in a list has a numeric position, or index, starting at 0 for the first item. Python also supports negative indices, which count backward from the end of the list, with -1 referring to the last item.
colors = ["red", "green", "blue", "yellow"] print(colors[0]) # red - first item print(colors[2]) # blue - third item print(colors[-1]) # yellow - last item print(colors[-2]) # blue - second to last # Indexing past the end raises an error # print(colors[10]) # IndexError: list index out of range
Index | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
Value |
|
|
|
|
Negative index |
|
|
|
|
Slicing Basics
Slicing lets you pull out a sub-list using the start:stop (and optional step) syntax. The start index is included, the stop index is excluded, and omitting either end defaults to “from the beginning” or “to the end.”
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print(numbers[2:5]) # [2, 3, 4] - index 2 up to (not including) 5 print(numbers[:3]) # [0, 1, 2] - from the start print(numbers[7:]) # [7, 8, 9] - to the end print(numbers[::2]) # [0, 2, 4, 6, 8] - every second item print(numbers[::-1]) # [9, 8, 7, ..., 0] - reversed copy # Slicing never raises IndexError, even out of range print(numbers[5:100]) # [5, 6, 7, 8, 9]
Nested Lists
Because a list can hold any object, it can hold other lists too. This is how you represent grids, matrices, or any table-like data in plain Python.
grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
print(grid[0]) # [1, 2, 3] - first row
print(grid[1][2]) # 6 - row 1, column 2
print(grid[-1][0]) # 7 - last row, first column
for row in grid:
print(row)
# [1, 2, 3]
# [4, 5, 6]
# [7, 8, 9]bad_grid = [[0] * 3] * 3 bad_grid[0][0] = 1 print(bad_grid) # [[1, 0, 0], [1, 0, 0], [1, 0, 0]] - all rows changed! # Correct way: build each row independently good_grid = [[0] * 3 for _ in range(3)] good_grid[0][0] = 1 print(good_grid) # [[1, 0, 0], [0, 0, 0], [0, 0, 0]] - only row 0 changed
Common Operations
Beyond indexing and slicing, lists support a handful of operators and methods that come up constantly. The methods below are covered in full detail (with every parameter) on the List Methods page — this is the quick-start version.
items = ["a", "b", "c"]
items.append("d") # add one item at the end
print(items) # ['a', 'b', 'c', 'd']
items.insert(1, "x") # insert "x" at index 1
print(items) # ['a', 'x', 'b', 'c', 'd']
items.remove("x") # remove the first "x" found
print(items) # ['a', 'b', 'c', 'd']
last = items.pop() # remove and return the last item
print(last, items) # d ['a', 'b', 'c']
items.extend(["e", "f"]) # append every item from another iterable
print(items) # ['a', 'b', 'c', 'e', 'f']
combined = ["a", "b"] + ["c", "d"] # concatenation
print(combined) # ['a', 'b', 'c', 'd']
repeated = ["x", "y"] * 3 # repetition
print(repeated) # ['x', 'y', 'x', 'y', 'x', 'y']Operation | Effect |
|---|---|
| Adds a single item |
| Inserts |
| Removes the first item equal to |
| Removes and returns the item at index |
| Appends every item from another iterable, in place. |
| Returns a new list that is the concatenation of both. |
| Returns a new list with |
Checking Membership with `in`
The in operator checks whether a value exists anywhere in a list, returning a plain bool. Its counterpart, not in, checks for absence.
fruits = ["apple", "banana", "cherry"]
print("banana" in fruits) # True
print("mango" in fruits) # False
print("mango" not in fruits) # True
if "apple" in fruits:
print("We have apples!") # We have apples!Lists vs Arrays
If you have used a language like Java, C, or C#, you might expect a Python list to behave like an array. Conceptually they are quite different.
A Python list can hold values of mixed types; a traditional array is typically fixed to one type.
A Python list resizes automatically as you append or remove items; many arrays have a fixed size set at creation.
Python does have a fixed-type, memory-compact
arraymodule and third-party arrays like NumPy’sndarray, which behave much more like classic arrays and are faster for large numeric workloads.For everyday general-purpose collections, the built-in
listis almost always the right default.
Length and Iteration
Two things you will do with nearly every list: ask how many items it has with len(), and loop over its items directly with for.
fruits = ["apple", "banana", "cherry"]
print(len(fruits)) # 3
for fruit in fruits:
print(fruit)
# apple
# banana
# cherry
for index, fruit in enumerate(fruits):
print(index, fruit)
# 0 apple
# 1 banana
# 2 cherry