Guide Python Beginner

10.1 Introduction to Lists

What a list is, its core characteristics, why it's Python's general-purpose array, and how it's actually stored in memory as a resizable, over-allocated array of references.

3 min read
Python Lists

What Is a List?

What Is It?

An ordered, mutable collection that can hold any mix of values, written with square brackets and comma-separated.

>>> servers = ["web01", "web02", "db01"]
>>> servers
['web01', 'web02', 'db01']

Why Does It Matter?

A list is Python’s general-purpose, resizable “array” — the default choice whenever an ordered group of items might grow, shrink, or be reordered, unlike the fixed-content tuple (see 5.4 Sequence Data Types).

Characteristics

  • Ordered — items keep the position they were inserted in.
  • Mutable — can be changed in place after creation (see 10.11 Copying and Mutability).
  • Allows duplicates — the same value can appear more than once.
  • Heterogeneous — can mix types freely (int, str, even other lists).

Why Lists?

Lists are the right tool whenever order matters and the collection’s size isn’t fixed in advance — the majority of everyday collections (a queue of tasks, a batch of records, a sequence of pipeline steps) fit this shape.

Real-World Applications

  • A shopping cart’s items
  • Rows returned from a database query
  • A sequence of steps in a pipeline
  • A batch of files to process

Lists in DevOps

Lists are everywhere in infrastructure scripting: server inventories, Amazon EC2 instance IDs, container names, log lines — 10.15 Lists in DevOps is dedicated entirely to these patterns. (Time complexity for append() is covered fully in 10.13 Performance.)

>>> allowed_regions = ["us-east-1", "us-west-2", "eu-west-1"]

Internal Representation

flowchart LR L["variable l"] --> A["contiguous array of POINTERS"] A --> P1["→ 1"] A --> P2["→ 2"] A --> P3["→ 3"] A --> S1["(spare)"] A --> S2["(spare)"]

Each slot is a reference to an object elsewhere on the heap, with spare capacity pre-allocated for fast appends.

CPython allocates a contiguous block of memory holding pointers to each element — not the elements’ actual data, which lives separately on the heap (see 6.3 Memory Management: Stack vs Heap). Every slot is a same-sized reference, exactly like a variable, which is why a single list can freely hold mixed types.

>>> import sys
>>> sys.getsizeof([])       # empty list overhead
56
>>> sys.getsizeof([1])      # one element added
88

Dynamic Memory and Capacity

Unlike a fixed-size C array, a Python list resizes itself automatically — no capacity is ever declared up front. When it needs to grow, CPython over-allocates a few extra, unused slots so the next several append() calls don’t need another resize. This amortizes the cost of growing: append() is O(1) on average even though an occasional resize is O(n) — see 10.13 Performance.

>>> l = [1, 2, 3]
>>> id(l)
140632280611584
>>> l.append(4)     # fits in spare capacity -- no reallocation needed
>>> id(l)            # SAME id -- same underlying array object
140632280611584

Quick Interview Answer

“A list is an ordered, mutable, heterogeneous collection — Python’s general-purpose resizable array. Internally, CPython stores it as a contiguous array of pointers to the actual element objects, which live separately on the heap; that’s why a single list can mix types freely, since every slot is just a same-sized reference regardless of what it points to. To make growth cheap, CPython over-allocates spare capacity whenever it resizes, which is exactly what makes append() O(1) amortized instead of paying a full reallocation cost on every single call.”

Common Mistakes

  • Assuming a list stores its elements’ actual values contiguously, like a C array — it stores contiguous pointers; the values themselves live elsewhere on the heap.
  • Reaching for a list when the collection is genuinely fixed and never changes — a tuple is more appropriate and slightly more memory-efficient (see 5.4 Sequence Data Types).
  • Expecting append() to be uniformly O(1) with zero variance — it’s O(1) amortized; the occasional resize underneath is O(n), it’s just rare enough not to matter in aggregate.

Add More Questions to This Guide

Know a question that should be here? Share it and help the community!

Open Google Form