Understanding Comprehensions in Python

Understanding  Comprehensions in Python

Image by Pierre Blaché from Pixabay

Comprehensions are one of the most powerful tools in Python. They allow Python programmers to write clean and concise code in a Pythonic way. They increase code readability while keeping it short and maintainable. In Python there are different types of comprehensions. In this article, we will explore all of them.

List Comprehensions

The most common and widely used type of comprehension is the list comprehension. List comprehensions allow us to create a new list from an existing sequence. The basic syntax of a list comprehension is as follows:

[expression for item in sequence]

Here, sequence can be any iterable Python sequence. item represents individual values from the sequence, and expression produces the value for the new list. Below is an example:

seq = [item for item in range(10)]
print(seq)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

You can also filter out items using an optional if statement. For the above example, we can take only the even numbers while constructing the new list. Only items that satisfy the condition are included:

seq = [item for item in range(10) if item % 2 == 0]
print(seq)
# [0, 2, 4, 6, 8]

You can also use an else block inside the list comprehension, but it must be in the expression part. In the example below, we mark items as even or odd using a list comprehension:

seq = ["even" if item % 2 == 0 else "odd" for item in range(10)]
print(seq)
# ['even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd']

Set Comprehensions

Similar to list comprehensions, you can use set comprehensions to create a new set data structure from a sequence. The only difference is that you must use curly braces ({}) instead of square braces ([]). The resulting set contains unique elements from the sequence.

seq = {item for item in range(10)}
print(seq)
# {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

Like list comprehensions, you can use an optional if condition in set comprehensions. In the following example, you can create a set of unique even numbers from a list containing duplicate elements.

alist = [1, 2, 3, 4, 5, 3, 2, 5, 6, 7, 8, 9, 0]
seq = {item for item in alist if item % 2 == 0}
print(seq)
# {0, 2, 4, 6, 8}

The only catch is that elements in the set are not ordered as in the original list. For ordered collections, you can use dictionary comprehensions, which maintain insertion order (Python 3.7+).

Dictionary Comprehensions

A dictionary comprehension is another short and concise way to create a dictionary from a sequence. For a dictionary comprehension, you must use curly braces and define key-value pair expressions. You can also use an optional if condition in a dictionary comprehension.

{key_expression: value_expression for item in sequence if condition}

Here is an example,

seq = {f"key-{item}": item for item in range(5)}
print(seq)
# {'key-0': 0, 'key-1': 1, 'key-2': 2, 'key-3': 3, 'key-4': 4}

You can also use an if condition with dictionary comprehensions to filter data. Additionally, you can use function or method calls in the key and value expressions.

cities = ["New York", "Los Angeles", "Chicago", "Houston", "Phoenix"]
seq = {index: city.upper() for index, city in enumerate(cities)}
print(seq)
# {0: 'NEW YORK', 1: 'LOS ANGELES', 2: 'CHICAGO', 3: 'HOUSTON', 4: 'PHOENIX'}

Generator Comprehensions

So far, we have discussed three types of comprehensions, and all of them have one common characteristic: they are eager loading in terms of memory usage. This means Python loads the entire list into memory, which is safe for small and medium-sized data. But this approach won’t work when you need to process large amounts of data.

When the size of the list becomes problematic, you can use a generator comprehension instead of a list comprehension. You can pass the generator comprehension directly to a function call, using parentheses instead of square braces.

Generator comprehensions use lazy evaluation while processing data. They load a single item into memory, process it, and then discard it to load the next item. Because of this, you can process very large datasets without creating memory issues.

data = sum(value for value in range(1_000_000_000))
print(data)
# 499999999500000000

Conclusion

Comprehensions are one of the most useful tools in Python. They allow you to write concise code while keeping it readable and maintainable. You can use any type of comprehension according to your needs. If you work on a feature that is memory-critical, you should choose generator comprehensions. When memory is not a problem, you can use any other comprehensions.


References
  1. When to Use a List Comprehension in Python
  2. List Comprehension in Python
  3. Python Comprehensions: A Guide to Writing Clean and Efficient Code
  4. Python Comprehensions

Recent posts

LinkedIn
Reddit
Telegram