A Short Lane to len() in Python

Programming | November 15, 2025 | Samin Yeasar

In Python, we get the size of a built-in object using len(x), not x.len(). This is a deliberate choice in CPython, the reference Python implementation. It balances speed and language consistency.

Fast-Path Optimization in CPython

For built-in types like list, str, tuple, bytes, and memoryview, calling len() does not invoke a Python method. CPython uses a C-level shortcut. All variable-sized built-ins use a C struct called PyVarObject. This struct has a field called ob_size that stores the number of elements. When we call len(x) on a built-in, CPython just reads ob_size. It does not look up a method or run Python bytecode. This makes len() very fast, which is important because we often check lengths in Python programs.

PyVarObject and ob_size

Many built-in objects use the PyVarObject struct:

typedef struct {
      PyObject ob_base;
      Py_ssize_t ob_size;  // number of elements
  } PyVarObject;

The ob_size field holds the length of the object. For built-ins, len(list_object) returns list_object->ob_size. For example, len([1, 2, 3]) reads ob_size directly. There is no method call, no attribute lookup, and no extra overhead. It is just one memory read.

Why User-Defined Classes Don’t Get the Shortcut

Custom classes do not have a fixed C struct. Python must call their __len__() method. When we call len(obj) on a user-defined object, Python finds obj.__len__() and runs it like a normal method. This is slower than built-ins, but it keeps the API consistent.

Data Model Consistency

len() is part of Python’s data model, like abs(), iter(), and repr(). Keeping it as a function gives a uniform interface. It lets CPython optimize built-ins. It keeps Python clean and predictable. This follows The Zen of Python: “Practicality beats purity” and “Special cases aren’t special enough to break the rules.” Built-ins get a fast path under the hood, but the API stays consistent for all objects.

For built-in objects, len() directly reads ob_size. For user-defined objects, Python calls __len__(). Both return the length, but built-ins are much faster.

Source: Ramalho, L. Fluent Python: Clear, Concise, and Effective Programming. Goodreads, 2015.

Thank you for reading! 🍩