{ "cells": [ { "cell_type": "raw", "metadata": { "raw_mimetype": "text/restructuredtext" }, "source": [ ".. meta::\n", " :description: Topic: simple use cases of python itertools, Difficulty: Easy, Category: Tutorial\n", " :keywords: itertools, examples, zip, range, enumerate, chain, combinations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Python's \"Itertools\"\n", "Python has an [itertools module](https://docs.python.org/3/library/itertools.html), which provides a core set of fast, memory-efficient tools for creating iterators. We will briefly showcase a few itertools here. The majority of these functions create [generators](https://www.pythonlikeyoumeanit.com/Module2_EssentialsOfPython/Generators_and_Comprehensions.html), thus we will have to iterate over them in order to explicitly demonstrate their use. It is hard to overstate the utility of this module - it is strongly recommended that you take some time to see what it has in store.\n", "\n", "There are three built-in functions, `range`, `enumerate`, and `zip`, that belong in itertools, but they are so useful that they are made accessible immediately and do not need to be imported. It is essential that `range`, `enumerate`, and `zip` become tools that you are comfortable using.\n", "\n", "**range**\n", "\n", "Generate a sequence of integers in the specified \"range\":\n", "```python\n", "# will generate 0.. 1.. 2.. ... 8.. 9\n", ">>> range(10)\n", "range(0, 10)\n", "\n", ">>> list(range(10))\n", "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n", "\n", "# will generate 0.. 3.. 6.. 9\n", ">>> range(0, 10, 3)\n", "range(0, 10, 3)\n", "\n", ">>> list(range(0, 10, 3))\n", "[0, 3, 6, 9]\n", "```\n", "\n", "**enumerate**\n", "\n", "Enumerates the items in an iterable: yielding a tuple containing the iteration count (starting with 0) and the corresponding item from the the iterable.\n", "```python\n", "# will generate (0, 'apple').. (1, 'banana').. (2, 'cat').. (3, 'dog')]\n", ">>> enumerate([\"apple\", \"banana\", \"cat\", \"dog\"])\n", "\n", "\n", ">>> list(enumerate([\"apple\", \"banana\", \"cat\", \"dog\"]))\n", "[(0, 'apple'), (1, 'banana'), (2, 'cat'), (3, 'dog')]\n", "```\n", "\n", "**zip**\n", "\n", "Zips together the corresponding elements of several iterables into tuples. This is valuable for \"pairing\" corresponding items across multiple iterables. \n", "```python\n", ">>> names = [\"Angie\", \"Brian\", \"Cassie\", \"David\"]\n", ">>> exam_1_scores = [90, 82, 79, 87]\n", ">>> exam_2_scores = [95, 84, 72, 91]\n", "\n", "# will generate ('Angie', 90, 95).. ('Brian', 82, 84).. ('Cassie', 79, 72).. ('David', 87, 91)]\n", ">>> zip(names, exam_1_scores, exam_2_scores)\n", "\n", "\n", ">>> list(zip(names, exam_1_scores, exam_2_scores))\n", "[('Angie', 90, 95), ('Brian', 82, 84), ('Cassie', 79, 72), ('David', 87, 91)]\n", "```\n", "***\n", "The following are some of the many useful tools provided by the `itertools` module:\n", "\n", "**itertools.chain**\n", "\n", "Chains together multiple iterables, end-to-end, forming a single iterable:\n", "```python\n", ">>> from itertools import chain\n", ">>> gen_1 = range(0, 5, 2) # 0.. 2.. 4\n", ">>> gen_2 = (i**2 for i in range(3, 6)) # 9.. 16.. 25 \n", ">>> iter_3 = [\"moo\", \"cow\"]\n", ">>> iter_4 = \"him\"\n", "\n", "# will generate: 0.. 2.. 4.. 9.. 16.. 25.. 'moo'.. 'cow'.. 'h'.. 'i'.. 'm'\n", ">>> chain(gen_1, gen_2, iter_3, iter_4)\n", "\n", "```\n", "\n", "**itertools.combinations**\n", "Generate all length-n tuples storing \"combinations\" of items from an iterable:\n", "```python\n", ">>> from itertools import combinations\n", "\n", "# will generate: (0, 1, 2).. (0, 1, 3).. (0, 2, 3).. (1, 2, 3)\n", ">>> combinations([0, 1, 2, 3], 3) # generate all length-3 combinations from [0, 1, 2, 3]\n", "\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "**Reading Comprehension: Itertools I**\n", "\n", "Using the `itertools.combinations` function, find the probability that two randomly drawn items from the list `[\"apples\", \"bananas\", \"pears\", \"pears\", \"oranges\"]` would yield a combination of \"apples\" and \"pears\".\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "**Reading Comprehension: Itertools II**\n", "\n", "Given the list `x_vals = [0.1, 0.3, 0.6, 0.9]`, create a generator, `y_gen`, that will generate the y-value $y = x^2$ for each value of $x$. Then, using `zip`, create a list of the $(x, y)$ pairs, each pair stored in a tuple.\n", "\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Links to Official Documentation\n", "\n", "- [range](https://docs.python.org/3/library/stdtypes.html#typesseq-range)\n", "- [enumerate](https://docs.python.org/3/library/functions.html#enumerate)\n", "- [zip](https://docs.python.org/3/library/functions.html#zip)\n", "- [itertools](https://docs.python.org/3/library/itertools.html)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Reading Comprehension: Solutions\n", "\n", "**Itertools I: Solution**\n", "\n", "```python\n", ">>> from itertools import combinations\n", ">>> ls = [\"apples\", \"bananas\", \"pears\", \"pears\", \"oranges\"]\n", ">>> comb_ls = list(combinations(ls, 2))\n", ">>> comb_ls.count((\"apples\", \"pears\")) / len(comb_ls)\n", "0.2\n", "```\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Itertools II: Solution**\n", "\n", "```python\n", ">>> x_vals = [0.1, 0.3, 0.6, 0.9]\n", ">>> y_gen = (x**2 for x in x_vals)\n", ">>> list(zip(x_vals, y_gen))\n", "[(0.1, 0.01), (0.3, 0.09), (0.6, 0.36), (0.9, 0.81)]\n", "```\n", "\n", "In this instance, the use of `zip` is a bit contrived. We could have foregone creating `y_gen` by just using the following list-comprehension:\n", "```python\n", ">>> x_vals = [0.1, 0.3, 0.6, 0.9]\n", ">>> [(x, x**2) for x in x_vals]\n", "[(0.1, 0.01), (0.3, 0.09), (0.6, 0.36), (0.9, 0.81)]\n", "```" ] } ], "metadata": { "jupytext": { "text_representation": { "extension": ".md", "format_name": "markdown", "format_version": "1.3", "jupytext_version": "1.13.6" } }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 4 }