#vector #comprehension #macro #generator #python

nightly mapcomp

Python-like list comprehensions for standard containers

7 releases

0.2.2 Mar 9, 2020
0.2.1 Nov 7, 2019
0.1.3 Sep 16, 2018
0.1.2 May 1, 2018
0.1.1 Apr 16, 2018

#808 in Rust patterns


220 lines


crates.io Build Status

Python-like list comprehension via macros for the following standard containers:

  • Vec
  • HashMap
  • HashSet
  • BTreeMap
  • BTreeSet

Also provides another macro for generator comprehension.

For more info please read the documentation here.


Dual-licensed under Apache License, Version 2.0 and the MIT License.


Macros for container comprehensions similar to Python's list comprehension.

This crate adds vector, set, map, and generator comprehensions. It is meant to complement maplit which provides macro literals for the same standard containers.

# #![feature(match_default_bindings)]
# #[macro_use] extern crate mapcomp;
# fn main() {
let v = vec![3, 2, 6, 9, 5];

let even_squares = vecc![x * x; for x in v.iter(); if x % 2 == 0];

assert_eq!(even_squares, vec![4, 36]);
# }

The macro names are the same as maplit's container literal macros but with a c at the end for comprehension. There is an additional macro iterc!() for creating lazily evaluated generator expressions.

List comprehensions exist in many languages and in many styles. This crate uses the same syntax as Python's list comprehensions due to it's ease of use, readability, and established popularity. If you understand Python's list comprehension, then you understand mapcomp's comprehensions.

One minor deviation from Python's syntax is the presence of semicolons between clauses which is a limitation of Rust's macro language. Another difference is that the map comprehensions use the => token to separate the key from the value instead of a colon the way Python does it.

The for var in iteratable clause can be nested as many times as you want and the if conditional is optional after each loop clause.

# #[macro_use] extern crate mapcomp;
# fn main() {
let grid = vec![vec![-2, 5], vec![3, -7, 6], vec![4, 2]];

let v = vecc![x; for row in grid; if row.len() < 3; for x in row; if x > 0];

assert_eq!(v, vec![5, 4, 2]);
# }

No runtime deps