List comprehensions vs map/filter
One of Python's most popular features is its list comprehensions. They are a concise way to create
lists from existing lists. Rust is more functional than Python, so it has a similar feature called
map and filter. Although map and filter functions are availble in Python, they are not as
commonly used as list comprehensions.
Python
Consider the following function in which we print a message depending on which persons from
a list of Person objects are born after the year 1995, based on their current age.
def run7() -> None:
"""
1. List comprehensions
"""
persons = [Person("Issa", 39), Person("Ibrahim", 26)]
persons_born_after_1995 = [
(person.name, person.age) for person in persons if approx_year_of_birth(person) > 1995
]
print(f"Persons born after 1995: {persons_born_after_1995}")
The list comprehension in the above function essentially does the following:
- Iterate over the list of
Personobjects - Unpack each
Persontuple into their name and age - For each person, check if their approximate year of birth is greater than 1995
Running the above function via main.py gives us the following output:
Persons born after 1995: [('Ibrahim', 26)]
Rust
We can define the below function in Rust, where we print a message depending on which persons from
a vector of Person objects are born after the year 1995, based on their current age.
fn run7() {
let persons = vec![Person::new("Issa", 39), Person::new("Ibrahim", 26)];
let result = persons
.into_iter()
.filter(|p| approx_year_of_birth(p) > 1995)
.map(|p| (p.name, p.age))
.collect::<Vec<(String, u8)>>();
println!("Persons born after 1995: {:?}", result)
The filter and map functions in the above function essentially do the following:
- Turn the
personsvector into an iterator and iterate over thePersonobjects - For each person, check if their approximate year of birth is greater than 1995
- If the above condition is true, then create a tuple of their name and age
- Collect all the tuples into a vector of unsigned 8-bit integers
Running the function via main.rs gives us the same output as in Python:
Persons born after 1995: [("Ibrahim", 26)]
The Rust version is a little more verbose than the Python version, but it's still quite readable.
Takeaways
- Both Python and Rust have convenient ways to create iterables without having to use explicit loops.
- Python's list comprehensions are more concise than Rust's
mapandfilterfunctions in most cases. - Rust's
mapandfilterfunctions show that Rust is more functional than Python in its syntax.