Lists
Python's general-purpose ordered, mutable sequence
A list is Python's workhorse collection: an ordered, mutable sequence that can hold values of any type. Lists are everywhere in real-world Python — search results from an API, user records from a database, file paths for batch processing, task queues, log messages, and more. If you need to store multiple things and might change them later, a list is usually your first choice.
Every snippet on this page runs in your browser — no setup required.
Creating a list
The simplest list is written with square brackets, separating items with commas.
Lists are heterogeneous: they can mix types freely.
The list() constructor converts any iterable into a list.
How lists work under the hood
Lists are implemented as dynamic arrays: a contiguous block of memory holding references to objects. This gives O(1) random access by index but O(n) insertion/deletion in the middle. Think of a list as a row of numbered parking spots, where each spot points to the actual object.
Lists in the wild
Every web framework returns search results as a list. Every database driver gives you rows as a list. Every file system walk yields paths in a list. Lists are the default sequence type in Python, and understanding them deeply pays off constantly.
Indexing
Lists support zero-based indexing. Negative indices count from the end.
Out-of-range access raises an IndexError.
Slicing
Slices let you extract a sublist with [start:stop:step]. The stop index is exclusive.
The step parameter lets you skip items or reverse.
Mutation via assignment
Unlike strings (which are immutable), you can assign directly through an index or slice.
Slice assignment can change the list's length.
Slice assignment replaces, not item-by-item
When you write xs[1:4] = [9], Python removes indices 1 through 3 and inserts the single item 9. The lengths do not need to match. This trips up newcomers who expect element-by-element replacement.
Common methods: adding items
The three main ways to grow a list:
append and extend are O(1) amortized, so they are fast. insert at the front or middle is O(n) because it shifts all subsequent elements.
Common methods: removing items
remove deletes the first occurrence and raises ValueError if the item is missing.
Common methods: searching and counting
Sorting and reversing
sort() and reverse() modify the list in place and return None.
For case-insensitive string sorting, pass a key function.
If you want a new sorted list without modifying the original, use the built-in sorted().
Iteration
The for loop is the canonical way to visit each item.
When you also need the index, use enumerate.
To iterate two lists in parallel, use zip.
Membership and aggregates
Membership testing is O(n)
item in list scans the entire list in the worst case. If you are doing frequent membership checks, consider converting to a set, where in is O(1).
Copying lists: shallow vs deep
Assignment does not copy. Both names point to the same list.
Use .copy() or slicing [:] for a shallow copy.
Shallow means nested structures are still shared.
For true independence, use copy.deepcopy.
Modifying while iterating
Changing a list's length during iteration invalidates the iterator and leads to skipped items or infinite loops. If you must remove items, iterate over a copy: for x in xs[:] or build a new list with a comprehension.
Stacks and queues
Lists make excellent stacks because append and pop at the end are both O(1).
For queues (FIFO), prefer collections.deque, which supports O(1) operations at both ends. Using a list as a queue means O(n) pop(0) every time you dequeue.
Challenges
Define a function rotate(items, n) that returns a new list with the items rotated left by n positions. For example, rotate([1, 2, 3, 4, 5], 2) returns [3, 4, 5, 1, 2].
Hint: slicing makes this one-liner.
Define dedupe(items) that returns a list of the items in items with duplicates removed, keeping the first occurrence of each. For example, dedupe([3, 1, 3, 2, 1, 4]) returns [3, 1, 2, 4].
Hint: a set of "already seen" items is a great fit.
Define a function flatten(nested) that takes a list of lists and returns a single flat list. For example, flatten([[1, 2], [3], [4, 5]]) returns [1, 2, 3, 4, 5].
You may assume the list is only one level deep.
What is the value of xs after this code runs?
xs = [1, 2, 3, 4, 5]
xs[1:4] = [9]
[1, 9, 4, 5]
[1, 9, 5]
[1, 9, 2, 3, 4, 5]
A ValueError because lengths differ
Which operation modifies the list in place?
sorted(xs)
xs.sort()
xs + [9]
list(xs)
What does xs.pop() return if xs = [1, 2, 3]?
[1, 2]
1
3
None
What is the time complexity of item in xs where xs is a list?
O(1)
O(n)
O(log n)
O(n²)
Lists are mutable. Their immutable cousin, the tuple, is next.