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
Person
objects - Unpack each
Person
tuple 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
persons
vector into an iterator and iterate over thePerson
objects - 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
map
andfilter
functions in most cases. - Rust's
map
andfilter
functions show that Rust is more functional than Python in its syntax.