|
- <!DOCTYPE html>
-
- <html lang="en" data-content_root="../">
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="viewport" content="width=device-width, initial-scale=1" />
- <meta property="og:title" content="Functional Programming HOWTO" />
- <meta property="og:type" content="website" />
- <meta property="og:url" content="https://docs.python.org/3/howto/functional.html" />
- <meta property="og:site_name" content="Python documentation" />
- <meta property="og:description" content="Author, A. M. Kuchling,, Release, 0.32,. In this document, we’ll take a tour of Python’s features suitable for implementing programs in a functional style. After an introduction to the concepts of ..." />
- <meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
- <meta property="og:image:alt" content="Python documentation" />
- <meta name="description" content="Author, A. M. Kuchling,, Release, 0.32,. In this document, we’ll take a tour of Python’s features suitable for implementing programs in a functional style. After an introduction to the concepts of ..." />
- <meta property="og:image:width" content="200" />
- <meta property="og:image:height" content="200" />
- <meta name="theme-color" content="#3776ab" />
-
- <title>Functional Programming HOWTO — Python 3.12.3 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
-
- <link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=80d5e7a1" />
- <link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?v=bb723527" />
- <link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css?v=b20cc3f5" />
-
- <script src="../_static/documentation_options.js?v=2c828074"></script>
- <script src="../_static/doctools.js?v=888ff710"></script>
- <script src="../_static/sphinx_highlight.js?v=dc90522c"></script>
-
- <script src="../_static/sidebar.js"></script>
-
- <link rel="search" type="application/opensearchdescription+xml"
- title="Search within Python 3.12.3 documentation"
- href="../_static/opensearch.xml"/>
- <link rel="author" title="About these documents" href="../about.html" />
- <link rel="index" title="Index" href="../genindex.html" />
- <link rel="search" title="Search" href="../search.html" />
- <link rel="copyright" title="Copyright" href="../copyright.html" />
- <link rel="next" title="Logging HOWTO" href="logging.html" />
- <link rel="prev" title="Enum HOWTO" href="enum.html" />
- <link rel="canonical" href="https://docs.python.org/3/howto/functional.html" />
-
-
-
-
-
- <style>
- @media only screen {
- table.full-width-table {
- width: 100%;
- }
- }
- </style>
- <link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
- <link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
- <script type="text/javascript" src="../_static/copybutton.js"></script>
- <script type="text/javascript" src="../_static/menu.js"></script>
- <script type="text/javascript" src="../_static/search-focus.js"></script>
- <script type="text/javascript" src="../_static/themetoggle.js"></script>
-
- </head>
- <body>
- <div class="mobile-nav">
- <input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
- aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
- <nav class="nav-content" role="navigation">
- <label for="menuToggler" class="toggler__label">
- <span></span>
- </label>
- <span class="nav-items-wrapper">
- <a href="https://www.python.org/" class="nav-logo">
- <img src="../_static/py.svg" alt="Python logo"/>
- </a>
- <span class="version_switcher_placeholder"></span>
- <form role="search" class="search" action="../search.html" method="get">
- <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
- <path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
- </svg>
- <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
- <input type="submit" value="Go"/>
- </form>
- </span>
- </nav>
- <div class="menu-wrapper">
- <nav class="menu" role="navigation" aria-label="main navigation">
- <div class="language_switcher_placeholder"></div>
-
- <label class="theme-selector-label">
- Theme
- <select class="theme-selector" oninput="activateTheme(this.value)">
- <option value="auto" selected>Auto</option>
- <option value="light">Light</option>
- <option value="dark">Dark</option>
- </select>
- </label>
- <div>
- <h3><a href="../contents.html">Table of Contents</a></h3>
- <ul>
- <li><a class="reference internal" href="#">Functional Programming HOWTO</a><ul>
- <li><a class="reference internal" href="#introduction">Introduction</a><ul>
- <li><a class="reference internal" href="#formal-provability">Formal provability</a></li>
- <li><a class="reference internal" href="#modularity">Modularity</a></li>
- <li><a class="reference internal" href="#ease-of-debugging-and-testing">Ease of debugging and testing</a></li>
- <li><a class="reference internal" href="#composability">Composability</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#iterators">Iterators</a><ul>
- <li><a class="reference internal" href="#data-types-that-support-iterators">Data Types That Support Iterators</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#generator-expressions-and-list-comprehensions">Generator expressions and list comprehensions</a></li>
- <li><a class="reference internal" href="#generators">Generators</a><ul>
- <li><a class="reference internal" href="#passing-values-into-a-generator">Passing values into a generator</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#built-in-functions">Built-in functions</a></li>
- <li><a class="reference internal" href="#the-itertools-module">The itertools module</a><ul>
- <li><a class="reference internal" href="#creating-new-iterators">Creating new iterators</a></li>
- <li><a class="reference internal" href="#calling-functions-on-elements">Calling functions on elements</a></li>
- <li><a class="reference internal" href="#selecting-elements">Selecting elements</a></li>
- <li><a class="reference internal" href="#combinatoric-functions">Combinatoric functions</a></li>
- <li><a class="reference internal" href="#grouping-elements">Grouping elements</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#the-functools-module">The functools module</a><ul>
- <li><a class="reference internal" href="#the-operator-module">The operator module</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#small-functions-and-the-lambda-expression">Small functions and the lambda expression</a></li>
- <li><a class="reference internal" href="#revision-history-and-acknowledgements">Revision History and Acknowledgements</a></li>
- <li><a class="reference internal" href="#references">References</a><ul>
- <li><a class="reference internal" href="#general">General</a></li>
- <li><a class="reference internal" href="#python-specific">Python-specific</a></li>
- <li><a class="reference internal" href="#python-documentation">Python documentation</a></li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
-
- </div>
- <div>
- <h4>Previous topic</h4>
- <p class="topless"><a href="enum.html"
- title="previous chapter">Enum HOWTO</a></p>
- </div>
- <div>
- <h4>Next topic</h4>
- <p class="topless"><a href="logging.html"
- title="next chapter">Logging HOWTO</a></p>
- </div>
- <div role="note" aria-label="source link">
- <h3>This Page</h3>
- <ul class="this-page-menu">
- <li><a href="../bugs.html">Report a Bug</a></li>
- <li>
- <a href="https://github.com/python/cpython/blob/main/Doc/howto/functional.rst"
- rel="nofollow">Show Source
- </a>
- </li>
- </ul>
- </div>
- </nav>
- </div>
- </div>
-
-
- <div class="related" role="navigation" aria-label="related navigation">
- <h3>Navigation</h3>
- <ul>
- <li class="right" style="margin-right: 10px">
- <a href="../genindex.html" title="General Index"
- accesskey="I">index</a></li>
- <li class="right" >
- <a href="../py-modindex.html" title="Python Module Index"
- >modules</a> |</li>
- <li class="right" >
- <a href="logging.html" title="Logging HOWTO"
- accesskey="N">next</a> |</li>
- <li class="right" >
- <a href="enum.html" title="Enum HOWTO"
- accesskey="P">previous</a> |</li>
-
- <li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
- <li><a href="https://www.python.org/">Python</a> »</li>
- <li class="switchers">
- <div class="language_switcher_placeholder"></div>
- <div class="version_switcher_placeholder"></div>
- </li>
- <li>
-
- </li>
- <li id="cpython-language-and-version">
- <a href="../index.html">3.12.3 Documentation</a> »
- </li>
-
- <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python HOWTOs</a> »</li>
- <li class="nav-item nav-item-this"><a href="">Functional Programming HOWTO</a></li>
- <li class="right">
-
-
- <div class="inline-search" role="search">
- <form class="inline-search" action="../search.html" method="get">
- <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
- <input type="submit" value="Go" />
- </form>
- </div>
- |
- </li>
- <li class="right">
- <label class="theme-selector-label">
- Theme
- <select class="theme-selector" oninput="activateTheme(this.value)">
- <option value="auto" selected>Auto</option>
- <option value="light">Light</option>
- <option value="dark">Dark</option>
- </select>
- </label> |</li>
-
- </ul>
- </div>
-
- <div class="document">
- <div class="documentwrapper">
- <div class="bodywrapper">
- <div class="body" role="main">
-
- <section id="functional-programming-howto">
- <h1>Functional Programming HOWTO<a class="headerlink" href="#functional-programming-howto" title="Link to this heading">¶</a></h1>
- <dl class="field-list simple">
- <dt class="field-odd">Author<span class="colon">:</span></dt>
- <dd class="field-odd"><p>A. M. Kuchling</p>
- </dd>
- <dt class="field-even">Release<span class="colon">:</span></dt>
- <dd class="field-even"><p>0.32</p>
- </dd>
- </dl>
- <p>In this document, we’ll take a tour of Python’s features suitable for
- implementing programs in a functional style. After an introduction to the
- concepts of functional programming, we’ll look at language features such as
- <a class="reference internal" href="../glossary.html#term-iterator"><span class="xref std std-term">iterator</span></a>s and <a class="reference internal" href="../glossary.html#term-generator"><span class="xref std std-term">generator</span></a>s and relevant library modules such as
- <a class="reference internal" href="../library/itertools.html#module-itertools" title="itertools: Functions creating iterators for efficient looping."><code class="xref py py-mod docutils literal notranslate"><span class="pre">itertools</span></code></a> and <a class="reference internal" href="../library/functools.html#module-functools" title="functools: Higher-order functions and operations on callable objects."><code class="xref py py-mod docutils literal notranslate"><span class="pre">functools</span></code></a>.</p>
- <section id="introduction">
- <h2>Introduction<a class="headerlink" href="#introduction" title="Link to this heading">¶</a></h2>
- <p>This section explains the basic concept of functional programming; if
- you’re just interested in learning about Python language features,
- skip to the next section on <a class="reference internal" href="#functional-howto-iterators"><span class="std std-ref">Iterators</span></a>.</p>
- <p>Programming languages support decomposing problems in several different ways:</p>
- <ul class="simple">
- <li><p>Most programming languages are <strong>procedural</strong>: programs are lists of
- instructions that tell the computer what to do with the program’s input. C,
- Pascal, and even Unix shells are procedural languages.</p></li>
- <li><p>In <strong>declarative</strong> languages, you write a specification that describes the
- problem to be solved, and the language implementation figures out how to
- perform the computation efficiently. SQL is the declarative language you’re
- most likely to be familiar with; a SQL query describes the data set you want
- to retrieve, and the SQL engine decides whether to scan tables or use indexes,
- which subclauses should be performed first, etc.</p></li>
- <li><p><strong>Object-oriented</strong> programs manipulate collections of objects. Objects have
- internal state and support methods that query or modify this internal state in
- some way. Smalltalk and Java are object-oriented languages. C++ and Python
- are languages that support object-oriented programming, but don’t force the
- use of object-oriented features.</p></li>
- <li><p><strong>Functional</strong> programming decomposes a problem into a set of functions.
- Ideally, functions only take inputs and produce outputs, and don’t have any
- internal state that affects the output produced for a given input. Well-known
- functional languages include the ML family (Standard ML, OCaml, and other
- variants) and Haskell.</p></li>
- </ul>
- <p>The designers of some computer languages choose to emphasize one
- particular approach to programming. This often makes it difficult to
- write programs that use a different approach. Other languages are
- multi-paradigm languages that support several different approaches.
- Lisp, C++, and Python are multi-paradigm; you can write programs or
- libraries that are largely procedural, object-oriented, or functional
- in all of these languages. In a large program, different sections
- might be written using different approaches; the GUI might be
- object-oriented while the processing logic is procedural or
- functional, for example.</p>
- <p>In a functional program, input flows through a set of functions. Each function
- operates on its input and produces some output. Functional style discourages
- functions with side effects that modify internal state or make other changes
- that aren’t visible in the function’s return value. Functions that have no side
- effects at all are called <strong>purely functional</strong>. Avoiding side effects means
- not using data structures that get updated as a program runs; every function’s
- output must only depend on its input.</p>
- <p>Some languages are very strict about purity and don’t even have assignment
- statements such as <code class="docutils literal notranslate"><span class="pre">a=3</span></code> or <code class="docutils literal notranslate"><span class="pre">c</span> <span class="pre">=</span> <span class="pre">a</span> <span class="pre">+</span> <span class="pre">b</span></code>, but it’s difficult to avoid all
- side effects, such as printing to the screen or writing to a disk file. Another
- example is a call to the <a class="reference internal" href="../library/functions.html#print" title="print"><code class="xref py py-func docutils literal notranslate"><span class="pre">print()</span></code></a> or <a class="reference internal" href="../library/time.html#time.sleep" title="time.sleep"><code class="xref py py-func docutils literal notranslate"><span class="pre">time.sleep()</span></code></a> function, neither
- of which returns a useful value. Both are called only for their side effects
- of sending some text to the screen or pausing execution for a second.</p>
- <p>Python programs written in functional style usually won’t go to the extreme of
- avoiding all I/O or all assignments; instead, they’ll provide a
- functional-appearing interface but will use non-functional features internally.
- For example, the implementation of a function will still use assignments to
- local variables, but won’t modify global variables or have other side effects.</p>
- <p>Functional programming can be considered the opposite of object-oriented
- programming. Objects are little capsules containing some internal state along
- with a collection of method calls that let you modify this state, and programs
- consist of making the right set of state changes. Functional programming wants
- to avoid state changes as much as possible and works with data flowing between
- functions. In Python you might combine the two approaches by writing functions
- that take and return instances representing objects in your application (e-mail
- messages, transactions, etc.).</p>
- <p>Functional design may seem like an odd constraint to work under. Why should you
- avoid objects and side effects? There are theoretical and practical advantages
- to the functional style:</p>
- <ul class="simple">
- <li><p>Formal provability.</p></li>
- <li><p>Modularity.</p></li>
- <li><p>Composability.</p></li>
- <li><p>Ease of debugging and testing.</p></li>
- </ul>
- <section id="formal-provability">
- <h3>Formal provability<a class="headerlink" href="#formal-provability" title="Link to this heading">¶</a></h3>
- <p>A theoretical benefit is that it’s easier to construct a mathematical proof that
- a functional program is correct.</p>
- <p>For a long time researchers have been interested in finding ways to
- mathematically prove programs correct. This is different from testing a program
- on numerous inputs and concluding that its output is usually correct, or reading
- a program’s source code and concluding that the code looks right; the goal is
- instead a rigorous proof that a program produces the right result for all
- possible inputs.</p>
- <p>The technique used to prove programs correct is to write down <strong>invariants</strong>,
- properties of the input data and of the program’s variables that are always
- true. For each line of code, you then show that if invariants X and Y are true
- <strong>before</strong> the line is executed, the slightly different invariants X’ and Y’ are
- true <strong>after</strong> the line is executed. This continues until you reach the end of
- the program, at which point the invariants should match the desired conditions
- on the program’s output.</p>
- <p>Functional programming’s avoidance of assignments arose because assignments are
- difficult to handle with this technique; assignments can break invariants that
- were true before the assignment without producing any new invariants that can be
- propagated onward.</p>
- <p>Unfortunately, proving programs correct is largely impractical and not relevant
- to Python software. Even trivial programs require proofs that are several pages
- long; the proof of correctness for a moderately complicated program would be
- enormous, and few or none of the programs you use daily (the Python interpreter,
- your XML parser, your web browser) could be proven correct. Even if you wrote
- down or generated a proof, there would then be the question of verifying the
- proof; maybe there’s an error in it, and you wrongly believe you’ve proved the
- program correct.</p>
- </section>
- <section id="modularity">
- <h3>Modularity<a class="headerlink" href="#modularity" title="Link to this heading">¶</a></h3>
- <p>A more practical benefit of functional programming is that it forces you to
- break apart your problem into small pieces. Programs are more modular as a
- result. It’s easier to specify and write a small function that does one thing
- than a large function that performs a complicated transformation. Small
- functions are also easier to read and to check for errors.</p>
- </section>
- <section id="ease-of-debugging-and-testing">
- <h3>Ease of debugging and testing<a class="headerlink" href="#ease-of-debugging-and-testing" title="Link to this heading">¶</a></h3>
- <p>Testing and debugging a functional-style program is easier.</p>
- <p>Debugging is simplified because functions are generally small and clearly
- specified. When a program doesn’t work, each function is an interface point
- where you can check that the data are correct. You can look at the intermediate
- inputs and outputs to quickly isolate the function that’s responsible for a bug.</p>
- <p>Testing is easier because each function is a potential subject for a unit test.
- Functions don’t depend on system state that needs to be replicated before
- running a test; instead you only have to synthesize the right input and then
- check that the output matches expectations.</p>
- </section>
- <section id="composability">
- <h3>Composability<a class="headerlink" href="#composability" title="Link to this heading">¶</a></h3>
- <p>As you work on a functional-style program, you’ll write a number of functions
- with varying inputs and outputs. Some of these functions will be unavoidably
- specialized to a particular application, but others will be useful in a wide
- variety of programs. For example, a function that takes a directory path and
- returns all the XML files in the directory, or a function that takes a filename
- and returns its contents, can be applied to many different situations.</p>
- <p>Over time you’ll form a personal library of utilities. Often you’ll assemble
- new programs by arranging existing functions in a new configuration and writing
- a few functions specialized for the current task.</p>
- </section>
- </section>
- <section id="iterators">
- <span id="functional-howto-iterators"></span><h2>Iterators<a class="headerlink" href="#iterators" title="Link to this heading">¶</a></h2>
- <p>I’ll start by looking at a Python language feature that’s an important
- foundation for writing functional-style programs: iterators.</p>
- <p>An iterator is an object representing a stream of data; this object returns the
- data one element at a time. A Python iterator must support a method called
- <a class="reference internal" href="../library/stdtypes.html#iterator.__next__" title="iterator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> that takes no arguments and always returns the next
- element of the stream. If there are no more elements in the stream,
- <a class="reference internal" href="../library/stdtypes.html#iterator.__next__" title="iterator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> must raise the <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> exception.
- Iterators don’t have to be finite, though; it’s perfectly reasonable to write
- an iterator that produces an infinite stream of data.</p>
- <p>The built-in <a class="reference internal" href="../library/functions.html#iter" title="iter"><code class="xref py py-func docutils literal notranslate"><span class="pre">iter()</span></code></a> function takes an arbitrary object and tries to return
- an iterator that will return the object’s contents or elements, raising
- <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> if the object doesn’t support iteration. Several of Python’s
- built-in data types support iteration, the most common being lists and
- dictionaries. An object is called <a class="reference internal" href="../glossary.html#term-iterable"><span class="xref std std-term">iterable</span></a> if you can get an iterator
- for it.</p>
- <p>You can experiment with the iteration interface manually:</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">L</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
- <span class="gp">>>> </span><span class="n">it</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">L</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="n">it</span>
- <span class="go"><...iterator object at ...></span>
- <span class="gp">>>> </span><span class="n">it</span><span class="o">.</span><span class="fm">__next__</span><span class="p">()</span> <span class="c1"># same as next(it)</span>
- <span class="go">1</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
- <span class="go">2</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
- <span class="go">3</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
- <span class="gt">Traceback (most recent call last):</span>
- File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
- <span class="gr">StopIteration</span>
- <span class="gp">>>></span>
- </pre></div>
- </div>
- <p>Python expects iterable objects in several different contexts, the most
- important being the <a class="reference internal" href="../reference/compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> statement. In the statement <code class="docutils literal notranslate"><span class="pre">for</span> <span class="pre">X</span> <span class="pre">in</span> <span class="pre">Y</span></code>,
- Y must be an iterator or some object for which <a class="reference internal" href="../library/functions.html#iter" title="iter"><code class="xref py py-func docutils literal notranslate"><span class="pre">iter()</span></code></a> can create an
- iterator. These two statements are equivalent:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">iter</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
-
- <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">obj</span><span class="p">:</span>
- <span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>Iterators can be materialized as lists or tuples by using the <a class="reference internal" href="../library/stdtypes.html#list" title="list"><code class="xref py py-func docutils literal notranslate"><span class="pre">list()</span></code></a> or
- <a class="reference internal" href="../library/stdtypes.html#tuple" title="tuple"><code class="xref py py-func docutils literal notranslate"><span class="pre">tuple()</span></code></a> constructor functions:</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">L</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
- <span class="gp">>>> </span><span class="n">iterator</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">L</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="n">t</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">iterator</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="n">t</span>
- <span class="go">(1, 2, 3)</span>
- </pre></div>
- </div>
- <p>Sequence unpacking also supports iterators: if you know an iterator will return
- N elements, you can unpack them into an N-tuple:</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">L</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
- <span class="gp">>>> </span><span class="n">iterator</span> <span class="o">=</span> <span class="nb">iter</span><span class="p">(</span><span class="n">L</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span> <span class="o">=</span> <span class="n">iterator</span>
- <span class="gp">>>> </span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span>
- <span class="go">(1, 2, 3)</span>
- </pre></div>
- </div>
- <p>Built-in functions such as <a class="reference internal" href="../library/functions.html#max" title="max"><code class="xref py py-func docutils literal notranslate"><span class="pre">max()</span></code></a> and <a class="reference internal" href="../library/functions.html#min" title="min"><code class="xref py py-func docutils literal notranslate"><span class="pre">min()</span></code></a> can take a single
- iterator argument and will return the largest or smallest element. The <code class="docutils literal notranslate"><span class="pre">"in"</span></code>
- and <code class="docutils literal notranslate"><span class="pre">"not</span> <span class="pre">in"</span></code> operators also support iterators: <code class="docutils literal notranslate"><span class="pre">X</span> <span class="pre">in</span> <span class="pre">iterator</span></code> is true if
- X is found in the stream returned by the iterator. You’ll run into obvious
- problems if the iterator is infinite; <a class="reference internal" href="../library/functions.html#max" title="max"><code class="xref py py-func docutils literal notranslate"><span class="pre">max()</span></code></a>, <a class="reference internal" href="../library/functions.html#min" title="min"><code class="xref py py-func docutils literal notranslate"><span class="pre">min()</span></code></a>
- will never return, and if the element X never appears in the stream, the
- <code class="docutils literal notranslate"><span class="pre">"in"</span></code> and <code class="docutils literal notranslate"><span class="pre">"not</span> <span class="pre">in"</span></code> operators won’t return either.</p>
- <p>Note that you can only go forward in an iterator; there’s no way to get the
- previous element, reset the iterator, or make a copy of it. Iterator objects
- can optionally provide these additional capabilities, but the iterator protocol
- only specifies the <a class="reference internal" href="../library/stdtypes.html#iterator.__next__" title="iterator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> method. Functions may therefore
- consume all of the iterator’s output, and if you need to do something different
- with the same stream, you’ll have to create a new iterator.</p>
- <section id="data-types-that-support-iterators">
- <h3>Data Types That Support Iterators<a class="headerlink" href="#data-types-that-support-iterators" title="Link to this heading">¶</a></h3>
- <p>We’ve already seen how lists and tuples support iterators. In fact, any Python
- sequence type, such as strings, will automatically support creation of an
- iterator.</p>
- <p>Calling <a class="reference internal" href="../library/functions.html#iter" title="iter"><code class="xref py py-func docutils literal notranslate"><span class="pre">iter()</span></code></a> on a dictionary returns an iterator that will loop over the
- dictionary’s keys:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">m</span> <span class="o">=</span> <span class="p">{</span><span class="s1">'Jan'</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">'Feb'</span><span class="p">:</span> <span class="mi">2</span><span class="p">,</span> <span class="s1">'Mar'</span><span class="p">:</span> <span class="mi">3</span><span class="p">,</span> <span class="s1">'Apr'</span><span class="p">:</span> <span class="mi">4</span><span class="p">,</span> <span class="s1">'May'</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s1">'Jun'</span><span class="p">:</span> <span class="mi">6</span><span class="p">,</span>
- <span class="gp">... </span> <span class="s1">'Jul'</span><span class="p">:</span> <span class="mi">7</span><span class="p">,</span> <span class="s1">'Aug'</span><span class="p">:</span> <span class="mi">8</span><span class="p">,</span> <span class="s1">'Sep'</span><span class="p">:</span> <span class="mi">9</span><span class="p">,</span> <span class="s1">'Oct'</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span> <span class="s1">'Nov'</span><span class="p">:</span> <span class="mi">11</span><span class="p">,</span> <span class="s1">'Dec'</span><span class="p">:</span> <span class="mi">12</span><span class="p">}</span>
- <span class="gp">>>> </span><span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">m</span><span class="p">:</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">m</span><span class="p">[</span><span class="n">key</span><span class="p">])</span>
- <span class="go">Jan 1</span>
- <span class="go">Feb 2</span>
- <span class="go">Mar 3</span>
- <span class="go">Apr 4</span>
- <span class="go">May 5</span>
- <span class="go">Jun 6</span>
- <span class="go">Jul 7</span>
- <span class="go">Aug 8</span>
- <span class="go">Sep 9</span>
- <span class="go">Oct 10</span>
- <span class="go">Nov 11</span>
- <span class="go">Dec 12</span>
- </pre></div>
- </div>
- <p>Note that starting with Python 3.7, dictionary iteration order is guaranteed
- to be the same as the insertion order. In earlier versions, the behaviour was
- unspecified and could vary between implementations.</p>
- <p>Applying <a class="reference internal" href="../library/functions.html#iter" title="iter"><code class="xref py py-func docutils literal notranslate"><span class="pre">iter()</span></code></a> to a dictionary always loops over the keys, but
- dictionaries have methods that return other iterators. If you want to iterate
- over values or key/value pairs, you can explicitly call the
- <a class="reference internal" href="../library/stdtypes.html#dict.values" title="dict.values"><code class="xref py py-meth docutils literal notranslate"><span class="pre">values()</span></code></a> or <a class="reference internal" href="../library/stdtypes.html#dict.items" title="dict.items"><code class="xref py py-meth docutils literal notranslate"><span class="pre">items()</span></code></a> methods to get an appropriate
- iterator.</p>
- <p>The <a class="reference internal" href="../library/stdtypes.html#dict" title="dict"><code class="xref py py-func docutils literal notranslate"><span class="pre">dict()</span></code></a> constructor can accept an iterator that returns a finite stream
- of <code class="docutils literal notranslate"><span class="pre">(key,</span> <span class="pre">value)</span></code> tuples:</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">L</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">'Italy'</span><span class="p">,</span> <span class="s1">'Rome'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'France'</span><span class="p">,</span> <span class="s1">'Paris'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'US'</span><span class="p">,</span> <span class="s1">'Washington DC'</span><span class="p">)]</span>
- <span class="gp">>>> </span><span class="nb">dict</span><span class="p">(</span><span class="nb">iter</span><span class="p">(</span><span class="n">L</span><span class="p">))</span>
- <span class="go">{'Italy': 'Rome', 'France': 'Paris', 'US': 'Washington DC'}</span>
- </pre></div>
- </div>
- <p>Files also support iteration by calling the <a class="reference internal" href="../library/io.html#io.TextIOBase.readline" title="io.TextIOBase.readline"><code class="xref py py-meth docutils literal notranslate"><span class="pre">readline()</span></code></a>
- method until there are no more lines in the file. This means you can read each
- line of a file like this:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">file</span><span class="p">:</span>
- <span class="c1"># do something for each line</span>
- <span class="o">...</span>
- </pre></div>
- </div>
- <p>Sets can take their contents from an iterable and let you iterate over the set’s
- elements:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">S</span> <span class="o">=</span> <span class="p">{</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">13</span><span class="p">}</span>
- <span class="gp">>>> </span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">S</span><span class="p">:</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
- <span class="go">2</span>
- <span class="go">3</span>
- <span class="go">5</span>
- <span class="go">7</span>
- <span class="go">11</span>
- <span class="go">13</span>
- </pre></div>
- </div>
- </section>
- </section>
- <section id="generator-expressions-and-list-comprehensions">
- <h2>Generator expressions and list comprehensions<a class="headerlink" href="#generator-expressions-and-list-comprehensions" title="Link to this heading">¶</a></h2>
- <p>Two common operations on an iterator’s output are 1) performing some operation
- for every element, 2) selecting a subset of elements that meet some condition.
- For example, given a list of strings, you might want to strip off trailing
- whitespace from each line or extract all the strings containing a given
- substring.</p>
- <p>List comprehensions and generator expressions (short form: “listcomps” and
- “genexps”) are a concise notation for such operations, borrowed from the
- functional programming language Haskell (<a class="reference external" href="https://www.haskell.org/">https://www.haskell.org/</a>). You can strip
- all the whitespace from a stream of strings with the following code:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">line_list</span> <span class="o">=</span> <span class="p">[</span><span class="s1">' line 1</span><span class="se">\n</span><span class="s1">'</span><span class="p">,</span> <span class="s1">'line 2 </span><span class="se">\n</span><span class="s1">'</span><span class="p">,</span> <span class="s1">' </span><span class="se">\n</span><span class="s1">'</span><span class="p">,</span> <span class="s1">''</span><span class="p">]</span>
-
- <span class="gp">>>> </span><span class="c1"># Generator expression -- returns iterator</span>
- <span class="gp">>>> </span><span class="n">stripped_iter</span> <span class="o">=</span> <span class="p">(</span><span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">line_list</span><span class="p">)</span>
-
- <span class="gp">>>> </span><span class="c1"># List comprehension -- returns list</span>
- <span class="gp">>>> </span><span class="n">stripped_list</span> <span class="o">=</span> <span class="p">[</span><span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">line_list</span><span class="p">]</span>
- </pre></div>
- </div>
- <p>You can select only certain elements by adding an <code class="docutils literal notranslate"><span class="pre">"if"</span></code> condition:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">stripped_list</span> <span class="o">=</span> <span class="p">[</span><span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">line_list</span>
- <span class="gp">... </span> <span class="k">if</span> <span class="n">line</span> <span class="o">!=</span> <span class="s2">""</span><span class="p">]</span>
- </pre></div>
- </div>
- <p>With a list comprehension, you get back a Python list; <code class="docutils literal notranslate"><span class="pre">stripped_list</span></code> is a
- list containing the resulting lines, not an iterator. Generator expressions
- return an iterator that computes the values as necessary, not needing to
- materialize all the values at once. This means that list comprehensions aren’t
- useful if you’re working with iterators that return an infinite stream or a very
- large amount of data. Generator expressions are preferable in these situations.</p>
- <p>Generator expressions are surrounded by parentheses (“()”) and list
- comprehensions are surrounded by square brackets (“[]”). Generator expressions
- have the form:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="p">(</span> <span class="n">expression</span> <span class="k">for</span> <span class="n">expr</span> <span class="ow">in</span> <span class="n">sequence1</span>
- <span class="k">if</span> <span class="n">condition1</span>
- <span class="k">for</span> <span class="n">expr2</span> <span class="ow">in</span> <span class="n">sequence2</span>
- <span class="k">if</span> <span class="n">condition2</span>
- <span class="k">for</span> <span class="n">expr3</span> <span class="ow">in</span> <span class="n">sequence3</span>
- <span class="o">...</span>
- <span class="k">if</span> <span class="n">condition3</span>
- <span class="k">for</span> <span class="n">exprN</span> <span class="ow">in</span> <span class="n">sequenceN</span>
- <span class="k">if</span> <span class="n">conditionN</span> <span class="p">)</span>
- </pre></div>
- </div>
- <p>Again, for a list comprehension only the outside brackets are different (square
- brackets instead of parentheses).</p>
- <p>The elements of the generated output will be the successive values of
- <code class="docutils literal notranslate"><span class="pre">expression</span></code>. The <code class="docutils literal notranslate"><span class="pre">if</span></code> clauses are all optional; if present, <code class="docutils literal notranslate"><span class="pre">expression</span></code>
- is only evaluated and added to the result when <code class="docutils literal notranslate"><span class="pre">condition</span></code> is true.</p>
- <p>Generator expressions always have to be written inside parentheses, but the
- parentheses signalling a function call also count. If you want to create an
- iterator that will be immediately passed to a function you can write:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">obj_total</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">obj</span><span class="o">.</span><span class="n">count</span> <span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="n">list_all_objects</span><span class="p">())</span>
- </pre></div>
- </div>
- <p>The <code class="docutils literal notranslate"><span class="pre">for...in</span></code> clauses contain the sequences to be iterated over. The
- sequences do not have to be the same length, because they are iterated over from
- left to right, <strong>not</strong> in parallel. For each element in <code class="docutils literal notranslate"><span class="pre">sequence1</span></code>,
- <code class="docutils literal notranslate"><span class="pre">sequence2</span></code> is looped over from the beginning. <code class="docutils literal notranslate"><span class="pre">sequence3</span></code> is then looped
- over for each resulting pair of elements from <code class="docutils literal notranslate"><span class="pre">sequence1</span></code> and <code class="docutils literal notranslate"><span class="pre">sequence2</span></code>.</p>
- <p>To put it another way, a list comprehension or generator expression is
- equivalent to the following Python code:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">expr1</span> <span class="ow">in</span> <span class="n">sequence1</span><span class="p">:</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">condition1</span><span class="p">):</span>
- <span class="k">continue</span> <span class="c1"># Skip this element</span>
- <span class="k">for</span> <span class="n">expr2</span> <span class="ow">in</span> <span class="n">sequence2</span><span class="p">:</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">condition2</span><span class="p">):</span>
- <span class="k">continue</span> <span class="c1"># Skip this element</span>
- <span class="o">...</span>
- <span class="k">for</span> <span class="n">exprN</span> <span class="ow">in</span> <span class="n">sequenceN</span><span class="p">:</span>
- <span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">conditionN</span><span class="p">):</span>
- <span class="k">continue</span> <span class="c1"># Skip this element</span>
-
- <span class="c1"># Output the value of</span>
- <span class="c1"># the expression.</span>
- </pre></div>
- </div>
- <p>This means that when there are multiple <code class="docutils literal notranslate"><span class="pre">for...in</span></code> clauses but no <code class="docutils literal notranslate"><span class="pre">if</span></code>
- clauses, the length of the resulting output will be equal to the product of the
- lengths of all the sequences. If you have two lists of length 3, the output
- list is 9 elements long:</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">seq1</span> <span class="o">=</span> <span class="s1">'abc'</span>
- <span class="gp">>>> </span><span class="n">seq2</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">seq1</span> <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">seq2</span><span class="p">]</span>
- <span class="go">[('a', 1), ('a', 2), ('a', 3),</span>
- <span class="go"> ('b', 1), ('b', 2), ('b', 3),</span>
- <span class="go"> ('c', 1), ('c', 2), ('c', 3)]</span>
- </pre></div>
- </div>
- <p>To avoid introducing an ambiguity into Python’s grammar, if <code class="docutils literal notranslate"><span class="pre">expression</span></code> is
- creating a tuple, it must be surrounded with parentheses. The first list
- comprehension below is a syntax error, while the second one is correct:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="c1"># Syntax error</span>
- <span class="p">[</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">seq1</span> <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">seq2</span><span class="p">]</span>
- <span class="c1"># Correct</span>
- <span class="p">[(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">seq1</span> <span class="k">for</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">seq2</span><span class="p">]</span>
- </pre></div>
- </div>
- </section>
- <section id="generators">
- <h2>Generators<a class="headerlink" href="#generators" title="Link to this heading">¶</a></h2>
- <p>Generators are a special class of functions that simplify the task of writing
- iterators. Regular functions compute a value and return it, but generators
- return an iterator that returns a stream of values.</p>
- <p>You’re doubtless familiar with how regular function calls work in Python or C.
- When you call a function, it gets a private namespace where its local variables
- are created. When the function reaches a <code class="docutils literal notranslate"><span class="pre">return</span></code> statement, the local
- variables are destroyed and the value is returned to the caller. A later call
- to the same function creates a new private namespace and a fresh set of local
- variables. But, what if the local variables weren’t thrown away on exiting a
- function? What if you could later resume the function where it left off? This
- is what generators provide; they can be thought of as resumable functions.</p>
- <p>Here’s the simplest example of a generator function:</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">def</span> <span class="nf">generate_ints</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
- <span class="gp">... </span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">N</span><span class="p">):</span>
- <span class="gp">... </span> <span class="k">yield</span> <span class="n">i</span>
- </pre></div>
- </div>
- <p>Any function containing a <a class="reference internal" href="../reference/simple_stmts.html#yield"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">yield</span></code></a> keyword is a generator function;
- this is detected by Python’s <a class="reference internal" href="../glossary.html#term-bytecode"><span class="xref std std-term">bytecode</span></a> compiler which compiles the
- function specially as a result.</p>
- <p>When you call a generator function, it doesn’t return a single value; instead it
- returns a generator object that supports the iterator protocol. On executing
- the <code class="docutils literal notranslate"><span class="pre">yield</span></code> expression, the generator outputs the value of <code class="docutils literal notranslate"><span class="pre">i</span></code>, similar to a
- <code class="docutils literal notranslate"><span class="pre">return</span></code> statement. The big difference between <code class="docutils literal notranslate"><span class="pre">yield</span></code> and a <code class="docutils literal notranslate"><span class="pre">return</span></code>
- statement is that on reaching a <code class="docutils literal notranslate"><span class="pre">yield</span></code> the generator’s state of execution is
- suspended and local variables are preserved. On the next call to the
- generator’s <a class="reference internal" href="../reference/expressions.html#generator.__next__" title="generator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> method, the function will resume
- executing.</p>
- <p>Here’s a sample usage of the <code class="docutils literal notranslate"><span class="pre">generate_ints()</span></code> generator:</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">gen</span> <span class="o">=</span> <span class="n">generate_ints</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="n">gen</span>
- <span class="go"><generator object generate_ints at ...></span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">gen</span><span class="p">)</span>
- <span class="go">0</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">gen</span><span class="p">)</span>
- <span class="go">1</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">gen</span><span class="p">)</span>
- <span class="go">2</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">gen</span><span class="p">)</span>
- <span class="gt">Traceback (most recent call last):</span>
- File <span class="nb">"stdin"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
- File <span class="nb">"stdin"</span>, line <span class="m">2</span>, in <span class="n">generate_ints</span>
- <span class="gr">StopIteration</span>
- </pre></div>
- </div>
- <p>You could equally write <code class="docutils literal notranslate"><span class="pre">for</span> <span class="pre">i</span> <span class="pre">in</span> <span class="pre">generate_ints(5)</span></code>, or <code class="docutils literal notranslate"><span class="pre">a,</span> <span class="pre">b,</span> <span class="pre">c</span> <span class="pre">=</span>
- <span class="pre">generate_ints(3)</span></code>.</p>
- <p>Inside a generator function, <code class="docutils literal notranslate"><span class="pre">return</span> <span class="pre">value</span></code> causes <code class="docutils literal notranslate"><span class="pre">StopIteration(value)</span></code>
- to be raised from the <a class="reference internal" href="../reference/expressions.html#generator.__next__" title="generator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> method. Once this happens, or
- the bottom of the function is reached, the procession of values ends and the
- generator cannot yield any further values.</p>
- <p>You could achieve the effect of generators manually by writing your own class
- and storing all the local variables of the generator as instance variables. For
- example, returning a list of integers could be done by setting <code class="docutils literal notranslate"><span class="pre">self.count</span></code> to
- 0, and having the <a class="reference internal" href="../library/stdtypes.html#iterator.__next__" title="iterator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> method increment <code class="docutils literal notranslate"><span class="pre">self.count</span></code> and
- return it.
- However, for a moderately complicated generator, writing a corresponding class
- can be much messier.</p>
- <p>The test suite included with Python’s library,
- <a class="reference external" href="https://github.com/python/cpython/tree/3.12/Lib/test/test_generators.py">Lib/test/test_generators.py</a>, contains
- a number of more interesting examples. Here’s one generator that implements an
- in-order traversal of a tree using generators recursively.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="c1"># A recursive generator that generates Tree leaves in in-order.</span>
- <span class="k">def</span> <span class="nf">inorder</span><span class="p">(</span><span class="n">t</span><span class="p">):</span>
- <span class="k">if</span> <span class="n">t</span><span class="p">:</span>
- <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">inorder</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">left</span><span class="p">):</span>
- <span class="k">yield</span> <span class="n">x</span>
-
- <span class="k">yield</span> <span class="n">t</span><span class="o">.</span><span class="n">label</span>
-
- <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">inorder</span><span class="p">(</span><span class="n">t</span><span class="o">.</span><span class="n">right</span><span class="p">):</span>
- <span class="k">yield</span> <span class="n">x</span>
- </pre></div>
- </div>
- <p>Two other examples in <code class="docutils literal notranslate"><span class="pre">test_generators.py</span></code> produce solutions for the N-Queens
- problem (placing N queens on an NxN chess board so that no queen threatens
- another) and the Knight’s Tour (finding a route that takes a knight to every
- square of an NxN chessboard without visiting any square twice).</p>
- <section id="passing-values-into-a-generator">
- <h3>Passing values into a generator<a class="headerlink" href="#passing-values-into-a-generator" title="Link to this heading">¶</a></h3>
- <p>In Python 2.4 and earlier, generators only produced output. Once a generator’s
- code was invoked to create an iterator, there was no way to pass any new
- information into the function when its execution is resumed. You could hack
- together this ability by making the generator look at a global variable or by
- passing in some mutable object that callers then modify, but these approaches
- are messy.</p>
- <p>In Python 2.5 there’s a simple way to pass values into a generator.
- <a class="reference internal" href="../reference/simple_stmts.html#yield"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">yield</span></code></a> became an expression, returning a value that can be assigned to
- a variable or otherwise operated on:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">val</span> <span class="o">=</span> <span class="p">(</span><span class="k">yield</span> <span class="n">i</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>I recommend that you <strong>always</strong> put parentheses around a <code class="docutils literal notranslate"><span class="pre">yield</span></code> expression
- when you’re doing something with the returned value, as in the above example.
- The parentheses aren’t always necessary, but it’s easier to always add them
- instead of having to remember when they’re needed.</p>
- <p>(<span class="target" id="index-0"></span><a class="pep reference external" href="https://peps.python.org/pep-0342/"><strong>PEP 342</strong></a> explains the exact rules, which are that a <code class="docutils literal notranslate"><span class="pre">yield</span></code>-expression must
- always be parenthesized except when it occurs at the top-level expression on the
- right-hand side of an assignment. This means you can write <code class="docutils literal notranslate"><span class="pre">val</span> <span class="pre">=</span> <span class="pre">yield</span> <span class="pre">i</span></code>
- but have to use parentheses when there’s an operation, as in <code class="docutils literal notranslate"><span class="pre">val</span> <span class="pre">=</span> <span class="pre">(yield</span> <span class="pre">i)</span>
- <span class="pre">+</span> <span class="pre">12</span></code>.)</p>
- <p>Values are sent into a generator by calling its <a class="reference internal" href="../reference/expressions.html#generator.send" title="generator.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send(value)</span></code></a> method. This method resumes the generator’s code and the
- <code class="docutils literal notranslate"><span class="pre">yield</span></code> expression returns the specified value. If the regular
- <a class="reference internal" href="../reference/expressions.html#generator.__next__" title="generator.__next__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__next__()</span></code></a> method is called, the <code class="docutils literal notranslate"><span class="pre">yield</span></code> returns <code class="docutils literal notranslate"><span class="pre">None</span></code>.</p>
- <p>Here’s a simple counter that increments by 1 and allows changing the value of
- the internal counter.</p>
- <div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">counter</span><span class="p">(</span><span class="n">maximum</span><span class="p">):</span>
- <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
- <span class="k">while</span> <span class="n">i</span> <span class="o"><</span> <span class="n">maximum</span><span class="p">:</span>
- <span class="n">val</span> <span class="o">=</span> <span class="p">(</span><span class="k">yield</span> <span class="n">i</span><span class="p">)</span>
- <span class="c1"># If value provided, change counter</span>
- <span class="k">if</span> <span class="n">val</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
- <span class="n">i</span> <span class="o">=</span> <span class="n">val</span>
- <span class="k">else</span><span class="p">:</span>
- <span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
- </pre></div>
- </div>
- <p>And here’s an example of changing the counter:</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">it</span> <span class="o">=</span> <span class="n">counter</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
- <span class="go">0</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
- <span class="go">1</span>
- <span class="gp">>>> </span><span class="n">it</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="mi">8</span><span class="p">)</span>
- <span class="go">8</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
- <span class="go">9</span>
- <span class="gp">>>> </span><span class="nb">next</span><span class="p">(</span><span class="n">it</span><span class="p">)</span>
- <span class="gt">Traceback (most recent call last):</span>
- File <span class="nb">"t.py"</span>, line <span class="m">15</span>, in <span class="n"><module></span>
- <span class="w"> </span><span class="n">it</span><span class="o">.</span><span class="n">next</span><span class="p">()</span>
- <span class="gr">StopIteration</span>
- </pre></div>
- </div>
- <p>Because <code class="docutils literal notranslate"><span class="pre">yield</span></code> will often be returning <code class="docutils literal notranslate"><span class="pre">None</span></code>, you should always check for
- this case. Don’t just use its value in expressions unless you’re sure that the
- <a class="reference internal" href="../reference/expressions.html#generator.send" title="generator.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code></a> method will be the only method used to resume your
- generator function.</p>
- <p>In addition to <a class="reference internal" href="../reference/expressions.html#generator.send" title="generator.send"><code class="xref py py-meth docutils literal notranslate"><span class="pre">send()</span></code></a>, there are two other methods on
- generators:</p>
- <ul>
- <li><p><a class="reference internal" href="../reference/expressions.html#generator.throw" title="generator.throw"><code class="xref py py-meth docutils literal notranslate"><span class="pre">throw(value)</span></code></a> is used to
- raise an exception inside the generator; the exception is raised by the
- <code class="docutils literal notranslate"><span class="pre">yield</span></code> expression where the generator’s execution is paused.</p></li>
- <li><p><a class="reference internal" href="../reference/expressions.html#generator.close" title="generator.close"><code class="xref py py-meth docutils literal notranslate"><span class="pre">close()</span></code></a> raises a <a class="reference internal" href="../library/exceptions.html#GeneratorExit" title="GeneratorExit"><code class="xref py py-exc docutils literal notranslate"><span class="pre">GeneratorExit</span></code></a> exception inside the
- generator to terminate the iteration. On receiving this exception, the
- generator’s code must either raise <a class="reference internal" href="../library/exceptions.html#GeneratorExit" title="GeneratorExit"><code class="xref py py-exc docutils literal notranslate"><span class="pre">GeneratorExit</span></code></a> or
- <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a>; catching the exception and doing anything else is
- illegal and will trigger a <a class="reference internal" href="../library/exceptions.html#RuntimeError" title="RuntimeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">RuntimeError</span></code></a>. <a class="reference internal" href="../reference/expressions.html#generator.close" title="generator.close"><code class="xref py py-meth docutils literal notranslate"><span class="pre">close()</span></code></a>
- will also be called by Python’s garbage collector when the generator is
- garbage-collected.</p>
- <p>If you need to run cleanup code when a <a class="reference internal" href="../library/exceptions.html#GeneratorExit" title="GeneratorExit"><code class="xref py py-exc docutils literal notranslate"><span class="pre">GeneratorExit</span></code></a> occurs, I suggest
- using a <code class="docutils literal notranslate"><span class="pre">try:</span> <span class="pre">...</span> <span class="pre">finally:</span></code> suite instead of catching <a class="reference internal" href="../library/exceptions.html#GeneratorExit" title="GeneratorExit"><code class="xref py py-exc docutils literal notranslate"><span class="pre">GeneratorExit</span></code></a>.</p>
- </li>
- </ul>
- <p>The cumulative effect of these changes is to turn generators from one-way
- producers of information into both producers and consumers.</p>
- <p>Generators also become <strong>coroutines</strong>, a more generalized form of subroutines.
- Subroutines are entered at one point and exited at another point (the top of the
- function, and a <code class="docutils literal notranslate"><span class="pre">return</span></code> statement), but coroutines can be entered, exited,
- and resumed at many different points (the <code class="docutils literal notranslate"><span class="pre">yield</span></code> statements).</p>
- </section>
- </section>
- <section id="built-in-functions">
- <h2>Built-in functions<a class="headerlink" href="#built-in-functions" title="Link to this heading">¶</a></h2>
- <p>Let’s look in more detail at built-in functions often used with iterators.</p>
- <p>Two of Python’s built-in functions, <a class="reference internal" href="../library/functions.html#map" title="map"><code class="xref py py-func docutils literal notranslate"><span class="pre">map()</span></code></a> and <a class="reference internal" href="../library/functions.html#filter" title="filter"><code class="xref py py-func docutils literal notranslate"><span class="pre">filter()</span></code></a> duplicate the
- features of generator expressions:</p>
- <dl>
- <dt><a class="reference internal" href="../library/functions.html#map" title="map"><code class="xref py py-func docutils literal notranslate"><span class="pre">map(f,</span> <span class="pre">iterA,</span> <span class="pre">iterB,</span> <span class="pre">...)</span></code></a> returns an iterator over the sequence</dt><dd><p><code class="docutils literal notranslate"><span class="pre">f(iterA[0],</span> <span class="pre">iterB[0]),</span> <span class="pre">f(iterA[1],</span> <span class="pre">iterB[1]),</span> <span class="pre">f(iterA[2],</span> <span class="pre">iterB[2]),</span> <span class="pre">...</span></code>.</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">def</span> <span class="nf">upper</span><span class="p">(</span><span class="n">s</span><span class="p">):</span>
- <span class="gp">... </span> <span class="k">return</span> <span class="n">s</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
- </pre></div>
- </div>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">list</span><span class="p">(</span><span class="nb">map</span><span class="p">(</span><span class="n">upper</span><span class="p">,</span> <span class="p">[</span><span class="s1">'sentence'</span><span class="p">,</span> <span class="s1">'fragment'</span><span class="p">]))</span>
- <span class="go">['SENTENCE', 'FRAGMENT']</span>
- <span class="gp">>>> </span><span class="p">[</span><span class="n">upper</span><span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="k">for</span> <span class="n">s</span> <span class="ow">in</span> <span class="p">[</span><span class="s1">'sentence'</span><span class="p">,</span> <span class="s1">'fragment'</span><span class="p">]]</span>
- <span class="go">['SENTENCE', 'FRAGMENT']</span>
- </pre></div>
- </div>
- </dd>
- </dl>
- <p>You can of course achieve the same effect with a list comprehension.</p>
- <p><a class="reference internal" href="../library/functions.html#filter" title="filter"><code class="xref py py-func docutils literal notranslate"><span class="pre">filter(predicate,</span> <span class="pre">iter)</span></code></a> returns an iterator over all the
- sequence elements that meet a certain condition, and is similarly duplicated by
- list comprehensions. A <strong>predicate</strong> is a function that returns the truth
- value of some condition; for use with <a class="reference internal" href="../library/functions.html#filter" title="filter"><code class="xref py py-func docutils literal notranslate"><span class="pre">filter()</span></code></a>, the predicate must take a
- single value.</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">def</span> <span class="nf">is_even</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
- <span class="gp">... </span> <span class="k">return</span> <span class="p">(</span><span class="n">x</span> <span class="o">%</span> <span class="mi">2</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span>
- </pre></div>
- </div>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">list</span><span class="p">(</span><span class="nb">filter</span><span class="p">(</span><span class="n">is_even</span><span class="p">,</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)))</span>
- <span class="go">[0, 2, 4, 6, 8]</span>
- </pre></div>
- </div>
- <p>This can also be written as a list comprehension:</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">list</span><span class="p">(</span><span class="n">x</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="k">if</span> <span class="n">is_even</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
- <span class="go">[0, 2, 4, 6, 8]</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/functions.html#enumerate" title="enumerate"><code class="xref py py-func docutils literal notranslate"><span class="pre">enumerate(iter,</span> <span class="pre">start=0)</span></code></a> counts off the elements in the
- iterable returning 2-tuples containing the count (from <em>start</em>) and
- each element.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="k">for</span> <span class="n">item</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">([</span><span class="s1">'subject'</span><span class="p">,</span> <span class="s1">'verb'</span><span class="p">,</span> <span class="s1">'object'</span><span class="p">]):</span>
- <span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="n">item</span><span class="p">)</span>
- <span class="go">(0, 'subject')</span>
- <span class="go">(1, 'verb')</span>
- <span class="go">(2, 'object')</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/functions.html#enumerate" title="enumerate"><code class="xref py py-func docutils literal notranslate"><span class="pre">enumerate()</span></code></a> is often used when looping through a list and recording the
- indexes at which certain conditions are met:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">f</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'data.txt'</span><span class="p">,</span> <span class="s1">'r'</span><span class="p">)</span>
- <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">line</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">f</span><span class="p">):</span>
- <span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="o">==</span> <span class="s1">''</span><span class="p">:</span>
- <span class="nb">print</span><span class="p">(</span><span class="s1">'Blank line at line #</span><span class="si">%i</span><span class="s1">'</span> <span class="o">%</span> <span class="n">i</span><span class="p">)</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/functions.html#sorted" title="sorted"><code class="xref py py-func docutils literal notranslate"><span class="pre">sorted(iterable,</span> <span class="pre">key=None,</span> <span class="pre">reverse=False)</span></code></a> collects all the
- elements of the iterable into a list, sorts the list, and returns the sorted
- result. The <em>key</em> and <em>reverse</em> arguments are passed through to the
- constructed list’s <a class="reference internal" href="../library/stdtypes.html#list.sort" title="list.sort"><code class="xref py py-meth docutils literal notranslate"><span class="pre">sort()</span></code></a> method.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">random</span>
- <span class="gp">>>> </span><span class="c1"># Generate 8 random numbers between [0, 10000)</span>
- <span class="gp">>>> </span><span class="n">rand_list</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">sample</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">10000</span><span class="p">),</span> <span class="mi">8</span><span class="p">)</span>
- <span class="gp">>>> </span><span class="n">rand_list</span>
- <span class="go">[769, 7953, 9828, 6431, 8442, 9878, 6213, 2207]</span>
- <span class="gp">>>> </span><span class="nb">sorted</span><span class="p">(</span><span class="n">rand_list</span><span class="p">)</span>
- <span class="go">[769, 2207, 6213, 6431, 7953, 8442, 9828, 9878]</span>
- <span class="gp">>>> </span><span class="nb">sorted</span><span class="p">(</span><span class="n">rand_list</span><span class="p">,</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
- <span class="go">[9878, 9828, 8442, 7953, 6431, 6213, 2207, 769]</span>
- </pre></div>
- </div>
- <p>(For a more detailed discussion of sorting, see the <a class="reference internal" href="sorting.html#sortinghowto"><span class="std std-ref">Sorting Techniques</span></a>.)</p>
- <p>The <a class="reference internal" href="../library/functions.html#any" title="any"><code class="xref py py-func docutils literal notranslate"><span class="pre">any(iter)</span></code></a> and <a class="reference internal" href="../library/functions.html#all" title="all"><code class="xref py py-func docutils literal notranslate"><span class="pre">all(iter)</span></code></a> built-ins look at the
- truth values of an iterable’s contents. <a class="reference internal" href="../library/functions.html#any" title="any"><code class="xref py py-func docutils literal notranslate"><span class="pre">any()</span></code></a> returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if any element
- in the iterable is a true value, and <a class="reference internal" href="../library/functions.html#all" title="all"><code class="xref py py-func docutils literal notranslate"><span class="pre">all()</span></code></a> returns <code class="docutils literal notranslate"><span class="pre">True</span></code> if all of the
- elements are true values:</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">any</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">])</span>
- <span class="go">True</span>
- <span class="gp">>>> </span><span class="nb">any</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">])</span>
- <span class="go">False</span>
- <span class="gp">>>> </span><span class="nb">any</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
- <span class="go">True</span>
- <span class="gp">>>> </span><span class="nb">all</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">])</span>
- <span class="go">False</span>
- <span class="gp">>>> </span><span class="nb">all</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">])</span>
- <span class="go">False</span>
- <span class="gp">>>> </span><span class="nb">all</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">])</span>
- <span class="go">True</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/functions.html#zip" title="zip"><code class="xref py py-func docutils literal notranslate"><span class="pre">zip(iterA,</span> <span class="pre">iterB,</span> <span class="pre">...)</span></code></a> takes one element from each iterable and
- returns them in a tuple:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nb">zip</span><span class="p">([</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">,</span> <span class="s1">'c'</span><span class="p">],</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span> <span class="o">=></span>
- <span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="s1">'b'</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="s1">'c'</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>It doesn’t construct an in-memory list and exhaust all the input iterators
- before returning; instead tuples are constructed and returned only if they’re
- requested. (The technical term for this behaviour is <a class="reference external" href="https://en.wikipedia.org/wiki/Lazy_evaluation">lazy evaluation</a>.)</p>
- <p>This iterator is intended to be used with iterables that are all of the same
- length. If the iterables are of different lengths, the resulting stream will be
- the same length as the shortest iterable.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nb">zip</span><span class="p">([</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">],</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span> <span class="o">=></span>
- <span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="s1">'b'</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>You should avoid doing this, though, because an element may be taken from the
- longer iterators and discarded. This means you can’t go on to use the iterators
- further because you risk skipping a discarded element.</p>
- </section>
- <section id="the-itertools-module">
- <h2>The itertools module<a class="headerlink" href="#the-itertools-module" title="Link to this heading">¶</a></h2>
- <p>The <a class="reference internal" href="../library/itertools.html#module-itertools" title="itertools: Functions creating iterators for efficient looping."><code class="xref py py-mod docutils literal notranslate"><span class="pre">itertools</span></code></a> module contains a number of commonly used iterators as well
- as functions for combining several iterators. This section will introduce the
- module’s contents by showing small examples.</p>
- <p>The module’s functions fall into a few broad classes:</p>
- <ul class="simple">
- <li><p>Functions that create a new iterator based on an existing iterator.</p></li>
- <li><p>Functions for treating an iterator’s elements as function arguments.</p></li>
- <li><p>Functions for selecting portions of an iterator’s output.</p></li>
- <li><p>A function for grouping an iterator’s output.</p></li>
- </ul>
- <section id="creating-new-iterators">
- <h3>Creating new iterators<a class="headerlink" href="#creating-new-iterators" title="Link to this heading">¶</a></h3>
- <p><a class="reference internal" href="../library/itertools.html#itertools.count" title="itertools.count"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.count(start,</span> <span class="pre">step)</span></code></a> returns an infinite
- stream of evenly spaced values. You can optionally supply the starting number,
- which defaults to 0, and the interval between numbers, which defaults to 1:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">count</span><span class="p">()</span> <span class="o">=></span>
- <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="o">...</span>
- <span class="n">itertools</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span> <span class="o">=></span>
- <span class="mi">10</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">14</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">19</span><span class="p">,</span> <span class="o">...</span>
- <span class="n">itertools</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span> <span class="o">=></span>
- <span class="mi">10</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">25</span><span class="p">,</span> <span class="mi">30</span><span class="p">,</span> <span class="mi">35</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">45</span><span class="p">,</span> <span class="mi">50</span><span class="p">,</span> <span class="mi">55</span><span class="p">,</span> <span class="o">...</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/itertools.html#itertools.cycle" title="itertools.cycle"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.cycle(iter)</span></code></a> saves a copy of the contents of
- a provided iterable and returns a new iterator that returns its elements from
- first to last. The new iterator will repeat these elements infinitely.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">cycle</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">])</span> <span class="o">=></span>
- <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="o">...</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/itertools.html#itertools.repeat" title="itertools.repeat"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.repeat(elem,</span> <span class="pre">[n])</span></code></a> returns the provided
- element <em>n</em> times, or returns the element endlessly if <em>n</em> is not provided.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">repeat</span><span class="p">(</span><span class="s1">'abc'</span><span class="p">)</span> <span class="o">=></span>
- <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span><span class="p">,</span> <span class="o">...</span>
- <span class="n">itertools</span><span class="o">.</span><span class="n">repeat</span><span class="p">(</span><span class="s1">'abc'</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span> <span class="o">=></span>
- <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span><span class="p">,</span> <span class="n">abc</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/itertools.html#itertools.chain" title="itertools.chain"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.chain(iterA,</span> <span class="pre">iterB,</span> <span class="pre">...)</span></code></a> takes an arbitrary
- number of iterables as input, and returns all the elements of the first
- iterator, then all the elements of the second, and so on, until all of the
- iterables have been exhausted.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">chain</span><span class="p">([</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">,</span> <span class="s1">'c'</span><span class="p">],</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">))</span> <span class="o">=></span>
- <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">c</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/itertools.html#itertools.islice" title="itertools.islice"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.islice(iter,</span> <span class="pre">[start],</span> <span class="pre">stop,</span> <span class="pre">[step])</span></code></a> returns
- a stream that’s a slice of the iterator. With a single <em>stop</em> argument, it
- will return the first <em>stop</em> elements. If you supply a starting index, you’ll
- get <em>stop-start</em> elements, and if you supply a value for <em>step</em>, elements
- will be skipped accordingly. Unlike Python’s string and list slicing, you can’t
- use negative values for <em>start</em>, <em>stop</em>, or <em>step</em>.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">islice</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">),</span> <span class="mi">8</span><span class="p">)</span> <span class="o">=></span>
- <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span>
- <span class="n">itertools</span><span class="o">.</span><span class="n">islice</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">),</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> <span class="o">=></span>
- <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span>
- <span class="n">itertools</span><span class="o">.</span><span class="n">islice</span><span class="p">(</span><span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">),</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="o">=></span>
- <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">6</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/itertools.html#itertools.tee" title="itertools.tee"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.tee(iter,</span> <span class="pre">[n])</span></code></a> replicates an iterator; it
- returns <em>n</em> independent iterators that will all return the contents of the
- source iterator.
- If you don’t supply a value for <em>n</em>, the default is 2. Replicating iterators
- requires saving some of the contents of the source iterator, so this can consume
- significant memory if the iterator is large and one of the new iterators is
- consumed more than the others.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">tee</span><span class="p">(</span> <span class="n">itertools</span><span class="o">.</span><span class="n">count</span><span class="p">()</span> <span class="p">)</span> <span class="o">=></span>
- <span class="n">iterA</span><span class="p">,</span> <span class="n">iterB</span>
-
- <span class="n">where</span> <span class="n">iterA</span> <span class="o">-></span>
- <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="o">...</span>
-
- <span class="ow">and</span> <span class="n">iterB</span> <span class="o">-></span>
- <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="o">...</span>
- </pre></div>
- </div>
- </section>
- <section id="calling-functions-on-elements">
- <h3>Calling functions on elements<a class="headerlink" href="#calling-functions-on-elements" title="Link to this heading">¶</a></h3>
- <p>The <a class="reference internal" href="../library/operator.html#module-operator" title="operator: Functions corresponding to the standard operators."><code class="xref py py-mod docutils literal notranslate"><span class="pre">operator</span></code></a> module contains a set of functions corresponding to Python’s
- operators. Some examples are <a class="reference internal" href="../library/operator.html#operator.add" title="operator.add"><code class="xref py py-func docutils literal notranslate"><span class="pre">operator.add(a,</span> <span class="pre">b)</span></code></a> (adds
- two values), <a class="reference internal" href="../library/operator.html#operator.ne" title="operator.ne"><code class="xref py py-func docutils literal notranslate"><span class="pre">operator.ne(a,</span> <span class="pre">b)</span></code></a> (same as <code class="docutils literal notranslate"><span class="pre">a</span> <span class="pre">!=</span> <span class="pre">b</span></code>), and
- <a class="reference internal" href="../library/operator.html#operator.attrgetter" title="operator.attrgetter"><code class="xref py py-func docutils literal notranslate"><span class="pre">operator.attrgetter('id')</span></code></a>
- (returns a callable that fetches the <code class="docutils literal notranslate"><span class="pre">.id</span></code> attribute).</p>
- <p><a class="reference internal" href="../library/itertools.html#itertools.starmap" title="itertools.starmap"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.starmap(func,</span> <span class="pre">iter)</span></code></a> assumes that the
- iterable will return a stream of tuples, and calls <em>func</em> using these tuples as
- the arguments:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">starmap</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">,</span>
- <span class="p">[(</span><span class="s1">'/bin'</span><span class="p">,</span> <span class="s1">'python'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'/usr'</span><span class="p">,</span> <span class="s1">'bin'</span><span class="p">,</span> <span class="s1">'java'</span><span class="p">),</span>
- <span class="p">(</span><span class="s1">'/usr'</span><span class="p">,</span> <span class="s1">'bin'</span><span class="p">,</span> <span class="s1">'perl'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'/usr'</span><span class="p">,</span> <span class="s1">'bin'</span><span class="p">,</span> <span class="s1">'ruby'</span><span class="p">)])</span>
- <span class="o">=></span>
- <span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">python</span><span class="p">,</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">java</span><span class="p">,</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">perl</span><span class="p">,</span> <span class="o">/</span><span class="n">usr</span><span class="o">/</span><span class="nb">bin</span><span class="o">/</span><span class="n">ruby</span>
- </pre></div>
- </div>
- </section>
- <section id="selecting-elements">
- <h3>Selecting elements<a class="headerlink" href="#selecting-elements" title="Link to this heading">¶</a></h3>
- <p>Another group of functions chooses a subset of an iterator’s elements based on a
- predicate.</p>
- <p><a class="reference internal" href="../library/itertools.html#itertools.filterfalse" title="itertools.filterfalse"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.filterfalse(predicate,</span> <span class="pre">iter)</span></code></a> is the
- opposite of <a class="reference internal" href="../library/functions.html#filter" title="filter"><code class="xref py py-func docutils literal notranslate"><span class="pre">filter()</span></code></a>, returning all elements for which the predicate
- returns false:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">filterfalse</span><span class="p">(</span><span class="n">is_even</span><span class="p">,</span> <span class="n">itertools</span><span class="o">.</span><span class="n">count</span><span class="p">())</span> <span class="o">=></span>
- <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="o">...</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/itertools.html#itertools.takewhile" title="itertools.takewhile"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.takewhile(predicate,</span> <span class="pre">iter)</span></code></a> returns
- elements for as long as the predicate returns true. Once the predicate returns
- false, the iterator will signal the end of its results.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">less_than_10</span><span class="p">(</span><span class="n">x</span><span class="p">):</span>
- <span class="k">return</span> <span class="n">x</span> <span class="o"><</span> <span class="mi">10</span>
-
- <span class="n">itertools</span><span class="o">.</span><span class="n">takewhile</span><span class="p">(</span><span class="n">less_than_10</span><span class="p">,</span> <span class="n">itertools</span><span class="o">.</span><span class="n">count</span><span class="p">())</span> <span class="o">=></span>
- <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span>
-
- <span class="n">itertools</span><span class="o">.</span><span class="n">takewhile</span><span class="p">(</span><span class="n">is_even</span><span class="p">,</span> <span class="n">itertools</span><span class="o">.</span><span class="n">count</span><span class="p">())</span> <span class="o">=></span>
- <span class="mi">0</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/itertools.html#itertools.dropwhile" title="itertools.dropwhile"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.dropwhile(predicate,</span> <span class="pre">iter)</span></code></a> discards
- elements while the predicate returns true, and then returns the rest of the
- iterable’s results.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">dropwhile</span><span class="p">(</span><span class="n">less_than_10</span><span class="p">,</span> <span class="n">itertools</span><span class="o">.</span><span class="n">count</span><span class="p">())</span> <span class="o">=></span>
- <span class="mi">10</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">12</span><span class="p">,</span> <span class="mi">13</span><span class="p">,</span> <span class="mi">14</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="mi">16</span><span class="p">,</span> <span class="mi">17</span><span class="p">,</span> <span class="mi">18</span><span class="p">,</span> <span class="mi">19</span><span class="p">,</span> <span class="o">...</span>
-
- <span class="n">itertools</span><span class="o">.</span><span class="n">dropwhile</span><span class="p">(</span><span class="n">is_even</span><span class="p">,</span> <span class="n">itertools</span><span class="o">.</span><span class="n">count</span><span class="p">())</span> <span class="o">=></span>
- <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="o">...</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/itertools.html#itertools.compress" title="itertools.compress"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.compress(data,</span> <span class="pre">selectors)</span></code></a> takes two
- iterators and returns only those elements of <em>data</em> for which the corresponding
- element of <em>selectors</em> is true, stopping whenever either one is exhausted:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">compress</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">],</span> <span class="p">[</span><span class="kc">True</span><span class="p">,</span> <span class="kc">True</span><span class="p">,</span> <span class="kc">False</span><span class="p">,</span> <span class="kc">False</span><span class="p">,</span> <span class="kc">True</span><span class="p">])</span> <span class="o">=></span>
- <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span>
- </pre></div>
- </div>
- </section>
- <section id="combinatoric-functions">
- <h3>Combinatoric functions<a class="headerlink" href="#combinatoric-functions" title="Link to this heading">¶</a></h3>
- <p>The <a class="reference internal" href="../library/itertools.html#itertools.combinations" title="itertools.combinations"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.combinations(iterable,</span> <span class="pre">r)</span></code></a>
- returns an iterator giving all possible <em>r</em>-tuple combinations of the
- elements contained in <em>iterable</em>.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">combinations</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">],</span> <span class="mi">2</span><span class="p">)</span> <span class="o">=></span>
- <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
-
- <span class="n">itertools</span><span class="o">.</span><span class="n">combinations</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">],</span> <span class="mi">3</span><span class="p">)</span> <span class="o">=></span>
- <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>The elements within each tuple remain in the same order as
- <em>iterable</em> returned them. For example, the number 1 is always before
- 2, 3, 4, or 5 in the examples above. A similar function,
- <a class="reference internal" href="../library/itertools.html#itertools.permutations" title="itertools.permutations"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.permutations(iterable,</span> <span class="pre">r=None)</span></code></a>,
- removes this constraint on the order, returning all possible
- arrangements of length <em>r</em>:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">permutations</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">],</span> <span class="mi">2</span><span class="p">)</span> <span class="o">=></span>
- <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">)</span>
-
- <span class="n">itertools</span><span class="o">.</span><span class="n">permutations</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">])</span> <span class="o">=></span>
- <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="o">...</span>
- <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>If you don’t supply a value for <em>r</em> the length of the iterable is used,
- meaning that all the elements are permuted.</p>
- <p>Note that these functions produce all of the possible combinations by
- position and don’t require that the contents of <em>iterable</em> are unique:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">permutations</span><span class="p">(</span><span class="s1">'aba'</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span> <span class="o">=></span>
- <span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'b'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">),</span>
- <span class="p">(</span><span class="s1">'b'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'a'</span><span class="p">,</span> <span class="s1">'b'</span><span class="p">,</span> <span class="s1">'a'</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>The identical tuple <code class="docutils literal notranslate"><span class="pre">('a',</span> <span class="pre">'a',</span> <span class="pre">'b')</span></code> occurs twice, but the two ‘a’
- strings came from different positions.</p>
- <p>The <a class="reference internal" href="../library/itertools.html#itertools.combinations_with_replacement" title="itertools.combinations_with_replacement"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.combinations_with_replacement(iterable,</span> <span class="pre">r)</span></code></a>
- function relaxes a different constraint: elements can be repeated
- within a single tuple. Conceptually an element is selected for the
- first position of each tuple and then is replaced before the second
- element is selected.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">combinations_with_replacement</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">],</span> <span class="mi">2</span><span class="p">)</span> <span class="o">=></span>
- <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">),</span>
- <span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
- </pre></div>
- </div>
- </section>
- <section id="grouping-elements">
- <h3>Grouping elements<a class="headerlink" href="#grouping-elements" title="Link to this heading">¶</a></h3>
- <p>The last function I’ll discuss, <a class="reference internal" href="../library/itertools.html#itertools.groupby" title="itertools.groupby"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.groupby(iter,</span> <span class="pre">key_func=None)</span></code></a>, is the most complicated. <code class="docutils literal notranslate"><span class="pre">key_func(elem)</span></code> is a function
- that can compute a key value for each element returned by the iterable. If you
- don’t supply a key function, the key is simply each element itself.</p>
- <p><a class="reference internal" href="../library/itertools.html#itertools.groupby" title="itertools.groupby"><code class="xref py py-func docutils literal notranslate"><span class="pre">groupby()</span></code></a> collects all the consecutive elements from the
- underlying iterable that have the same key value, and returns a stream of
- 2-tuples containing a key value and an iterator for the elements with that key.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">city_list</span> <span class="o">=</span> <span class="p">[(</span><span class="s1">'Decatur'</span><span class="p">,</span> <span class="s1">'AL'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'Huntsville'</span><span class="p">,</span> <span class="s1">'AL'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'Selma'</span><span class="p">,</span> <span class="s1">'AL'</span><span class="p">),</span>
- <span class="p">(</span><span class="s1">'Anchorage'</span><span class="p">,</span> <span class="s1">'AK'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'Nome'</span><span class="p">,</span> <span class="s1">'AK'</span><span class="p">),</span>
- <span class="p">(</span><span class="s1">'Flagstaff'</span><span class="p">,</span> <span class="s1">'AZ'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'Phoenix'</span><span class="p">,</span> <span class="s1">'AZ'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'Tucson'</span><span class="p">,</span> <span class="s1">'AZ'</span><span class="p">),</span>
- <span class="o">...</span>
- <span class="p">]</span>
-
- <span class="k">def</span> <span class="nf">get_state</span><span class="p">(</span><span class="n">city_state</span><span class="p">):</span>
- <span class="k">return</span> <span class="n">city_state</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
-
- <span class="n">itertools</span><span class="o">.</span><span class="n">groupby</span><span class="p">(</span><span class="n">city_list</span><span class="p">,</span> <span class="n">get_state</span><span class="p">)</span> <span class="o">=></span>
- <span class="p">(</span><span class="s1">'AL'</span><span class="p">,</span> <span class="n">iterator</span><span class="o">-</span><span class="mi">1</span><span class="p">),</span>
- <span class="p">(</span><span class="s1">'AK'</span><span class="p">,</span> <span class="n">iterator</span><span class="o">-</span><span class="mi">2</span><span class="p">),</span>
- <span class="p">(</span><span class="s1">'AZ'</span><span class="p">,</span> <span class="n">iterator</span><span class="o">-</span><span class="mi">3</span><span class="p">),</span> <span class="o">...</span>
-
- <span class="n">where</span>
- <span class="n">iterator</span><span class="o">-</span><span class="mi">1</span> <span class="o">=></span>
- <span class="p">(</span><span class="s1">'Decatur'</span><span class="p">,</span> <span class="s1">'AL'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'Huntsville'</span><span class="p">,</span> <span class="s1">'AL'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'Selma'</span><span class="p">,</span> <span class="s1">'AL'</span><span class="p">)</span>
- <span class="n">iterator</span><span class="o">-</span><span class="mi">2</span> <span class="o">=></span>
- <span class="p">(</span><span class="s1">'Anchorage'</span><span class="p">,</span> <span class="s1">'AK'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'Nome'</span><span class="p">,</span> <span class="s1">'AK'</span><span class="p">)</span>
- <span class="n">iterator</span><span class="o">-</span><span class="mi">3</span> <span class="o">=></span>
- <span class="p">(</span><span class="s1">'Flagstaff'</span><span class="p">,</span> <span class="s1">'AZ'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'Phoenix'</span><span class="p">,</span> <span class="s1">'AZ'</span><span class="p">),</span> <span class="p">(</span><span class="s1">'Tucson'</span><span class="p">,</span> <span class="s1">'AZ'</span><span class="p">)</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/itertools.html#itertools.groupby" title="itertools.groupby"><code class="xref py py-func docutils literal notranslate"><span class="pre">groupby()</span></code></a> assumes that the underlying iterable’s contents will
- already be sorted based on the key. Note that the returned iterators also use
- the underlying iterable, so you have to consume the results of iterator-1 before
- requesting iterator-2 and its corresponding key.</p>
- </section>
- </section>
- <section id="the-functools-module">
- <h2>The functools module<a class="headerlink" href="#the-functools-module" title="Link to this heading">¶</a></h2>
- <p>The <a class="reference internal" href="../library/functools.html#module-functools" title="functools: Higher-order functions and operations on callable objects."><code class="xref py py-mod docutils literal notranslate"><span class="pre">functools</span></code></a> module contains some higher-order functions.
- A <strong>higher-order function</strong> takes one or more functions as input and returns a
- new function. The most useful tool in this module is the
- <a class="reference internal" href="../library/functools.html#functools.partial" title="functools.partial"><code class="xref py py-func docutils literal notranslate"><span class="pre">functools.partial()</span></code></a> function.</p>
- <p>For programs written in a functional style, you’ll sometimes want to construct
- variants of existing functions that have some of the parameters filled in.
- Consider a Python function <code class="docutils literal notranslate"><span class="pre">f(a,</span> <span class="pre">b,</span> <span class="pre">c)</span></code>; you may wish to create a new function
- <code class="docutils literal notranslate"><span class="pre">g(b,</span> <span class="pre">c)</span></code> that’s equivalent to <code class="docutils literal notranslate"><span class="pre">f(1,</span> <span class="pre">b,</span> <span class="pre">c)</span></code>; you’re filling in a value for
- one of <code class="docutils literal notranslate"><span class="pre">f()</span></code>’s parameters. This is called “partial function application”.</p>
- <p>The constructor for <a class="reference internal" href="../library/functools.html#functools.partial" title="functools.partial"><code class="xref py py-func docutils literal notranslate"><span class="pre">partial()</span></code></a> takes the arguments
- <code class="docutils literal notranslate"><span class="pre">(function,</span> <span class="pre">arg1,</span> <span class="pre">arg2,</span> <span class="pre">...,</span> <span class="pre">kwarg1=value1,</span> <span class="pre">kwarg2=value2)</span></code>. The resulting
- object is callable, so you can just call it to invoke <code class="docutils literal notranslate"><span class="pre">function</span></code> with the
- filled-in arguments.</p>
- <p>Here’s a small but realistic example:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">functools</span>
-
- <span class="k">def</span> <span class="nf">log</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">subsystem</span><span class="p">):</span>
- <span class="w"> </span><span class="sd">"""Write the contents of 'message' to the specified subsystem."""</span>
- <span class="nb">print</span><span class="p">(</span><span class="s1">'</span><span class="si">%s</span><span class="s1">: </span><span class="si">%s</span><span class="s1">'</span> <span class="o">%</span> <span class="p">(</span><span class="n">subsystem</span><span class="p">,</span> <span class="n">message</span><span class="p">))</span>
- <span class="o">...</span>
-
- <span class="n">server_log</span> <span class="o">=</span> <span class="n">functools</span><span class="o">.</span><span class="n">partial</span><span class="p">(</span><span class="n">log</span><span class="p">,</span> <span class="n">subsystem</span><span class="o">=</span><span class="s1">'server'</span><span class="p">)</span>
- <span class="n">server_log</span><span class="p">(</span><span class="s1">'Unable to open socket'</span><span class="p">)</span>
- </pre></div>
- </div>
- <p><a class="reference internal" href="../library/functools.html#functools.reduce" title="functools.reduce"><code class="xref py py-func docutils literal notranslate"><span class="pre">functools.reduce(func,</span> <span class="pre">iter,</span> <span class="pre">[initial_value])</span></code></a>
- cumulatively performs an operation on all the iterable’s elements and,
- therefore, can’t be applied to infinite iterables. <em>func</em> must be a function
- that takes two elements and returns a single value. <a class="reference internal" href="../library/functools.html#functools.reduce" title="functools.reduce"><code class="xref py py-func docutils literal notranslate"><span class="pre">functools.reduce()</span></code></a>
- takes the first two elements A and B returned by the iterator and calculates
- <code class="docutils literal notranslate"><span class="pre">func(A,</span> <span class="pre">B)</span></code>. It then requests the third element, C, calculates
- <code class="docutils literal notranslate"><span class="pre">func(func(A,</span> <span class="pre">B),</span> <span class="pre">C)</span></code>, combines this result with the fourth element returned,
- and continues until the iterable is exhausted. If the iterable returns no
- values at all, a <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a> exception is raised. If the initial value is
- supplied, it’s used as a starting point and <code class="docutils literal notranslate"><span class="pre">func(initial_value,</span> <span class="pre">A)</span></code> is the
- first calculation.</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">operator</span><span class="o">,</span> <span class="nn">functools</span>
- <span class="gp">>>> </span><span class="n">functools</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="n">operator</span><span class="o">.</span><span class="n">concat</span><span class="p">,</span> <span class="p">[</span><span class="s1">'A'</span><span class="p">,</span> <span class="s1">'BB'</span><span class="p">,</span> <span class="s1">'C'</span><span class="p">])</span>
- <span class="go">'ABBC'</span>
- <span class="gp">>>> </span><span class="n">functools</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="n">operator</span><span class="o">.</span><span class="n">concat</span><span class="p">,</span> <span class="p">[])</span>
- <span class="gt">Traceback (most recent call last):</span>
- <span class="w"> </span><span class="c">...</span>
- <span class="gr">TypeError</span>: <span class="n">reduce() of empty sequence with no initial value</span>
- <span class="gp">>>> </span><span class="n">functools</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="n">operator</span><span class="o">.</span><span class="n">mul</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span> <span class="mi">1</span><span class="p">)</span>
- <span class="go">6</span>
- <span class="gp">>>> </span><span class="n">functools</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="n">operator</span><span class="o">.</span><span class="n">mul</span><span class="p">,</span> <span class="p">[],</span> <span class="mi">1</span><span class="p">)</span>
- <span class="go">1</span>
- </pre></div>
- </div>
- <p>If you use <a class="reference internal" href="../library/operator.html#operator.add" title="operator.add"><code class="xref py py-func docutils literal notranslate"><span class="pre">operator.add()</span></code></a> with <a class="reference internal" href="../library/functools.html#functools.reduce" title="functools.reduce"><code class="xref py py-func docutils literal notranslate"><span class="pre">functools.reduce()</span></code></a>, you’ll add up all the
- elements of the iterable. This case is so common that there’s a special
- built-in called <a class="reference internal" href="../library/functions.html#sum" title="sum"><code class="xref py py-func docutils literal notranslate"><span class="pre">sum()</span></code></a> to compute it:</p>
- <div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">functools</span><span class="o">,</span> <span class="nn">operator</span>
- <span class="gp">>>> </span><span class="n">functools</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="n">operator</span><span class="o">.</span><span class="n">add</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">],</span> <span class="mi">0</span><span class="p">)</span>
- <span class="go">10</span>
- <span class="gp">>>> </span><span class="nb">sum</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">])</span>
- <span class="go">10</span>
- <span class="gp">>>> </span><span class="nb">sum</span><span class="p">([])</span>
- <span class="go">0</span>
- </pre></div>
- </div>
- <p>For many uses of <a class="reference internal" href="../library/functools.html#functools.reduce" title="functools.reduce"><code class="xref py py-func docutils literal notranslate"><span class="pre">functools.reduce()</span></code></a>, though, it can be clearer to just
- write the obvious <a class="reference internal" href="../reference/compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> loop:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">functools</span>
- <span class="c1"># Instead of:</span>
- <span class="n">product</span> <span class="o">=</span> <span class="n">functools</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="n">operator</span><span class="o">.</span><span class="n">mul</span><span class="p">,</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span> <span class="mi">1</span><span class="p">)</span>
-
- <span class="c1"># You can write:</span>
- <span class="n">product</span> <span class="o">=</span> <span class="mi">1</span>
- <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]:</span>
- <span class="n">product</span> <span class="o">*=</span> <span class="n">i</span>
- </pre></div>
- </div>
- <p>A related function is <a class="reference internal" href="../library/itertools.html#itertools.accumulate" title="itertools.accumulate"><code class="xref py py-func docutils literal notranslate"><span class="pre">itertools.accumulate(iterable,</span> <span class="pre">func=operator.add)</span></code></a>. It performs the same calculation, but instead of
- returning only the final result, <a class="reference internal" href="../library/itertools.html#itertools.accumulate" title="itertools.accumulate"><code class="xref py py-func docutils literal notranslate"><span class="pre">accumulate()</span></code></a> returns an iterator
- that also yields each partial result:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">itertools</span><span class="o">.</span><span class="n">accumulate</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">])</span> <span class="o">=></span>
- <span class="mi">1</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">15</span>
-
- <span class="n">itertools</span><span class="o">.</span><span class="n">accumulate</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">],</span> <span class="n">operator</span><span class="o">.</span><span class="n">mul</span><span class="p">)</span> <span class="o">=></span>
- <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">24</span><span class="p">,</span> <span class="mi">120</span>
- </pre></div>
- </div>
- <section id="the-operator-module">
- <h3>The operator module<a class="headerlink" href="#the-operator-module" title="Link to this heading">¶</a></h3>
- <p>The <a class="reference internal" href="../library/operator.html#module-operator" title="operator: Functions corresponding to the standard operators."><code class="xref py py-mod docutils literal notranslate"><span class="pre">operator</span></code></a> module was mentioned earlier. It contains a set of
- functions corresponding to Python’s operators. These functions are often useful
- in functional-style code because they save you from writing trivial functions
- that perform a single operation.</p>
- <p>Some of the functions in this module are:</p>
- <ul class="simple">
- <li><p>Math operations: <code class="docutils literal notranslate"><span class="pre">add()</span></code>, <code class="docutils literal notranslate"><span class="pre">sub()</span></code>, <code class="docutils literal notranslate"><span class="pre">mul()</span></code>, <code class="docutils literal notranslate"><span class="pre">floordiv()</span></code>, <code class="docutils literal notranslate"><span class="pre">abs()</span></code>, …</p></li>
- <li><p>Logical operations: <code class="docutils literal notranslate"><span class="pre">not_()</span></code>, <code class="docutils literal notranslate"><span class="pre">truth()</span></code>.</p></li>
- <li><p>Bitwise operations: <code class="docutils literal notranslate"><span class="pre">and_()</span></code>, <code class="docutils literal notranslate"><span class="pre">or_()</span></code>, <code class="docutils literal notranslate"><span class="pre">invert()</span></code>.</p></li>
- <li><p>Comparisons: <code class="docutils literal notranslate"><span class="pre">eq()</span></code>, <code class="docutils literal notranslate"><span class="pre">ne()</span></code>, <code class="docutils literal notranslate"><span class="pre">lt()</span></code>, <code class="docutils literal notranslate"><span class="pre">le()</span></code>, <code class="docutils literal notranslate"><span class="pre">gt()</span></code>, and <code class="docutils literal notranslate"><span class="pre">ge()</span></code>.</p></li>
- <li><p>Object identity: <code class="docutils literal notranslate"><span class="pre">is_()</span></code>, <code class="docutils literal notranslate"><span class="pre">is_not()</span></code>.</p></li>
- </ul>
- <p>Consult the operator module’s documentation for a complete list.</p>
- </section>
- </section>
- <section id="small-functions-and-the-lambda-expression">
- <h2>Small functions and the lambda expression<a class="headerlink" href="#small-functions-and-the-lambda-expression" title="Link to this heading">¶</a></h2>
- <p>When writing functional-style programs, you’ll often need little functions that
- act as predicates or that combine elements in some way.</p>
- <p>If there’s a Python built-in or a module function that’s suitable, you don’t
- need to define a new function at all:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">stripped_lines</span> <span class="o">=</span> <span class="p">[</span><span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">]</span>
- <span class="n">existing_files</span> <span class="o">=</span> <span class="nb">filter</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">,</span> <span class="n">file_list</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>If the function you need doesn’t exist, you need to write it. One way to write
- small functions is to use the <a class="reference internal" href="../reference/expressions.html#lambda"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">lambda</span></code></a> expression. <code class="docutils literal notranslate"><span class="pre">lambda</span></code> takes a
- number of parameters and an expression combining these parameters, and creates
- an anonymous function that returns the value of the expression:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">adder</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">:</span> <span class="n">x</span><span class="o">+</span><span class="n">y</span>
-
- <span class="n">print_assign</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">name</span> <span class="o">+</span> <span class="s1">'='</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>An alternative is to just use the <code class="docutils literal notranslate"><span class="pre">def</span></code> statement and define a function in the
- usual way:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">adder</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">):</span>
- <span class="k">return</span> <span class="n">x</span> <span class="o">+</span> <span class="n">y</span>
-
- <span class="k">def</span> <span class="nf">print_assign</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
- <span class="k">return</span> <span class="n">name</span> <span class="o">+</span> <span class="s1">'='</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>Which alternative is preferable? That’s a style question; my usual course is to
- avoid using <code class="docutils literal notranslate"><span class="pre">lambda</span></code>.</p>
- <p>One reason for my preference is that <code class="docutils literal notranslate"><span class="pre">lambda</span></code> is quite limited in the
- functions it can define. The result has to be computable as a single
- expression, which means you can’t have multiway <code class="docutils literal notranslate"><span class="pre">if...</span> <span class="pre">elif...</span> <span class="pre">else</span></code>
- comparisons or <code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except</span></code> statements. If you try to do too much in a
- <code class="docutils literal notranslate"><span class="pre">lambda</span></code> statement, you’ll end up with an overly complicated expression that’s
- hard to read. Quick, what’s the following code doing?</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">functools</span>
- <span class="n">total</span> <span class="o">=</span> <span class="n">functools</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="k">lambda</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">:</span> <span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">a</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">b</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">items</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
- </pre></div>
- </div>
- <p>You can figure it out, but it takes time to disentangle the expression to figure
- out what’s going on. Using a short nested <code class="docutils literal notranslate"><span class="pre">def</span></code> statements makes things a
- little bit better:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">functools</span>
- <span class="k">def</span> <span class="nf">combine</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">):</span>
- <span class="k">return</span> <span class="mi">0</span><span class="p">,</span> <span class="n">a</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">b</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
-
- <span class="n">total</span> <span class="o">=</span> <span class="n">functools</span><span class="o">.</span><span class="n">reduce</span><span class="p">(</span><span class="n">combine</span><span class="p">,</span> <span class="n">items</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
- </pre></div>
- </div>
- <p>But it would be best of all if I had simply used a <code class="docutils literal notranslate"><span class="pre">for</span></code> loop:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">total</span> <span class="o">=</span> <span class="mi">0</span>
- <span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">items</span><span class="p">:</span>
- <span class="n">total</span> <span class="o">+=</span> <span class="n">b</span>
- </pre></div>
- </div>
- <p>Or the <a class="reference internal" href="../library/functions.html#sum" title="sum"><code class="xref py py-func docutils literal notranslate"><span class="pre">sum()</span></code></a> built-in and a generator expression:</p>
- <div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">total</span> <span class="o">=</span> <span class="nb">sum</span><span class="p">(</span><span class="n">b</span> <span class="k">for</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span> <span class="ow">in</span> <span class="n">items</span><span class="p">)</span>
- </pre></div>
- </div>
- <p>Many uses of <a class="reference internal" href="../library/functools.html#functools.reduce" title="functools.reduce"><code class="xref py py-func docutils literal notranslate"><span class="pre">functools.reduce()</span></code></a> are clearer when written as <code class="docutils literal notranslate"><span class="pre">for</span></code> loops.</p>
- <p>Fredrik Lundh once suggested the following set of rules for refactoring uses of
- <code class="docutils literal notranslate"><span class="pre">lambda</span></code>:</p>
- <ol class="arabic simple">
- <li><p>Write a lambda function.</p></li>
- <li><p>Write a comment explaining what the heck that lambda does.</p></li>
- <li><p>Study the comment for a while, and think of a name that captures the essence
- of the comment.</p></li>
- <li><p>Convert the lambda to a def statement, using that name.</p></li>
- <li><p>Remove the comment.</p></li>
- </ol>
- <p>I really like these rules, but you’re free to disagree
- about whether this lambda-free style is better.</p>
- </section>
- <section id="revision-history-and-acknowledgements">
- <h2>Revision History and Acknowledgements<a class="headerlink" href="#revision-history-and-acknowledgements" title="Link to this heading">¶</a></h2>
- <p>The author would like to thank the following people for offering suggestions,
- corrections and assistance with various drafts of this article: Ian Bicking,
- Nick Coghlan, Nick Efford, Raymond Hettinger, Jim Jewett, Mike Krell, Leandro
- Lameiro, Jussi Salmela, Collin Winter, Blake Winton.</p>
- <p>Version 0.1: posted June 30 2006.</p>
- <p>Version 0.11: posted July 1 2006. Typo fixes.</p>
- <p>Version 0.2: posted July 10 2006. Merged genexp and listcomp sections into one.
- Typo fixes.</p>
- <p>Version 0.21: Added more references suggested on the tutor mailing list.</p>
- <p>Version 0.30: Adds a section on the <code class="docutils literal notranslate"><span class="pre">functional</span></code> module written by Collin
- Winter; adds short section on the operator module; a few other edits.</p>
- </section>
- <section id="references">
- <h2>References<a class="headerlink" href="#references" title="Link to this heading">¶</a></h2>
- <section id="general">
- <h3>General<a class="headerlink" href="#general" title="Link to this heading">¶</a></h3>
- <p><strong>Structure and Interpretation of Computer Programs</strong>, by Harold Abelson and
- Gerald Jay Sussman with Julie Sussman. The book can be found at
- <a class="reference external" href="https://mitpress.mit.edu/sicp">https://mitpress.mit.edu/sicp</a>. In this classic textbook of computer science,
- chapters 2 and 3 discuss the use of sequences and streams to organize the data
- flow inside a program. The book uses Scheme for its examples, but many of the
- design approaches described in these chapters are applicable to functional-style
- Python code.</p>
- <p><a class="reference external" href="https://www.defmacro.org/ramblings/fp.html">https://www.defmacro.org/ramblings/fp.html</a>: A general introduction to functional
- programming that uses Java examples and has a lengthy historical introduction.</p>
- <p><a class="reference external" href="https://en.wikipedia.org/wiki/Functional_programming">https://en.wikipedia.org/wiki/Functional_programming</a>: General Wikipedia entry
- describing functional programming.</p>
- <p><a class="reference external" href="https://en.wikipedia.org/wiki/Coroutine">https://en.wikipedia.org/wiki/Coroutine</a>: Entry for coroutines.</p>
- <p><a class="reference external" href="https://en.wikipedia.org/wiki/Partial_application">https://en.wikipedia.org/wiki/Partial_application</a>: Entry for the concept of partial function application.</p>
- <p><a class="reference external" href="https://en.wikipedia.org/wiki/Currying">https://en.wikipedia.org/wiki/Currying</a>: Entry for the concept of currying.</p>
- </section>
- <section id="python-specific">
- <h3>Python-specific<a class="headerlink" href="#python-specific" title="Link to this heading">¶</a></h3>
- <p><a class="reference external" href="https://gnosis.cx/TPiP/">https://gnosis.cx/TPiP/</a>: The first chapter of David Mertz’s book
- <cite>Text Processing in Python</cite> discusses functional programming
- for text processing, in the section titled “Utilizing Higher-Order Functions in
- Text Processing”.</p>
- <p>Mertz also wrote a 3-part series of articles on functional programming
- for IBM’s DeveloperWorks site; see
- <a class="reference external" href="https://developer.ibm.com/articles/l-prog/">part 1</a>,
- <a class="reference external" href="https://developer.ibm.com/tutorials/l-prog2/">part 2</a>, and
- <a class="reference external" href="https://developer.ibm.com/tutorials/l-prog3/">part 3</a>,</p>
- </section>
- <section id="python-documentation">
- <h3>Python documentation<a class="headerlink" href="#python-documentation" title="Link to this heading">¶</a></h3>
- <p>Documentation for the <a class="reference internal" href="../library/itertools.html#module-itertools" title="itertools: Functions creating iterators for efficient looping."><code class="xref py py-mod docutils literal notranslate"><span class="pre">itertools</span></code></a> module.</p>
- <p>Documentation for the <a class="reference internal" href="../library/functools.html#module-functools" title="functools: Higher-order functions and operations on callable objects."><code class="xref py py-mod docutils literal notranslate"><span class="pre">functools</span></code></a> module.</p>
- <p>Documentation for the <a class="reference internal" href="../library/operator.html#module-operator" title="operator: Functions corresponding to the standard operators."><code class="xref py py-mod docutils literal notranslate"><span class="pre">operator</span></code></a> module.</p>
- <p><span class="target" id="index-1"></span><a class="pep reference external" href="https://peps.python.org/pep-0289/"><strong>PEP 289</strong></a>: “Generator Expressions”</p>
- <p><span class="target" id="index-2"></span><a class="pep reference external" href="https://peps.python.org/pep-0342/"><strong>PEP 342</strong></a>: “Coroutines via Enhanced Generators” describes the new generator
- features in Python 2.5.</p>
- </section>
- </section>
- </section>
-
-
- <div class="clearer"></div>
- </div>
- </div>
- </div>
- <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
- <div class="sphinxsidebarwrapper">
- <div>
- <h3><a href="../contents.html">Table of Contents</a></h3>
- <ul>
- <li><a class="reference internal" href="#">Functional Programming HOWTO</a><ul>
- <li><a class="reference internal" href="#introduction">Introduction</a><ul>
- <li><a class="reference internal" href="#formal-provability">Formal provability</a></li>
- <li><a class="reference internal" href="#modularity">Modularity</a></li>
- <li><a class="reference internal" href="#ease-of-debugging-and-testing">Ease of debugging and testing</a></li>
- <li><a class="reference internal" href="#composability">Composability</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#iterators">Iterators</a><ul>
- <li><a class="reference internal" href="#data-types-that-support-iterators">Data Types That Support Iterators</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#generator-expressions-and-list-comprehensions">Generator expressions and list comprehensions</a></li>
- <li><a class="reference internal" href="#generators">Generators</a><ul>
- <li><a class="reference internal" href="#passing-values-into-a-generator">Passing values into a generator</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#built-in-functions">Built-in functions</a></li>
- <li><a class="reference internal" href="#the-itertools-module">The itertools module</a><ul>
- <li><a class="reference internal" href="#creating-new-iterators">Creating new iterators</a></li>
- <li><a class="reference internal" href="#calling-functions-on-elements">Calling functions on elements</a></li>
- <li><a class="reference internal" href="#selecting-elements">Selecting elements</a></li>
- <li><a class="reference internal" href="#combinatoric-functions">Combinatoric functions</a></li>
- <li><a class="reference internal" href="#grouping-elements">Grouping elements</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#the-functools-module">The functools module</a><ul>
- <li><a class="reference internal" href="#the-operator-module">The operator module</a></li>
- </ul>
- </li>
- <li><a class="reference internal" href="#small-functions-and-the-lambda-expression">Small functions and the lambda expression</a></li>
- <li><a class="reference internal" href="#revision-history-and-acknowledgements">Revision History and Acknowledgements</a></li>
- <li><a class="reference internal" href="#references">References</a><ul>
- <li><a class="reference internal" href="#general">General</a></li>
- <li><a class="reference internal" href="#python-specific">Python-specific</a></li>
- <li><a class="reference internal" href="#python-documentation">Python documentation</a></li>
- </ul>
- </li>
- </ul>
- </li>
- </ul>
-
- </div>
- <div>
- <h4>Previous topic</h4>
- <p class="topless"><a href="enum.html"
- title="previous chapter">Enum HOWTO</a></p>
- </div>
- <div>
- <h4>Next topic</h4>
- <p class="topless"><a href="logging.html"
- title="next chapter">Logging HOWTO</a></p>
- </div>
- <div role="note" aria-label="source link">
- <h3>This Page</h3>
- <ul class="this-page-menu">
- <li><a href="../bugs.html">Report a Bug</a></li>
- <li>
- <a href="https://github.com/python/cpython/blob/main/Doc/howto/functional.rst"
- rel="nofollow">Show Source
- </a>
- </li>
- </ul>
- </div>
- </div>
- <div id="sidebarbutton" title="Collapse sidebar">
- <span>«</span>
- </div>
-
- </div>
- <div class="clearer"></div>
- </div>
- <div class="related" role="navigation" aria-label="related navigation">
- <h3>Navigation</h3>
- <ul>
- <li class="right" style="margin-right: 10px">
- <a href="../genindex.html" title="General Index"
- >index</a></li>
- <li class="right" >
- <a href="../py-modindex.html" title="Python Module Index"
- >modules</a> |</li>
- <li class="right" >
- <a href="logging.html" title="Logging HOWTO"
- >next</a> |</li>
- <li class="right" >
- <a href="enum.html" title="Enum HOWTO"
- >previous</a> |</li>
-
- <li><img src="../_static/py.svg" alt="Python logo" style="vertical-align: middle; margin-top: -1px"/></li>
- <li><a href="https://www.python.org/">Python</a> »</li>
- <li class="switchers">
- <div class="language_switcher_placeholder"></div>
- <div class="version_switcher_placeholder"></div>
- </li>
- <li>
-
- </li>
- <li id="cpython-language-and-version">
- <a href="../index.html">3.12.3 Documentation</a> »
- </li>
-
- <li class="nav-item nav-item-1"><a href="index.html" >Python HOWTOs</a> »</li>
- <li class="nav-item nav-item-this"><a href="">Functional Programming HOWTO</a></li>
- <li class="right">
-
-
- <div class="inline-search" role="search">
- <form class="inline-search" action="../search.html" method="get">
- <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" id="search-box" />
- <input type="submit" value="Go" />
- </form>
- </div>
- |
- </li>
- <li class="right">
- <label class="theme-selector-label">
- Theme
- <select class="theme-selector" oninput="activateTheme(this.value)">
- <option value="auto" selected>Auto</option>
- <option value="light">Light</option>
- <option value="dark">Dark</option>
- </select>
- </label> |</li>
-
- </ul>
- </div>
- <div class="footer">
- ©
- <a href="../copyright.html">
-
- Copyright
-
- </a>
- 2001-2024, Python Software Foundation.
- <br />
- This page is licensed under the Python Software Foundation License Version 2.
- <br />
- Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
- <br />
-
- See <a href="/license.html">History and License</a> for more information.<br />
-
-
- <br />
-
- The Python Software Foundation is a non-profit corporation.
- <a href="https://www.python.org/psf/donations/">Please donate.</a>
- <br />
- <br />
- Last updated on Apr 09, 2024 (13:47 UTC).
-
- <a href="/bugs.html">Found a bug</a>?
-
- <br />
-
- Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 7.2.6.
- </div>
-
- </body>
- </html>
|