len() Across Types

Concepts covered: Collections

len returns how many items a collection holds, as an integer. The same call works on every collection in this track so far, and what counts as 1 item depends on the type.

Valuelen countsExampleResult
stringcharacters, including spaces and escapes`len("5K run")`6
listitems`len([312, 298])`2
tupleitems`len((38.7, -9.1))`2
dictkeys, each key-value pair once`len({"ana": 21, "ben": 42})`2
setdistinct members after duplicates drop`len({5, 10, 5})`2
rangenumbers it would produce`len(range(1, 6))`5
note = "5K run\nfelt fast"
splits = (312, 298, 305, 291, 284)
profile = {"name": "ana", "city": "Lisbon", "runs": [5, 8, 12, 21]}
cities = {"Lisbon", "Porto", "Lisbon", "Faro"}

print(len(note))
print(len(splits))
print(len(profile))
print(len(cities))
print(len(range(0, 100, 10)))

Output:

16
5
3
3
10

Two of those results catch people out. The \n escape is 1 character, so the note has length 16 even though it prints on 2 lines. The runs list inside the profile holds 4 numbers, and len(profile) is still 3 because it counts the 3 keys and never looks inside a value.

What does this program print?

profile = {"name": "ana", "runs": [5, 8, 12, 21], "tags": ("trail", "night")}
print(len(profile), len(profile["runs"]), len(profile["name"]))

Only the top level counts

len counts the items directly inside a collection. A list of 3 tuples has length 3 however long the tuples are. To count everything inside, loop over the outer collection and add up the inner lengths.

week = [
    (312, 298, 305, 291, 284),
    (330, 325),
    (301, 299, 300, 296, 294, 290, 288, 285, 280, 279),
]

print(len(week))
print(len(week[2]))

total_km = 0
for run in week:
    total_km = total_km + len(run)
print(total_km)

Output:

3
10
17

Length and indexes

A sequence of length n has valid indexes from 0 to n - 1. That is why range(len(splits)) produces exactly the indexes of splits, and why splits[len(splits)] raises IndexError: tuple index out of range. The last item sits at len(splits) - 1, the same position as -1.

Counting distinct values

A set drops duplicates, so len(set(items)) counts distinct values. Comparing it with len(items) shows whether duplicates exist, a standard check on IDs that are meant to be unique.

uploaded_ids = ["r_4821", "r_4822", "r_4821", "r_4830", "r_4822"]

print(len(uploaded_ids))
print(len(set(uploaded_ids)))
print(len(uploaded_ids) - len(set(uploaded_ids)))

Output:

5
3
2

Values with no length

A single number is 1 value, so len(1490) raises TypeError: object of type 'int' has no len(). Floats and True fail the same way. Counting the digits of a number is a question about its text form, which needs a conversion first.

Guarding a summary with len

An average divides by the length, and an empty list has length 0, so sum(x) / len(x) on it raises ZeroDivisionError: division by zero. A length check in front of the division decides what an empty input returns.

def average_split(splits):
    if len(splits) == 0:
        return 0
    return sum(splits) / len(splits)

print(average_split([312, 298, 305]))
print(average_split([]))

Output:

305.0
0

Checking a row before unpacking it

len pairs with starred assignment. The target run_id, runner, *splits needs at least 2 fields, and a row with exactly 2 unpacks to an empty splits list. This job only summarizes runs that carry at least 1 split, so it checks len(row) < 3 first, sets those rows aside and keeps going. The program combines tuples, starred assignment, len and sum.

rows = [
    ("r_4821", "ana", 312, 298, 305),
    ("r_4822", "ben"),
    ("r_4823", "caro", 330),
]

rejected = []
for row in rows:
    if len(row) < 3:
        rejected.append(row)
        continue
    run_id, runner, *splits = row
    print(run_id, runner, len(splits), sum(splits))

print("rejected:", rejected)

Output:

r_4821 ana 3 915
r_4823 caro 1 330
rejected: [('r_4822', 'ben')]

Ben's row has no splits to summarize, so the length check sets it aside. Without the check it would unpack cleanly to an empty splits list and print r_4822 ben 0 0, a 0-second run that never happened. The other rows unpack with a starred splits list of whatever length they carry, and len and sum summarize it.

About this lesson

This section is part of the Collections: Beginner lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.