Python Comprehensions
# Python Comprehensions: A Comprehensive Guide
Python comprehensions provide a concise, elegant, and highly readable way to construct new data structures (lists, dictionaries, sets, and generators) from existing iterables. They serve as a powerful alternative to traditional `for` loops and `map()`/`filter()` functions.
When using comprehensions, it is important to balance brevity with readability. Keep your expressions simple to ensure your codebase remains clean and maintainable.
Python supports four types of comprehensions:
1. **List Comprehensions**
2. **Dictionary (Dict) Comprehensions**
3. **Set Comprehensions**
4. **Generator Expressions** (often referred to as Tuple Comprehensions)
---
## List Comprehensions
List comprehensions allow you to construct a new list from an iterable in a single line of code.
### Syntax
```python
# Or with a conditional filter:
```
* **`expression`**: The operation or value to yield for the new list. This can also be a function call that returns a value.
* **`for item in iterable`**: The loop that iterates over the source collection.
* **`if condition`**: An optional filter. Only items for which the condition evaluates to `True` will be processed by the expression.
### Code Examples
#### Example 1: Filter and Transform Strings
Filter out names with a length of 3 or less, and convert the remaining names to uppercase:
```python
>>> names = ['Bob', 'Tom', 'alice', 'Jerry', 'Wendy', 'Smith']
>>> new_names = [name.upper() for name in names if len(name) > 3]
>>> print(new_names)
['ALICE', 'JERRY', 'WENDY', 'SMITH']
```
#### Example 2: Find Multiples of a Number
Find all integers under 30 that are divisible by 3:
```python
>>> multiples = [i for i in range(30) if i % 3 == 0]
>>> print(multiples)
[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
```
---
## Dictionary Comprehensions
Dictionary comprehensions allow you to dynamically build dictionaries using a syntax similar to list comprehensions, but with key-value pairs.
### Syntax
```python
{key_expr: value_expr for item in iterable}
# Or with a conditional filter:
{key_expr: value_expr for item in iterable if condition}
```
### Code Examples
#### Example 1: Map Strings to Their Lengths
Create a dictionary where the keys are strings from a list and the values are their respective lengths:
```python
listdemo = ['Google', 'Runoob', 'Taobao']
# Map each string to its length
>>> newdict = {key: len(key) for key in listdemo}
>>> newdict
{'Google': 6, 'Runoob': 6, 'Taobao': 6}
```
#### Example 2: Map Numbers to Their Squares
Create a dictionary mapping a tuple of numbers to their squared values:
```python
>>> dic = {x: x**2 for x in (2, 4, 6)}
>>> dic
{2: 4, 4: 16, 6: 36}
>>> type(dic)
```
---
## Set Comprehensions
Set comprehensions are syntactically identical to dictionary comprehensions but do not use key-value pairs. They automatically handle deduplication, as sets only contain unique elements.
### Syntax
```python
{expression for item in iterable}
# Or with a conditional filter:
{expression for item in iterable if condition}
```
### Code Examples
#### Example 1: Calculate Squares of Unique Numbers
Calculate the squares of the numbers 1, 2, and 3:
```python
>>> setnew = {i**2 for i in (1, 2, 3)}
>>> setnew
{1, 4, 9}
```
#### Example 2: Extract Unique Characters with Filtering
Extract unique characters from a string, excluding the characters 'a', 'b', and 'c':
```python
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
{'d', 'r'}
>>> type(a)
```
---
## Generator Expressions (Tuple Comprehensions)
While you might expect a comprehension wrapped in parentheses `()` to return a tuple, it actually returns a **Generator Object**. Generators evaluate elements lazily (on-demand), which makes them highly memory-efficient for large datasets.
### Syntax
```python
(expression for item in iterable)
# Or with a conditional filter:
(expression for item in iterable if condition)
```
### Code Example
#### Example 1: Creating a Generator and Converting to Tuple
Generate numbers from 1 to 9 using a generator expression, then convert the generator into a tuple:
```python
>>> a = (x for x in range(1, 10))
>>> a
at 0x7faf6ee20a50> # Returns a generator object
>>> tuple(a) # Convert the generator object directly into a tuple
(1, 2, 3, 4, 5, 6, 7, 8, 9)
```
---
## Considerations & Best Practices
1. **Keep It Simple**: Comprehensions are designed to simplify code. If your comprehension spans multiple lines or contains complex nested logic, a standard `for` loop is usually more readable.
2. **Memory Efficiency**: For extremely large datasets, prefer **Generator Expressions** over list comprehensions. List comprehensions build the entire list in memory immediately, whereas generators yield items one at a time.
3. **Avoid Side Effects**: Do not write expressions inside comprehensions that modify external state (e.g., appending to an external list or modifying global variables). Comprehensions should be treated as pure functional transformations.
YouTip