Python
Generators
Programming
Code Tutorial
Python Tips

How to pick just one item from a generator?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

To pick one item from a Python generator, use next(generator). This advances the generator to its first yield and returns the value. If the generator is exhausted, next() raises StopIteration — use next(generator, default) to return a default value instead. For picking a specific item, combine next() with itertools.islice() or a generator expression with a filter condition. The key advantage of using next() over converting to a list is that it does not consume the entire generator.

Basic: next()

python
1def count_up():
2    n = 1
3    while True:
4        yield n
5        n += 1
6
7gen = count_up()
8
9# Pick the first item
10first = next(gen)
11print(first)  # 1
12
13# Pick the second item (generator remembers its position)
14second = next(gen)
15print(second)  # 2
16
17# Pick the third
18third = next(gen)
19print(third)  # 3

Each call to next() advances the generator by one step. The generator retains its internal state between calls.

Handling Exhausted Generators

python
1def limited():
2    yield "a"
3    yield "b"
4
5gen = limited()
6print(next(gen))  # "a"
7print(next(gen))  # "b"
8
9# Generator is exhausted
10# next(gen)  # Raises StopIteration
11
12# Use a default value to avoid the exception
13print(next(gen, "nothing"))  # "nothing"
14print(next(gen, None))       # None

The two-argument form next(gen, default) returns the default when the generator has no more items, avoiding the need for try/except.

Pick the First Matching Item

python
1# Generator expression with a condition
2numbers = iter(range(100))
3first_even_over_50 = next(x for x in numbers if x > 50 and x % 2 == 0)
4print(first_even_over_50)  # 52
5
6# Finding a matching item in a large dataset
7def read_large_file(path):
8    with open(path) as f:
9        for line in f:
10            yield line.strip()
11
12# Stops reading as soon as the first match is found
13first_error = next(
14    (line for line in read_large_file("app.log") if "ERROR" in line),
15    "No errors found"
16)
17print(first_error)

The generator expression (x for x in gen if condition) is lazy — it only processes elements until the condition is met, then stops.

Pick the Nth Item with islice

python
1from itertools import islice
2
3def fibonacci():
4    a, b = 0, 1
5    while True:
6        yield a
7        a, b = b, a + b
8
9# Get the 10th Fibonacci number (0-indexed)
10gen = fibonacci()
11tenth = next(islice(gen, 10, 11))
12print(tenth)  # 55
13
14# Get the first 5 items as a list
15gen = fibonacci()
16first_five = list(islice(gen, 5))
17print(first_five)  # [0, 1, 1, 2, 3]
18
19# Skip the first 100 items, take the next one
20gen = fibonacci()
21item_101 = next(islice(gen, 100, 101))
22print(item_101)  # 354224848179261915075

islice(gen, start, stop) efficiently skips items without materializing them. It is the standard way to access a specific position in a generator.

Pick a Random Item

python
1import random
2from itertools import islice
3
4def data_stream():
5    for i in range(1000):
6        yield f"item-{i}"
7
8# Method 1: Reservoir sampling (O(n) memory: O(1))
9def random_from_generator(gen):
10    chosen = next(gen)
11    for i, item in enumerate(gen, start=2):
12        if random.randint(1, i) == 1:
13            chosen = item
14    return chosen
15
16result = random_from_generator(data_stream())
17print(result)  # Random item from the stream
18
19# Method 2: If you know the length, pick an index
20gen = data_stream()
21n = 1000
22idx = random.randrange(n)
23random_item = next(islice(gen, idx, idx + 1))
24print(random_item)

Reservoir sampling picks a uniformly random item from a generator of unknown length in a single pass with O(1) memory.

Pick Last Item

python
1from collections import deque
2
3def limited_gen():
4    yield 1
5    yield 2
6    yield 3
7
8# Method 1: deque with maxlen=1
9last = deque(limited_gen(), maxlen=1)[0]
10print(last)  # 3
11
12# Method 2: Loop to the end
13gen = limited_gen()
14for last_item in gen:
15    pass
16print(last_item)  # 3
17
18# Method 3: Consume and return last (functools.reduce)
19from functools import reduce
20last = reduce(lambda _, x: x, limited_gen())
21print(last)  # 3

All methods consume the entire generator. deque(gen, maxlen=1) is the most memory-efficient — it discards all but the last element.

Pick Multiple Items

python
1from itertools import islice
2
3def infinite_stream():
4    i = 0
5    while True:
6        yield f"event-{i}"
7        i += 1
8
9gen = infinite_stream()
10
11# Pick first 3
12batch1 = list(islice(gen, 3))
13print(batch1)  # ['event-0', 'event-1', 'event-2']
14
15# Pick next 3 (generator remembers position)
16batch2 = list(islice(gen, 3))
17print(batch2)  # ['event-3', 'event-4', 'event-5']
18
19# Batch processing pattern
20def batched(gen, size):
21    while True:
22        batch = list(islice(gen, size))
23        if not batch:
24            break
25        yield batch
26
27for batch in batched(infinite_stream(), 5):
28    print(batch)
29    if batch[-1] == "event-14":
30        break

Common Pitfalls

  • Converting to a list to pick one item: list(generator)[0] works but consumes the entire generator into memory. For infinite generators, this hangs forever. Use next(gen) instead — it only fetches one item.
  • Forgetting that generators are single-use: After calling next() or iterating partially, you cannot restart a generator. To iterate again, create a new generator instance. Calling next() on an exhausted generator raises StopIteration.
  • Not providing a default to next(): next(gen) raises StopIteration if the generator is empty. This is often unexpected. Use next(gen, None) or next(gen, default_value) to handle empty generators gracefully.
  • Using next() inside a for loop on the same generator: for item in gen and next(gen) both advance the same generator. Mixing them causes skipped items. Use one approach consistently or be explicit about consuming items.
  • Assuming islice returns a generator: islice returns an islice iterator, not a list. To get a single value, wrap it in next(): next(islice(gen, n, n+1)). Calling list(islice(gen, n)) returns a list of the first n items.

Summary

  • Use next(gen) to pick the first (or next) item from a generator
  • Use next(gen, default) to avoid StopIteration on empty generators
  • Use next(x for x in gen if condition) to find the first matching item
  • Use itertools.islice(gen, n, n+1) to pick the nth item without consuming the whole generator
  • Use reservoir sampling for picking a random item from a generator of unknown length
  • Generators are single-use and stateful — next() advances them permanently

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.