
    
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
            
{"version":"https:\/\/jsonfeed.org\/version\/1","title":"mathspp.com feed","home_page_url":"https:\/\/mathspp.com\/blog\/tags\/itertools","feed_url":"https:\/\/mathspp.com\/blog\/tags\/itertools.json","description":"Stay up-to-date with the articles on mathematics and programming that get published to mathspp.com.","author":{"name":"Rodrigo Gir\u00e3o Serr\u00e3o"},"items":[{"title":"itertools cheatsheet","date_published":"2026-07-13T16:28:00+02:00","id":"https:\/\/mathspp.com\/blog\/itertools-cheatsheet","url":"https:\/\/mathspp.com\/blog\/itertools-cheatsheet","content_html":"<p>Cheatsheet with visual diagrams that explain how the iterables from <code>itertools<\/code> work.<\/p>\n\n<p>This cheatsheet contains diagrams that explain how the iterables from the module <code>itertools<\/code> work in a visual way.<\/p>\n<p><a href=\"https:\/\/gumroad.com\/l\/cheatsheet-itertools\" class=\"btn btn-lg btn-center external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Download this cheatsheet<\/a><\/p>\n<p><img alt=\"A4 itertools cheatsheet shown in light and dark themes.\" class=\"dark-theme-only\" src=\"\/user\/pages\/02.blog\/itertools-cheatsheet\/_cheatsheets-light-front.webp\"><\/p>\n<p><img alt=\"A4 itertools cheatsheet shown in light and dark themes.\" class=\"light-theme-only\" src=\"\/user\/pages\/02.blog\/itertools-cheatsheet\/_cheatsheets-dark-front.webp\"><\/p>\n<p><a href=\"https:\/\/gumroad.com\/l\/itertools-uv\" class=\"btn btn-lg btn-center external-link no-image\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Download this cheatsheet<\/a><\/p>","summary":"Cheatsheet with visual diagrams that explain how the iterables from itertools work.","date_modified":"2026-07-13T16:43:09+02:00","tags":["python","programming","itertools","modules"],"image":"\/user\/pages\/02.blog\/itertools-cheatsheet\/thumbnail.webp"},{"title":"Generalising itertools.pairwise","date_published":"2025-11-24T19:36:00+01:00","id":"https:\/\/mathspp.com\/blog\/generalising-itertools-pairwise","url":"https:\/\/mathspp.com\/blog\/generalising-itertools-pairwise","content_html":"<p>In this article you will learn about itertools.pairwise, how to use it, and how to generalise it.<\/p>\n\n<p>In this tutorial you will learn to use and generalise <code>itertools.pairwise<\/code>.\nYou will understand what <code>itertools.pairwise<\/code> does, how to use it, and how to implement a generalised version for when <code>itertools.pairwise<\/code> isn't enough.<\/p>\n<h2 id=\"itertools-pairwise\"><code>itertools.pairwise<\/code><a href=\"#itertools-pairwise\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p><code>itertools.pairwise<\/code> is an iterable from the standard module <code>itertools<\/code> that lets you access overlapping pairs of consecutive elements of the input iterable.\nThat's quite a mouthful, so let me translate:<\/p>\n<blockquote>\n<p>You give <code>pairwise<\/code> an iterable, like <code>\"ABCD\"<\/code>, and <code>pairwise<\/code> gives you pairs back, like <code>(\"A\", \"B\")<\/code>, <code>(\"B\", \"C\")<\/code>, and <code>(\"C\", \"D\")<\/code>.<\/p>\n<\/blockquote>\n<p>In loops, it is common to unpack the pairs directly to perform some operation on both values.\nThe example below uses <code>pairwise<\/code> to determine how the balance of a bank account changed based on the balance history:<\/p>\n<pre><code class=\"language-py\">from itertools import pairwise  # Python 3.10+\n\nbalance_history = [700, 1000, 800, 750]\n\nfor before, after in pairwise(balance_history):\n    change = after - before\n    print(f\"Balance changed by {change:+}.\")<\/code><\/pre>\n<pre><code class=\"language-txt\">Balance changed by +300.\nBalance changed by -200.\nBalance changed by -50.<\/code><\/pre>\n<h2 id=\"how-to-implement-pairwise\">How to implement <code>pairwise<\/code><a href=\"#how-to-implement-pairwise\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>If you had to implement <code>pairwise<\/code>, you might think of something like the code below:<\/p>\n<pre><code class=\"language-py\">def my_pairwise(iterable):\n    for prev_, next_ in zip(iterable, iterable[1:]):\n        yield (prev_, next_)<\/code><\/pre>\n<p>Which directly translates to<\/p>\n<pre><code class=\"language-py\">def my_pairwise(iterable):\n    yield from zip(iterable, iterable[1:])<\/code><\/pre>\n<p>But there is a problem with this implementation, and that is the slicing operation.\n<code>pairwise<\/code> is supposed to work with any iterable and not all iterables are sliceable.\nFor example, files are iterables but are not sliceable.<\/p>\n<p>There are a couple of different ways to fix this but my favourite uses <a href=\"https:\/\/mathspp.com\/blog\/python-deque-tutorial#implement-itertools-pairwise\"><code>collections.deque<\/code> with its parameter <code>maxlen<\/code><\/a>:<\/p>\n<pre><code class=\"language-py\">from collections import deque\nfrom itertools import islice\n\ndef my_pairwise(data):\n    data = iter(data)\n    window = deque(islice(data, 1), maxlen=2)\n    for value in data:\n        window.append(value)\n        yield tuple(window)<\/code><\/pre>\n<h2 id=\"generalising-itertools-pairwise\">Generalising <code>itertools.pairwise<\/code><a href=\"#generalising-itertools-pairwise\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p><code>pairwise<\/code> will always produce <strong>pairs<\/strong> of consecutive elements, but sometimes you might want tuples of different sizes.\nFor example, you might want something like &ldquo;<code>triplewise<\/code>&rdquo;, to get triples of consecutive elements, but <code>pairwise<\/code> can't be used for that.\nSo, how do you implement that generalisation?<\/p>\n<p>In the upcoming subsections I will present different ways of implementing the function <code>nwise(iterable, n)<\/code> that accepts an iterable and a positive integer <code>n<\/code> and produces overlapping tuples of <code>n<\/code> elements taken from the given iterable.<\/p>\n<p>Some example applications:<\/p>\n<pre><code class=\"language-py\">nwise(\"ABCD\", 2) -&gt; (\"A\", \"B\"), (\"B\", \"C\"), (\"C\", \"D\")\nnwise(\"ABCD\", 3) -&gt; (\"A\", \"B\", \"C\"), (\"B\", \"C\", \"D\")\nnwise(\"ABCD\", 4) -&gt; (\"A\", \"B\", \"C\", \"D\")<\/code><\/pre>\n<h3 id=\"using-deque\">Using <code>deque<\/code><a href=\"#using-deque\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>The implementation of <code>pairwise<\/code> that I showed above can be adapted for <code>nwise<\/code>:<\/p>\n<pre><code class=\"language-py\">from collections import deque\nfrom itertools import islice\n\ndef nwise(iterable, n):\n    iterable = iter(iterable)\n    window = deque(islice(iterable, n - 1), maxlen=n)\n    for value in iterable:\n        window.append(value)\n        yield tuple(window)<\/code><\/pre>\n<p>Note that you have to change <code>maxlen=2<\/code> to <code>maxlen=n<\/code>, but also <code>islice(iterable, 1)<\/code> to <code>islice(iterable, n - 1)<\/code>.<\/p>\n<h3 id=\"using-tee\">Using <code>tee<\/code><a href=\"#using-tee\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>Another fundamentally different way of implement <code>nwise<\/code> is by using <code>itertools.tee<\/code> to split the input...<\/p>","summary":"In this article you will learn about itertools.pairwise, how to use it, and how to generalise it.","date_modified":"2026-07-13T16:40:24+02:00","tags":["programming","python","algorithms","itertools"],"image":"\/user\/pages\/02.blog\/generalising-itertools-pairwise\/thumbnail.webp"},{"title":"Module itertools overview","date_published":"2024-07-23T00:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/module-itertools-overview","url":"https:\/\/mathspp.com\/blog\/module-itertools-overview","content_html":"<p>This article briefly describes the iterators available in the Python module itertools and how to use them.<\/p>\n\n<p>The Python module <code>itertools<\/code> contains 20 tools that every Python developer should be aware of.\nWe divide the iterators from the module <code>itertools<\/code> in 5 categories to make it easier to learn them and we also present a short list of the generally most useful ones.<\/p>\n<h2 id=\"all-the-iterators-from-itertools\">All the iterators from <code>itertools<\/code><a href=\"#all-the-iterators-from-itertools\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<table><thead><tr><th style=\"text-align: left;\">Category<\/th>\n<th style=\"text-align: left;\">Iterators<\/th>\n<\/tr><\/thead><tbody><tr><td style=\"text-align: left;\"><a href=\"#reshaping-iterators\">Reshaping iterators<\/a><\/td>\n<td style=\"text-align: left;\"><code>batched<\/code>, <code>chain<\/code>*, <code>groupby<\/code>, <code>islice<\/code>, <code>pairwise<\/code>*<\/td>\n<\/tr><tr><td style=\"text-align: left;\"><a href=\"#filtering-iterators\">Filtering iterators<\/a><\/td>\n<td style=\"text-align: left;\"><code>compress<\/code>, <code>dropwhile<\/code>, <code>filterfalse<\/code>, <code>takewhile<\/code><\/td>\n<\/tr><tr><td style=\"text-align: left;\"><a href=\"#combinatorial-iterators\">Combinatorial iterators<\/a><\/td>\n<td style=\"text-align: left;\"><code>combinations<\/code>, <code>combinations_with_replacement<\/code>, <code>permutations<\/code>, <code>product<\/code>*<\/td>\n<\/tr><tr><td style=\"text-align: left;\"><a href=\"#infinite-iterators\">Infinite iterators<\/a><\/td>\n<td style=\"text-align: left;\"><code>count<\/code>, <code>cycle<\/code>, <code>repeat<\/code><\/td>\n<\/tr><tr><td style=\"text-align: left;\"><a href=\"#iterators-that-complement-other-tools\">Iterators that complement other tools<\/a><\/td>\n<td style=\"text-align: left;\"><code>accumulate<\/code>, <code>starmap<\/code>, <code>zip_longest<\/code><\/td>\n<\/tr><\/tbody><\/table><p>On top of the 19 iterators listed in the table above, the module <code>itertools<\/code> also provides the function <code>tee<\/code>, which is very powerful but often not necessary.\nIn <a href=\"\/books\/the-little-book-of-itertools\">&ldquo;The little book of <code>itertools<\/code>&rdquo;<\/a> I devote a small chapter to it because understanding and reimplementing <code>tee<\/code> is an excellent learning and coding exercise.<\/p>\n<h2 id=\"the-3-most-useful-iterators-from-itertools\">The 3 most useful iterators from <code>itertools<\/code><a href=\"#the-3-most-useful-iterators-from-itertools\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>In my experience, the 3 more commonly useful tools in the module <code>itertools<\/code> are <code>product<\/code>, <code>chain<\/code>, and <code>pairwise<\/code>.<\/p>\n<h3 id=\"product-flattens-nested-loops\"><code>product<\/code> flattens nested loops<a href=\"#product-flattens-nested-loops\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>The iterator <code>product<\/code> is a <a href=\"#combinatorial-iterators\">combinatorial iterator<\/a> that is very useful when you want to flatten a series of nested <code>for<\/code> loops.\nAs the prototypical example, a nested loop that traverses a two-dimensional grid can be rewritten as a single loop with <code>product<\/code>.<\/p>\n<p>So, whenever we have two or more independent, nested <code>for<\/code> loops, like below:<\/p>\n<pre><code class=\"language-py\">for x in range(width):\n    for y in range(height):\n        # Do stuff...<\/code><\/pre>\n<p>We can reshape them into a single loop if we use <code>product<\/code>:<\/p>\n<pre><code class=\"language-py\">from itertools import product\n\nfor x, y in product(range(width), range(height)):\n    # Do stuff...<\/code><\/pre>\n<p>The flat structure gives you more horizontal space to write your code and makes it easier to manage breaking out of your loop.<\/p>\n<p>This is a very common use case for <code>product<\/code>.\nIf you go back to old code of yours, I am sure you will be able to find places where you could rewrite a loop like this.<\/p>\n<h3 id=\"chain-creates-a-single-iterable-out-of-many\"><code>chain<\/code> creates a single iterable out of many<a href=\"#chain-creates-a-single-iterable-out-of-many\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>The iterator <code>chain<\/code> lets you chain two or more iterables together, so that you can traverse them in sequence without having to add them explicitly.<\/p>\n<p>When you are dealing with iterables like lists or strings, you might argue that you would rather spend the time doing the addition instead of having to import <code>chain<\/code>, but this doesn't always work.<\/p>\n<p>Consider this snippet of code that concatenates two lists so that we can traverse them:<\/p>\n<pre><code class=\"language-py\"># Typical pattern:\nfirst_list = [...]\nsecond_list = [...]\nfull_list = first_list + second_list  # + third_list + ...\nfor element in full_list:\n    # Do stuff<\/code><\/pre>\n<p>Using <code>chain<\/code>, we wouldn't need the addition:<\/p>\n<pre><code class=\"language-py\">from itertools import chain\n\nfirst_list = [...]\nsecond_list = [...]\nfor element in chain(first_list, second_list):  # Also works with 3+ iterables.\n    # Do stuff<\/code><\/pre>\n<p>This...<\/p>","summary":"This article briefly describes the iterators available in the Python module itertools and how to use them.","date_modified":"2026-07-13T16:40:24+02:00","tags":["modules","programming","python","itertools"],"image":"\/user\/pages\/02.blog\/module-itertools-overview\/thumbnail.webp"},{"title":"itertools.batched","date_published":"2023-10-17T00:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/itertools-batched","url":"https:\/\/mathspp.com\/blog\/itertools-batched","content_html":"<p>Learn how <code>batched<\/code> from the module <code>itertools<\/code> works, example use cases, and how to implement it.<\/p>\n\n<p>The module <code>itertools<\/code> introduced a new tool called <code>batched<\/code> in Python 3.12.\n<code>itertools.batched<\/code> lets you iterate over an iterable by going over portions of that iterable &ndash; or batches &ndash; that all have the same size, except possibly for the last one.\nSome <a href=\"#example-use-cases\">example use cases<\/a> include batching API requests or batching data processing.<\/p>\n<p>As a dummy example, consider the snippet below:<\/p>\n<pre><code class=\"language-py\">&gt;&gt;&gt; from itertools import batched\n&gt;&gt;&gt; for batch in batched(\"Hello, world!\", 3):\n...     print(batch)\n...\n('H', 'e', 'l')\n('l', 'o', ',')\n(' ', 'w', 'o')\n('r', 'l', 'd')\n('!',)<\/code><\/pre>\n<p>Notice how the last batch is a tuple with the single character, <code>\"!\"<\/code>.\nThat's because the original input string had length 13 and I asked for batches of size 3, so <code>batched<\/code> served me with four batches of size 3 and the final batch contained the remaining character.<\/p>\n<h2 id=\"example-use-cases\">Example use cases<a href=\"#example-use-cases\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>In this section I will show you a couple of example use cases for <code>itertools.batched<\/code>.\nIf you know of any other good use cases, feel free to leave a comment below or to <a href=\"\/contact-me\">reach out to me<\/a> and I'll include them here.<\/p>\n<h3 id=\"go-over-a-file-in-chunks\">Go over a file in chunks<a href=\"#go-over-a-file-in-chunks\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>If you have a huge file that you need to go over, but you don't need to read the whole file at once, you can use <code>batched<\/code> to go over a set number of lines at a time.\nThe code would look like this:<\/p>\n<pre><code class=\"language-py\">from itertools import batched\n\nwith open(some_file, \"r\") as file:\n    for chunk in batched(file, 25):\n        process_chunk_of_lines(chunk)<\/code><\/pre>\n<p>This could work well if you were looking for some specific line in the file, for example, and you couldn't hold the whole file in memory.\nOf course, in that case, you could probably increase the batch size to something bigger than <code>25<\/code>.<\/p>\n<h3 id=\"chunking-a-response-over-a-socket\">Chunking a response over a socket<a href=\"#chunking-a-response-over-a-socket\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>In contexts like socket communications, it is common to have to chunk your response to a maximum size, so if your message is bigger than some limit, you have to send it in chunks.\nThe code would look something like this:<\/p>\n<pre><code class=\"language-py\">from itertools import batched\n\nfor chunk in batched(raw_data, 1024):\n    sent = socket.send(b\"\".join(chunk))\n    if sent &lt; len(chunk):\n        # Handle the fact that not all data was sent.<\/code><\/pre>\n<p>In this case, you may need to send strings (or bytes) over the socket, and that is why we do <code>b\"\".join(...)<\/code>, because <code>batched<\/code> returns tuples with the elements.<\/p>\n<h3 id=\"iterating-over-substrings\">Iterating over substrings<a href=\"#iterating-over-substrings\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>If you need to use <code>batched<\/code> to split a string, but the final thing you need is substrings, you can use <code>batched<\/code> together with <code>\"\".join<\/code> and <code>map<\/code> to create an iterator that produces substrings of a given length:<\/p>\n<pre><code class=\"language-py\">map(\"\".join, batched(string, length))<\/code><\/pre>\n<p>Here is an example:<\/p>\n<pre><code class=\"language-pycon\">&gt;&gt;&gt; from itertools import batched\n&gt;&gt;&gt; hello_world_substrings = map(\"\".join, batched(\"Hello, world!\", 3))\n&gt;&gt;&gt; for substring in hello_world_substrings:\n...     print(substring)\n...\nHel\nlo,\n wo\nrld\n!<\/code><\/pre>\n<p>This could also work well with the <a href=\"#chunking-a-response-over-a-socket\">socket example<\/a> from above.<\/p>\n<p>Another example where...<\/p>","summary":"Learn how batched from the module itertools works, example use cases, and how to implement it.","date_modified":"2026-07-13T16:40:24+02:00","tags":["dunder methods","generators","modules","programming","python","itertools"],"image":"\/user\/pages\/02.blog\/itertools-batched\/thumbnail.webp"}]}
