Fundamentals 7 min read

10 Practical Scenarios of Lazy Evaluation and Infinite Sequences in Python

This article explains lazy evaluation in functional programming and presents ten Python code examples that demonstrate how generators and iterators can efficiently handle infinite sequences and large‑scale data by computing values only when needed.

Test Development Learning Exchange
Test Development Learning Exchange
Test Development Learning Exchange
10 Practical Scenarios of Lazy Evaluation and Infinite Sequences in Python

Lazy evaluation is a key concept in functional programming where computation is deferred until the result is required, providing memory and performance benefits especially for infinite sequences and large data sets.

1. Generating the Fibonacci sequence

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

fib = fibonacci()
for i in range(10):
    print(next(fib))  # Output: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34

Using a generator function allows the Fibonacci sequence to be produced indefinitely without pre‑computing all values.

2. Generating an infinite natural numbers sequence

def natural_numbers():
    n = 1
    while True:
        yield n
        n += 1

numbers = natural_numbers()
for i in range(10):
    print(next(numbers))  # Output: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10

This generator yields natural numbers forever, producing each number only when requested.

3. Using a generator expression to process large data

data = [1, 2, 3, 4, 5, ...]  # large‑scale data
result = (x * 2 for x in data if x % 2 == 0)
for value in result:
    print(value)

The generator expression computes each result lazily, avoiding loading the entire dataset into memory.

4. Lazy reading of a large file

def read_large_file(file_path):
    with open(file_path, 'r') as file:
        for line in file:
            yield line

lines = read_large_file('large_file.txt')
for line in lines:
    process_line(line)

Reading a file line‑by‑line with a generator prevents the whole file from being loaded at once.

5. Generating squares of an infinite sequence

squares = (x**2 for x in natural_numbers())
for i in range(10):
    print(next(squares))  # Output: 1, 4, 9, 16, 25, 36, 49, 64, 81, 100

The generator expression lazily produces the squares of natural numbers.

6. Lazy prime number filtering

def primes():
    primes_list = []
    yield 2
    for n in natural_numbers():
        if all(n % p != 0 for p in primes_list):
            primes_list.append(n)
            yield n

prime_gen = primes()
for i in range(10):
    print(next(prime_gen))  # Output: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29

This generator yields prime numbers on demand, calculating each only when needed.

7. Lazy computation of the n‑th Fibonacci number

def fibonacci(n):
    a, b = 0, 1
    for _ in range(n):
        a, b = b, a + b
    return a

fib_n = fibonacci(10)  # Compute only the 10th term
print(fib_n)  # Output: 55

Only the required term is computed, avoiding the full sequence generation.

8. Lazy processing of elements in an infinite sequence

def process_infinite_sequence(seq):
    for item in seq:
        process_item(item)
        if should_stop(item):
            break

infinite_seq = natural_numbers()
process_infinite_sequence(infinite_seq)

The loop processes items lazily and can stop early based on a condition.

9. Lazy chunked processing of large data

def process_large_data(data):
    chunk_size = 1000
    for i in range(0, len(data), chunk_size):
        chunk = data[i:i+chunk_size]
        process_chunk(chunk)

large_data = [1, 2, 3, 4, 5, ...]  # large‑scale data
process_large_data(large_data)

Using a generator‑like approach, data is handled in manageable chunks rather than all at once.

10. Lazy accumulation of an infinite sequence

def accumulate(seq):
    total = 0
    for item in seq:
        total += item
        yield total

numbers = natural_numbers()
accumulated = accumulate(numbers)
for i in range(10):
    print(next(accumulated))  # Output: 1, 3, 6, 10, 15, 21, 28, 36, 45, 55

This generator yields the running total of an infinite sequence, computing each sum only when requested.

These examples demonstrate how generators and iterators enable lazy evaluation, allowing efficient handling of infinite sequences and large data sets while conserving memory and computational resources.

Pythonlazy-evaluationGeneratorsMemory EfficiencyInfinite Sequences
Test Development Learning Exchange
Written by

Test Development Learning Exchange

Test Development Learning Exchange

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.