Python

How to join two generators or other iterables in Python

25 September 2026 · 4 min read

How to join two generators or other iterables in Python

Python, renowned for its elegant syntax and powerful libraries, offers a rich ecosystem for handling data streams and sequences. One common challenge developers face is efficiently combining multiple iterables, particularly generators, which produce values on demand. This article delves into various techniques for joining two generators or other iterables in Python, exploring their nuances and providing practical examples to enhance your coding arsenal.

Using itertools.chain

The itertools module provides a powerful function called chain specifically designed for concatenating iterables. It efficiently links iterables sequentially, consuming them one after another. This approach is particularly useful when dealing with generators, as it avoids loading entire sequences into memory simultaneously.

For instance, imagine processing two large log files. Reading both files entirely into memory before combining them would be inefficient. itertools.chain allows you to process each file line by line, significantly reducing memory footprint.

python import itertools gen1 = (x for x in range(5)) gen2 = (x for x in range(5, 10)) combined = itertools.chain(gen1, gen2) for item in combined: print(item)

Leveraging List Comprehension

List comprehension offers a concise and expressive way to combine iterables into a new list. While this approach materializes the entire combined sequence in memory, it’s often suitable for smaller datasets or when subsequent operations require list functionality.

List comprehension’s readability makes it a preferred choice for simple combinations where memory consumption isn’t a primary concern. Its compact syntax simplifies the code and enhances maintainability.

python list1 = [1, 2, 3] list2 = [4, 5, 6] combined = [item for sublist in [list1, list2] for item in sublist] print(combined)

Employing the + Operator with Lists

The + operator provides a straightforward way to concatenate lists. This method is intuitive and easy to understand, but it creates a new list containing all elements, which might be less efficient for large datasets.

If memory efficiency is paramount, consider alternative approaches like itertools.chain or generator expressions. However, for smaller lists, the + operator offers a simple and effective solution.

python list1 = [1, 2, 3] list2 = [4, 5, 6] combined = list1 + list2 print(combined)

Creating a Custom Generator Function

For complex concatenation logic or situations requiring fine-grained control over the combination process, creating a custom generator function offers maximum flexibility. This approach allows you to implement custom filtering, transformations, or other operations while iterating through the input iterables.

While potentially more verbose, custom generators empower you to tailor the combination process to your specific needs, providing a robust solution for intricate scenarios.

python def combine_generators(gen1, gen2): yield from gen1 yield from gen2 gen1 = (x for x in range(3)) gen2 = (x for x in range(3, 6)) combined = combine_generators(gen1, gen2) for item in combined: print(item)

Choosing the right technique depends on factors like data size, performance requirements, and the complexity of the combination logic. For large datasets or memory-sensitive operations, itertools.chain or custom generators are generally preferred. For smaller datasets or when list functionalities are needed, list comprehension or the + operator can be suitable choices.

  • Consider memory usage when working with large datasets.
  • Choose the most readable and maintainable approach for your specific needs.
  1. Analyze your data size and performance requirements.
  2. Select the appropriate technique based on the complexity of the combination logic.
  3. Implement and test your chosen solution.

Check out more resources on itertools, Python generators, and list comprehensions.

This internal link will take you to another helpful resource.

Infographic Placeholder: A visual representation of the different methods and their memory usage characteristics.

FAQ

Q: What’s the most memory-efficient way to combine large generators?

A: itertools.chain is generally the most memory-efficient way to combine large generators, as it avoids loading the entire sequence into memory.

By understanding the strengths and weaknesses of each method, you can make informed decisions and optimize your Python code for efficiency and clarity. Experiment with the examples provided and explore further to discover the best approach for your specific use cases. Explore more advanced topics like asynchronous generators and parallel processing to further enhance your iterable manipulation skills. This knowledge empowers you to process data effectively and build robust, scalable applications.

Question & Answer :
I want to change the following code

for directory, dirs, files in os.walk(directory_1): do_something() for directory, dirs, files in os.walk(directory_2): do_something() 

to this code:

for directory, dirs, files in os.walk(directory_1) + os.walk(directory_2): do_something() 

I get the error:

unsupported operand type(s) for +: ‘generator’ and ‘generator’

How to join two generators in Python?

itertools.chain() should do it. It takes multiple iterables and yields from each one by one, roughly equivalent to:

def chain(*iterables): for it in iterables: for element in it: yield element 

Usage example:

from itertools import chain g = (c for c in 'ABC') # Dummy generator, just for example c = chain(g, 'DEF') # Chain the generator and a string for item in c: print(item) 

Output:

A B C D E F