NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
crates.io · #13 most downloaded on crates.io
Extra iterator adaptors, iterator methods, free functions, and macros.
Last release 3 months ago
16 Jun 2026
Ships fairly regularly
a new release about every 6 months
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
12 years old
131 releases · first in 2014
chore: Release itertools version 0.15.0
chore: Release itertools version 0.15.0
Position as struct instead of enum (#1042, #1043)all_equal_value's error type (#1032)*_with_hasher adaptors (#1007)Clone bounds from tuple_combinations and array_combinations(#1011)must_use for collect_vec (#1009)izip! temporary friendly (#1021)array_combinations_with_replacement (#1033)Debug for remaining public types (#1038)ExactlyOneError::count (#1046)PeekingNext for more types, in particular vec::IntoIter (#1059, #1073)PadUsing::next_back (#1082)[circular_]array_windows, deprecate tuple_windows (#1086)tuple_combinations (replaced by array_combinations) (#1085)into_group_map code more idiomatic (#1027)One column per quarter.
chore: Release itertools version 0.14.0
chore: Release itertools version 0.14.0
cons_tuples (#988)array_combinations (#991)k_smallest_relaxed and variants (#925)next_array and collect_array (#560)DoubleEndedIterator for FilterOk (#948)DoubleEndedIterator for FilterMapOk (#950)Q: ?Sized in Itertools::contains (#971)chain! (#943)into_group_map_by documentation (#1000)tree_reduce documentation (#955)merge_join_by (#966)take_while_inclusive (#972)find_or_last and find_or_first (#984)tuple_combinations (#945)track_caller attr for asser_equal (#976)default_features in Cargo.toml to default-features (#985)Prepare v0.13.0 release
Prepare v0.13.0 release (#937)
DoubleEndedIterator for ConsTuples (#853)MultiProduct fused and fixed on an empty iterator (#835, #834)iproduct! to return tuples for maxi one iterator too (#870)PutBack::put_back to return the old value (#880)repeat_call, Itertools::{foreach, step, map_results, fold_results} (#878)TakeWhileInclusive::new (#912)Itertools::{smallest_by, smallest_by_key, largest, largest_by, largest_by_key} (#654, #885)Itertools::tail (#899)DoubleEndedIterator for ProcessResults (#910)Debug for FormatWith (#931)Itertools::get (#891)Itertools::group_by (renamed chunk_by) (#866, #879)unfold (use std::iter::from_fn instead) (#871)GroupingMapBy (#873, #876)Fn bounds to FnMut in diff_with, Itertools::into_group_map_by (#886)Debug/Clone bounds for MapInto (#889)use_alloc feature (#887)Itertools::set_from (#888)README.md (#890)Cargo.toml (#894)Itertools::k_smallest on short unfused iterators (#900)Itertools::tree_fold1 (renamed tree_reduce) (#895)GroupingMap::fold_first (renamed reduce) (#902)Itertools::k_smallest(0) to consume the iterator, optimized Itertools::k_smallest(1) (#909)Combinations::nth (#914)MergeBy::fold (#920)CombinationsWithReplacement::nth (#923)FlattenOk::{fold, rfold} (#927)Powerset::nth (#924)assert_equal for iterators longer than i32::MAX (#932)must_use message of non-lazy KMergeBy and TupleCombinations (#939)CONTRIBUTING.md (#767)chore: Release itertools version 0.12.1
chore: Release itertools version 0.12.1
Itertools::[tuple_]combinations (#822)iterate (#842)Clone and Debug for Diff (#845)Debug for WithPosition (#859)Eq for MinMaxResult (#838)From<EitherOrBoth<A, B>> for Option<Either<A, B>> (#843)PeekingNext for RepeatN (#855)CoalesceBy lazy (#801)Filter[Map]Ok::next, Itertools::partition, Unique[By]::next[_back] (#818)Itertools::find_position (#837)Positions::next[_back] (#816)ZipLongest::fold (#854)Debug bounds for GroupingMapBy (#860)ExactlyOneError::fold (#826)Interleave[Shortest]::fold (#849)MultiPeek::fold (#820)PadUsing::[r]fold (#825)PeekNth::fold (#824)Positions::[r]fold (#813)PutBackN::fold (#823)RepeatN::[r]fold (#821)TakeWhileInclusive::fold (#851)ZipLongest::rfold (#848)clippy in CI (#740)rustdoc in CI (#840)chore: Release itertools version 0.12.0
chore: Release itertools version 0.12.0
take_while_inclusive consume iterator by value (#709)Clone bound to Unique (#777)Itertools::try_len (#723)sort_unstable (#796)GroupMap::fold_with (#778, #785)PeekNth::{peek_mut, peek_nth_mut} (#716)PeekNth::{next_if, next_if_eq} (#734)(Option<A>,Option<B>) to EitherOrBoth (#713)Either<A, B> to EitherOrBoth<A, B> (#715)ExactSizeIterator for Tuples (#761)ExactSizeIterator for (Circular)TupleWindows (#752)EitherOrBoth<T> a shorthand for EitherOrBoth<T, T> (#719)#[must_use] annotations on iterator adaptors (#794)Combinations lazy (#795)Intersperse(With) lazy (#797)Permutations lazy (#793)Product lazy (#800)TupleWindows lazy (#602)Combinations::{count, size_hint} (#729)CombinationsWithReplacement::{count, size_hint} (#737)Powerset::fold (#765)Powerset::count (#735)TupleCombinations::{count, size_hint} (#763)TupleCombinations::fold (#775)WhileSome::fold (#780)WithPosition::fold (#772)ZipLongest::fold (#774){min, max}_set* operations require alloc feature, instead of std (#760)tree_fold1 (#787)permutations (#724)multiunzip (#770)Permutations (#739, #748, #790)Merge/MergeBy/MergeJoinBy implementations (#736)Permutations::size_hint (#739)rustfmt in CI (#751)cargo hack to check MSRV (#754)chore: Release itertools version 0.11.0
chore: Release itertools version 0.11.0
Itertools::merge_join_by also accept functions returning bool (#704)PeekingNext transitively over mutable references (#643)with_position to yield (Position, Item) instead of Position<Item> (#699)Itertools::take_while_inclusive (#616)PeekingNext for PeekingTakeWhile (#644)EitherOrBoth::{just_left, just_right, into_left, into_right, as_deref, as_deref_mut, left_or_insert, right_or_insert, left_or_insert_with, right_or_insert_with, insert_left, insert_right, insert_both} (#629)Clone for CircularTupleWindows (#686)Clone for Chunks (#683)Itertools::process_results (#680)Cell instead of RefCell in Format and FormatWith (#608)Itertools::max_set_by_key (#692)Cargo.toml (#672)equal with Iterator::eq (#591)- Maintenance
Add EitherOrBoth::or and EitherOrBoth::or_else
EitherOrBoth::or and EitherOrBoth::or_else (#593)
min_set, max_set et al. (#613, #323)either/use_std (#628)(cargo-release) itertools version 0.10.3
(cargo-release) itertools version 0.10.1
(cargo-release) itertools version 0.10.1
Itertools::contains (#514)
Itertools::counts_by (#515)Itertools::partition_result (#511)Itertools::all_unique (#241)Itertools::duplicates and Itertools::duplicates_by (#502)chain! (#525)Itertools::at_most_one (#523)Itertools::flatten_ok (#527)EitherOrBoth::or_default (#583)Itertools::find_or_last and Itertools::find_or_first (#535)FusedIterator for FilterOk, FilterMapOk, InterleaveShortest, KMergeBy, MergeBy, PadUsing, Positions, Product , RcIter, TupleWindows, Unique, UniqueBy, Update, WhileSome, Combinations, CombinationsWithReplacement, Powerset, RepeatN, and WithPosition (#550)FusedIterator for Interleave, IntersperseWith, and ZipLongest (#548)Undeprecate Itertools::fold_while
Itertools::powerset (#335)Itertools::sorted_unstable, Itertools::sorted_unstable_by, and Itertools::sorted_unstable_by_key (#494)Error for ExactlyOneError (#484)Itertools::fold_while (#476)use_alloc feature for users who have alloc, but not std (#474)Itertools::k_smallest (#473)Itertools::into_grouping_map and GroupingMap (#465)Itertools::into_grouping_map_by and GroupingMapBy (#465)Itertools::counts (#468)DoubleEndedIterator for Unique (#442)DoubleEndedIterator for UniqueBy (#442)DoubleEndedIterator for Zip (#346)Itertools::multipeek (#435)Itertools::dedup_with_count and DedupWithCount (#423)Itertools::dedup_by_with_count and DedupByWithCount (#423)Itertools::intersperse_with and IntersperseWith (#381)Itertools::filter_ok and FilterOk (#377)Itertools::filter_map_ok and FilterMapOk (#377)Itertools::fold_results, use Itertools::fold_ok instead (#377)Itertools::map_results, use Itertools::map_ok instead (#377)FoldResults, use FoldOk instead (#377)MapResults, use MapOk instead (#377)Itertools::circular_tuple_windows and CircularTupleWindows (#350)peek_nth and PeekNth (#303)Fix potential overflow in MergeJoinBy::size_hint
MergeJoinBy::size_hint (#385)
derive(Clone) where possible (#382)try_collect method (#394)HomogeneousTuple trait (#389)combinations(0) and combinations_with_replacement(0) (#383)ParitalEq to the Item of DedupBy (#397)PutBack adaptor and on the MergeJoinBy iterator (#372)position_* methods (#412)Hash for EitherOrBoth (#417)Use slice::iter instead of into_iter to avoid future breakage (#378, by @LukasKalbertodt)
slice::iter instead of into_iter to avoid future breakage (#378, by @LukasKalbertodt)Added a `.exactly_one()` iterator method that, on success, extracts the single value of an iterator ; by @Xaeroxe
.exactly_one() iterator method that, on success, extracts the single value of an iterator ; by @Xaeroxe
Added combinatory iterator adaptors:
[0, 1, 2].iter().permutations(2) yields
[
vec![0, 1],
vec![0, 2],
vec![1, 0],
vec![1, 2],
vec![2, 0],
vec![2, 1],
]
; by @tobz1000
.combinations_with_replacement(k):
[0, 1, 2].iter().combinations_with_replacement(2) yields
[
vec![0, 0],
vec![0, 1],
vec![0, 2],
vec![1, 1],
vec![1, 2],
vec![2, 2],
]
; by @tommilligan
For reference, these methods join the already existing .combinations(k):
[0, 1, 2].iter().combinations(2) yields
[
vec![0, 1],
vec![0, 2],
vec![1, 2],
]
Improved the performance of .fold()-based internal iteration for the .intersperse() iterator ; by @jswrenn
Added .dedup_by(), .merge_by() and .kmerge_by() adaptors that work like .dedup(), .merge() and .kmerge(), but taking an additional custom comparison closure parameter. ; by @phimuemue
Improved the performance of .all_equal() ; by @fyrchik
Loosened the bounds on .partition_map() to take just a FnMut closure rather than a Fn closure, and made its implementation use internal iteration for better performance ; by @danielhenrymantilla
Added convenience methods to EitherOrBoth elements yielded from the .zip_longest() iterator adaptor ; by @Avi-D-coder
Added .sum1() and .product1() iterator methods that respectively try to return the sum and the product of the elements of an iterator when it is not empty, otherwise they return None ; by @Emerentius
Deprecate .foreach() in favour of std's .for_each()
.map_into() for conversions using Into by @vorner
Itertools docs by @JohnHeitmann.sorted_by_by_key() is now an iterator, not a Vec.izip!(x, y) macro with exactly two arguments is now the usual Iterator::zip..flatten() in favour of std's .flatten().foreach() in favour of std's .for_each().step() in favour of std's .step_by()repeat_call in favour of std's repeat_with.fold_while() in favour of std's .try_fold()Add convenience methods to EitherOrBoth, making it more similar to Option and Either by @jethrogb
EitherOrBoth, making it more similar to Option and Either by @jethrogb- No changes.
New inclusion policy: See the readme about suggesting features for std before accepting them in itertools.
FoldWhile type now implements Eq and PartialEq by @jturner314Add new iterator method .tree_fold1() which is like .fold1() except items are combined in a tree structure (see its docs). By @scottmcm
.tree_fold1() which is like .fold1() except items are combined in a tree structure (see its docs). By @scottmcm
Debug impls by @phimuemue: KMerge, KMergeBy, MergeJoinBy, ConsTuples, Intersperse, ProcessResults, RcIter, Tee, TupleWindows, Tee, ZipLongest, ZipEq, Zip.Add new iterator method .into_group_map() -> HashMap > which turns an iterator of (K, V) elements into such a hash table, where values are grouped by
.into_group_map() -> HashMap<K, Vec<V>> which turns an iterator of (K, V) elements into such a hash table, where values are grouped by key. By @tobz1000
flatten for the .flatten() adaptor. NOTE: recent Rust nightlies have Iterator::flatten and thus a clash with our flatten adaptor. One workaround is to use the itertools flatten free function.Add new adaptor .multi_cartesian_product() which is an n-ary product iterator by @tobz1000
.multi_cartesian_product() which is an n-ary product iterator by @tobz1000
.sorted_by_key() by @Xion.count() for .unique() and .unique_by().multipeek() now implements PeekingNext, by @nicopap.
.multipeek() now implements PeekingNext, by @nicopap.Add new adaptor .update() by @lucasem; this adaptor is used to modify an element before passing it on in an iterator chain.
.update() by @lucasem; this adaptor is used to modify an element before passing it on in an iterator chain.Add new method .collect_tuple() by @matklad; it makes a tuple out of the iterator's elements if the number of them matches exactly.
.collect_tuple() by @matklad; it makes a tuple out of the iterator's elements if the number of them matches exactly.
fold and collect for .map_results() which means it reuses the code of the standard .map() for these methods.Add new adaptor .merge_join_by by @srijs; a heterogeneous merge join for two ordered sequences.
.merge_join_by by @srijs; a heterogeneous merge join for two ordered sequences.Iterator adaptors and iterators in itertools now use the same must_use reminder that the standard library adaptors do, by @matematikaedit and @bluss *
must_use reminder that the standard library adaptors do, by @matematikaedit and @bluss “iterator adaptors are lazy and do nothing unless consumed”.Removed deprecated constructor Zip::new — use izip!() or multizip()
izip!() by @krdln
izip!() is now a wrapper for repeated regular .zip() and a single .map(). This means it optimizes as well as the standard library .zip() it uses. Note: multizip and izip!() are now different! The former has a named type but the latter optimizes better..unique()no_std support, which is opt-in!
izip!() or .format() or .merge(), but not those that use collections.group_by's PartialEq by @Phlosioneer and repeat_call's FnMut.Zip::new — use izip!() or multizip()Fix bug in .cartesian_product()'s fold (which only was visible for unfused iterators).
.cartesian_product()'s fold (which only was visible for unfused iterators).Add specific fold implementations for .cartesian_product() and cons_tuples(), which improves their performance in fold, foreach, and iterator consumer
fold implementations for .cartesian_product() and cons_tuples(), which improves their performance in fold, foreach, and iterator consumers derived from them.Add iterator adaptor .positions(predicate) by @tmccombs
.positions(predicate) by @tmccombsAdd function process_results which can “lift” a function of the regular values of an iterator so that it can process the Ok values from an iterator of
process_results which can “lift” a function of the regular values of an iterator so that it can process the Ok values from an iterator of Results instead, by @shepmaster
.concat() which combines all iterator elements into a single collection using the Extend trait, by @srijsBetter size hint testing and subsequent size hint bugfixes by @rkarp. Fixes bugs in product, interleave_shortest size hints.
interleave_shortest size hints.
.all_equal() by @phimuemueDeprecated names were removed in favour of their replacements
.flatten() does not implement double ended iteration anymore.fold_while() uses &mut self and returns FoldWhile<T>, for composability #168.foreach() and .fold1() use self, like .fold() does..combinations(0) now produces a single empty vector. #174Add itertools method .kmerge_by() (and corresponding free function)
.kmerge_by() (and corresponding free function)
.kmerge() and .minmax() to PartialOrd.Add multipeek method .reset_peek()
.reset_peek()
Add iterator adaptor .peeking_take_while() and its trait PeekingNext.
.peeking_take_while() and its trait PeekingNext.Add iterator adaptor .with_position()
.with_position()
VecDeque.- Add .map_results()
.map_results()Add free function constructor repeat_n. RepeatN::new is now deprecated.
Debug
repeat_n. RepeatN::new is now deprecated.Add infinite generator function iterate, that takes a seed and a closure.
iterate, that takes a seed and a closure.Special-cased .fold() for flatten and put back. .foreach() now uses fold on the iterator, to pick up any iterator specific loop implementation.
.fold() for flatten and put back. .foreach() now uses fold on the iterator, to pick up any iterator specific loop implementation.
.combinations(n) asserts up front that n != 0, instead of running into an error on the second iterator element.Add .tuples:: () that iterates by two, three or four elements at a time (where T is a tuple type).
.tuples::<T>() that iterates by two, three or four elements at a time (where T is a tuple type).
.tuple_windows::<T>() that iterates using a window of the two, three or four most recent elements..next_tuple::<T>() method, that picks the next two, three or four elements in one go..interleave() now has an accurate size hint.Workaround module/function name clash that made racer crash on completing itertools. Only internal changes needed.
combinations is now tuple_combinations
combinations is now tuple_combinationscombinations_n to combinationsgroup_by_lazy, chunks_lazy to group_by, chunksUnfold::new to unfold()RepeatCall::new to repeat_call()Zip::new to multizipPutBack::new, PutBackN::new to put_back, put_back_nPutBack::with_value is now a builder setter, not a constructorMultiPeek::new, .multipeek() to multipeek()format to format_with and format_default to format.into_rc() to rciterPartition enum is now Eitheritertools::structs but also reexported to the top level, for backwards compatibilityitertools::free will be removed in the next versionZipSlices, use .zip() instead.enumerate_from(), ZipTrusted, due to being unstable.mend_slices(), moved to crate oddsoddslinspace(), moved to crate itertools-num.sort_by(), use .sorted_by().is_empty_hint(), use .size_hint().dropn(), use .dropping().map_fn(), use .map().slice(), use .take() / .skip()miscnew constructors on iterator structs, use Itertools trait or free functions insteaditertools::size_hint is now privateformat and format_with helpers now panic if you try to format them more than once.repeat_call is not double ended anymorecons_tuplesEither from the either crate. Either<L, R> is an iterator when L, R are.MinMaxResult now implements Copy and Clonetuple_combinations supports 1-4 tuples of combinations (previously just 2)Nothing published for this version
Nothing published for this version
Improve .step(n) slightly to take advantage of specialized Fuse better.
.minmax_by()
itertools::free::cloneditertools::free::rciter.step(n) slightly to take advantage of specialized Fuse better.Only changes related to the "unstable" crate feature. This feature is more or less deprecated.
.enumerate_from() will be removed imminently since it's using a deprecated libstd trait.Fix bug in .kmerge() that caused it to often produce the wrong order #134
.kmerge() that caused it to often produce the wrong order #134Improve precision of the interleave_shortest adaptor's size hint (it is now computed exactly when possible).
interleave_shortest adaptor's size hint (it is now computed exactly when possible).Fixup on top of the workaround in 0.4.14. A function in itertools::free was removed by mistake and now it is added back again.
itertools::free was removed by mistake and now it is added back again.Workaround an upstream regression in a Rust nightly build that broke compilation of of itertools::{interleave, merge}
itertools::free::{interleave, merge}Add .minmax() and .minmax_by_key(), iterator methods for finding both minimum and maximum in one scan.
.minmax() and .minmax_by_key(), iterator methods for finding both minimum and maximum in one scan.
.format_default(), a simpler version of .format() (lazy formatting for iterators).Add .zip_eq(), an adaptor like .zip() except it ensures iterators of inequal length don't pass silently (instead it panics).
.zip_eq(), an adaptor like .zip() except it ensures iterators of inequal length don't pass silently (instead it panics).
.fold_while(), an iterator method that is a fold that can short-circuit..partition_map(), an iterator method that can separate elements into two collections.Add .get() for Stride{,Mut} and .get_mut() for StrideMut
.get() for Stride{,Mut} and .get_mut() for StrideMutImprove performance of .kmerge()
.kmerge()Add k-ary merge adaptor .kmerge()
.kmerge()
.islice() with ranges a..b where a > b.Implement Clone, Debug for Linspace
Clone, Debug for LinspaceAdd function diff_with() that compares two iterators
diff_with() that compares two iterators
.combinations_n(), an n-ary combinations iteratorPutBack::with_value and PutBack::into_parts.Add module itertools::free with free function variants of common iterator adaptors and methods. For example enumerate(iterable), rev(iterable), and so
.sorted()
itertools::free with free function variants of common iterator adaptors and methods. For example enumerate(iterable), rev(iterable), and so on.Your coding agent can read these notes before it upgrades. Set up the MCP server →