Does Rust have an equivalent to Python's list comprehension syntax?
Asked Answered
W

4

65

Python list comprehension is really simple:

>>> l = [x for x in range(1, 10) if x % 2 == 0]
>>> [2, 4, 6, 8] 

Does Rust have an equivalent syntax like:

let vector = vec![x for x in (1..10) if x % 2 == 0]
// [2, 4, 6, 8]
Wages answered 24/7, 2017 at 14:18 Comment(0)
G
90

You can just use iterators:

fn main() {
    let v1 = (0u32..9).filter(|x| x % 2 == 0).map(|x| x.pow(2)).collect::<Vec<_>>();
    let v2 = (1..10).filter(|x| x % 2 == 0).collect::<Vec<u32>>();

    println!("{:?}", v1); // [0, 4, 16, 36, 64]
    println!("{:?}", v2); // [2, 4, 6, 8]
}
Grandparent answered 24/7, 2017 at 14:23 Comment(2)
Do you know about complexity ? Does appling filter and then map force too iterate twice and so double the computation time ?Wages
@Wages no. Iterators are lazy and process each element only once.Heidy
C
68

cute is a macro for Python-esque list and dictionary (HashMap) comprehensions in Rust.

use cute::c;

let vector = c![x, for x in 1..10, if x % 2 == 0];
Crater answered 24/7, 2017 at 14:28 Comment(3)
I had already seen this and found it really interesting but what I want is more a built-in function/syntax like @Grandparent answered.Wages
@Wages rust has a fairly lean std lib so you might not get far without additional crates.Rozier
use cute::c; now works in place of the 1st two lines. Strangely the cute manual does not mention this. The manual on changes to the use of extern does doc.rust-lang.org/edition-guide/rust-2018/path-changes.htmlForeconscious
D
-1

For anyone else looking for a python-like list\dict comprehension:

list_comprehension_macro

Python:

even_squares = [x for x in range(1, 10) if x % 2 == 0]

Rust equivalent:

let even_squares = comp![x for x in (1..10) if x % 2 == 0]

Full example

In cargo.toml:

list_comprehension_macro = "*"

Then:

use list_comprehension_macro::comp;
fn main() {
    let arr: Vec<u32> = vec![1, 2, 3, 4];
    let result = comp![x * 2 for x in arr];
}
Deloris answered 20/10, 2022 at 15:8 Comment(0)
F
-2

Since rust 2018, you can do:

use cute::c;
…

let vector = c![x, for x in 1..10, if x % 2 == 0];

see https://doc.rust-lang.org/edition-guide/rust-2018/path-changes.html for why.

Foreconscious answered 8/9, 2022 at 20:48 Comment(2)
This is better left as a comment on the answer already suggesting this crate since this doesn't provide anything new to the original question.Roach
I should also point out that #[macro_use] extern crate cute; is the "more correct" way to import the crate since even the most recent published version uses the 2015 edition. It just happens that the modern way to import also works because the macro is self-contained and doesn't rely on other items in the crate. Trying this on other 2015 edition crates with macros may not work.Roach

© 2022 - 2024 — McMap. All rights reserved.