Crates.io | iter-python |
lib.rs | iter-python |
version | 0.10.1 |
source | src |
created_at | 2019-03-10 00:47:32.514635 |
updated_at | 2021-12-12 20:21:44.227431 |
description | Python generator expressions and 'list' comprehensions |
homepage | https://github.com/danielhenrymantilla/iter-python-rs |
repository | https://github.com/danielhenrymantilla/iter-python-rs |
max_upload_size | |
id | 119691 |
size | 19,754 |
Python generator expressions (
i!
) and "list" comprehensions (v!
)
Add the following line to your Cargo.toml
, under [dependencies]
:
iter-python = "0.10.0"
Bring i!
and (enhanced) v!
ec into scope in you Rust code with:
use ::iter_python::prelude::*;
use ::iter_python::prelude::{*,
// Not necessary, but since `v` supersedes stdlib's `vec`'s API,
// you can do this if you feel like it.
v as vec,
};
fn main ()
{
// `i!` macro for comprehension "lists" (iterators):
let infinite_odds = || i!(2 * n + 1 for n in 0..);
let sums_of_odds = i!(infinite_odds().take(n).sum() for n in 1..);
assert!(sums_of_odds.take(100).all(is_square));
/* The above may be suprising, but is an obvious mathematical property
once we represent it as:
1> 1 3 5 M-1
| | |
3> 1---2 4 M-#
| |
5> 1---2---3 M-n
|
M> 1---#---n---n+1 where M=2n+1
*/
// `v!` macro: like `vec!`, but supporting `i!`'s input as well.
let v = v![
2 * x
for &x_opt in &[None, Some(21), None]
if let Some(x) = x_opt
];
assert_eq!(
dbg!(v),
vec![42], // `v!` does indeed feature classic `vec!` semantics.
);
// A more advanced example: generate the following string…
const MATRIX: &str = "\
+-----+-----+-----+-----+-----+
| a11 | a12 | a13 | a14 | a15 |
| a21 | a22 | a23 | a24 | a25 |
| a31 | a32 | a33 | a34 | a35 |
| a41 | a42 | a43 | a44 | a45 |
| a51 | a52 | a53 | a54 | a55 |
+-----+-----+-----+-----+-----+";
const N: usize = 6;
// … using only one allocation!
// This is achieved by combining lazy iterators (`i!`) with
// "lazy strings" / lazy `Display`ables: `lazy_format!`.
use ::iter_python::macros::lazy_format; // prelude provides it as `f!`
let line = || lazy_format!(
"+-{}-+",
"-+-".join(i!("---" for _ in 1..N))
);
let top_line = line();
let body = "\n".join(i!(
lazy_format!(
"| {} |",
" | ".join(i!(f!("a{i}{j}") for j in 1..N)),
)
for i in 1..N
));
let bottom_line = line();
// Heap-allocation and iterator consumption occurs here:
let matrix = format!("{top_line}\n{body}\n{bottom_line}");
assert_eq!(matrix, MATRIX);
}
fn is_square (n: u32)
-> bool
{
n == ((n as f64).sqrt().trunc() as u32).pow(2)
}
See iter!
and vec!
for more examples.
no_std
supportThis crates supports #![no_std]
, by disabling the default "std"
feature.