DEV Community

Riko
Riko

Posted on

Understanding when to use list comprehensions vs generator expressions

List Comprehensions

List comprehensions create new lists by transforming or filtering items from another iterable (such as a dictionary, tuple, or another list). They can be read as "do this operation for each item in this collection (and sometimes, only if this condition is true)".

The syntax looks like this:

[operation(item) for item in iterable if condition(item)]

List comprehensions are useful if you need to reuse and access these lists in your code.

List Comprehension with Simple Condition

Let's say I want a list representing books I haven't read yet in my personal library. I can use a list comprehension with a simple condition:

unread_books = [book for book in books if book.status == "to_read"]
Enter fullscreen mode Exit fullscreen mode

Here, the list comprehension does not perform any operation on the individual book; it is only checking if the book's status is "to_read".

List Comprehension with Function Call

What if I want to ensure that my book titles are consistently capitalized? I can use a list comprehension that calls a function on each book title:

def fix_title(title):
    return title.strip().title()

book_titles = ['  war and peace', 'the HOBBIT ', '  dune']

cleaned_titles = [fix_title(t) for t in book_titles]
print(cleaned_titles)
# Output: ['War And Peace', 'The Hobbit', 'Dune']
Enter fullscreen mode Exit fullscreen mode

List Comprehension with a more complex condition

Let's say I want all the titles of books that are longer than 300 pages AND I've already read:

finished_long_books = [
    book.title for book in books 
    if book.status == "finished" and book.page_count > 300
]
Enter fullscreen mode Exit fullscreen mode

Generator Expressions

Generator expressions have a similar syntax as list comprehensions, but instead of creating a list, they produces items or values one at a time instead of storing a full list. This is useful if you're working with very large datasets and need to iterate over them only once.

Using generator expressions to sum values

Let's say I want to get a sum of all the pages I've read in my library:

total_pages_read = sum(book.page_count for book in books if book.status == "finished")
Enter fullscreen mode Exit fullscreen mode

Note that the generator expression is passed to sum(), which adds each book's page count together if the book's status is "finished".

Using generator expressions to print values

Let's say I just want to print the names of the authors of the books I'm currently reading and don't need to store these as a separate list:

print(*(f"{book.author}" for book in books), sep="\n")
Enter fullscreen mode Exit fullscreen mode

The generator expression is passed to print() as the first argument, which uses the unpacking operator * to print each author's name. The second argument is the separator that prints each name on a newline. This removes the need to use a for loop, iterating and printing over the authors in a single line.

Summary

List comprehensions create lists that can be reused and access in your code.

Generator expressions create generator objects that produce one value at a time, using less memory than a list.

Top comments (0)