1350 lines
155 KiB
HTML
1350 lines
155 KiB
HTML
|
||
<!DOCTYPE html>
|
||
|
||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<title>Functional Programming HOWTO — Python 3.7.4 documentation</title>
|
||
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
|
||
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
|
||
|
||
<script type="text/javascript" id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
|
||
<script type="text/javascript" src="../_static/jquery.js"></script>
|
||
<script type="text/javascript" src="../_static/underscore.js"></script>
|
||
<script type="text/javascript" src="../_static/doctools.js"></script>
|
||
<script type="text/javascript" src="../_static/language_data.js"></script>
|
||
|
||
<script type="text/javascript" src="../_static/sidebar.js"></script>
|
||
|
||
<link rel="search" type="application/opensearchdescription+xml"
|
||
title="Search within Python 3.7.4 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="Descriptor HowTo Guide" href="descriptor.html" />
|
||
<link rel="shortcut icon" type="image/png" href="../_static/py.png" />
|
||
<link rel="canonical" href="https://docs.python.org/3/howto/functional.html" />
|
||
|
||
<script type="text/javascript" src="../_static/copybutton.js"></script>
|
||
<script type="text/javascript" src="../_static/switchers.js"></script>
|
||
|
||
|
||
|
||
<style>
|
||
@media only screen {
|
||
table.full-width-table {
|
||
width: 100%;
|
||
}
|
||
}
|
||
</style>
|
||
|
||
|
||
</head><body>
|
||
|
||
<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="descriptor.html" title="Descriptor HowTo Guide"
|
||
accesskey="P">previous</a> |</li>
|
||
<li><img src="../_static/py.png" alt=""
|
||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li>
|
||
<span class="language_switcher_placeholder">en</span>
|
||
<span class="version_switcher_placeholder">3.7.4</span>
|
||
<a href="../index.html">Documentation </a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python HOWTOs</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" style="display: none" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" type="text" name="q" />
|
||
<input type="submit" value="Go" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="document">
|
||
<div class="documentwrapper">
|
||
<div class="bodywrapper">
|
||
<div class="body" role="main">
|
||
|
||
<div class="section" id="functional-programming-howto">
|
||
<h1>Functional Programming HOWTO<a class="headerlink" href="#functional-programming-howto" title="Permalink to this headline">¶</a></h1>
|
||
<dl class="field-list simple">
|
||
<dt class="field-odd">Author</dt>
|
||
<dd class="field-odd"><p>A. M. Kuchling</p>
|
||
</dd>
|
||
<dt class="field-even">Release</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>
|
||
<div class="section" id="introduction">
|
||
<h2>Introduction<a class="headerlink" href="#introduction" title="Permalink to this headline">¶</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. Printing to the screen or writing to a disk file are side
|
||
effects, for example. For example, in Python 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 both return no useful value; they’re only called 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>
|
||
<div class="section" id="formal-provability">
|
||
<h3>Formal provability<a class="headerlink" href="#formal-provability" title="Permalink to this headline">¶</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>
|
||
</div>
|
||
<div class="section" id="modularity">
|
||
<h3>Modularity<a class="headerlink" href="#modularity" title="Permalink to this headline">¶</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>
|
||
</div>
|
||
<div class="section" id="ease-of-debugging-and-testing">
|
||
<h3>Ease of debugging and testing<a class="headerlink" href="#ease-of-debugging-and-testing" title="Permalink to this headline">¶</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>
|
||
</div>
|
||
<div class="section" id="composability">
|
||
<h3>Composability<a class="headerlink" href="#composability" title="Permalink to this headline">¶</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>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="iterators">
|
||
<span id="functional-howto-iterators"></span><h2>Iterators<a class="headerlink" href="#iterators" title="Permalink to this headline">¶</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="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="c1">#doctest: +ELLIPSIS</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="go">>>></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="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="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>
|
||
<div class="section" id="data-types-that-support-iterators">
|
||
<h3>Data Types That Support Iterators<a class="headerlink" href="#data-types-that-support-iterators" title="Permalink to this headline">¶</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="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="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="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">S</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>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="generator-expressions-and-list-comprehensions">
|
||
<h2>Generator expressions and list comprehensions<a class="headerlink" href="#generator-expressions-and-list-comprehensions" title="Permalink to this headline">¶</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="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="o">...</span><span class="p">]</span>
|
||
|
||
<span class="c1"># Generator expression -- returns iterator</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="c1"># List comprehension -- returns list</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="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="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="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="c1">#doctest: +NORMALIZE_WHITESPACE</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>
|
||
</div>
|
||
<div class="section" id="generators">
|
||
<h2>Generators<a class="headerlink" href="#generators" title="Permalink to this headline">¶</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="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="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="c1">#doctest: +ELLIPSIS</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.7/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>
|
||
<div class="section" id="passing-values-into-a-generator">
|
||
<h3>Passing values into a generator<a class="headerlink" href="#passing-values-into-a-generator" title="Permalink to this headline">¶</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://www.python.org/dev/peps/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-python3 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="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="c1">#doctest: +SKIP</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="c1">#doctest: +SKIP</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="c1">#doctest: +SKIP</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="c1">#doctest: +SKIP</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="c1">#doctest: +SKIP</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="c1">#doctest: +SKIP</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="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(type,</span> <span class="pre">value=None,</span> <span class="pre">traceback=None)</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>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="built-in-functions">
|
||
<h2>Built-in functions<a class="headerlink" href="#built-in-functions" title="Permalink to this headline">¶</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="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="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="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="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="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 HOW TO</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="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>
|
||
</div>
|
||
<div class="section" id="the-itertools-module">
|
||
<h2>The itertools module<a class="headerlink" href="#the-itertools-module" title="Permalink to this headline">¶</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>
|
||
<div class="section" id="creating-new-iterators">
|
||
<h3>Creating new iterators<a class="headerlink" href="#creating-new-iterators" title="Permalink to this headline">¶</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>
|
||
</div>
|
||
<div class="section" id="calling-functions-on-elements">
|
||
<h3>Calling functions on elements<a class="headerlink" href="#calling-functions-on-elements" title="Permalink to this headline">¶</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>
|
||
</div>
|
||
<div class="section" id="selecting-elements">
|
||
<h3>Selecting elements<a class="headerlink" href="#selecting-elements" title="Permalink to this headline">¶</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>
|
||
</div>
|
||
<div class="section" id="combinatoric-functions">
|
||
<h3>Combinatoric functions<a class="headerlink" href="#combinatoric-functions" title="Permalink to this headline">¶</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>
|
||
</div>
|
||
<div class="section" id="grouping-elements">
|
||
<h3>Grouping elements<a class="headerlink" href="#grouping-elements" title="Permalink to this headline">¶</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>
|
||
</div>
|
||
</div>
|
||
<div class="section" id="the-functools-module">
|
||
<h2>The functools module<a class="headerlink" href="#the-functools-module" title="Permalink to this headline">¶</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 in Python 2.5 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="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="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="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, <code class="xref py py-func docutils literal notranslate"><span class="pre">accumulate()</span></code> 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>
|
||
<div class="section" id="the-operator-module">
|
||
<h3>The operator module<a class="headerlink" href="#the-operator-module" title="Permalink to this headline">¶</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>
|
||
</div>
|
||
</div>
|
||
<div class="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="Permalink to this headline">¶</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>
|
||
</div>
|
||
<div class="section" id="revision-history-and-acknowledgements">
|
||
<h2>Revision History and Acknowledgements<a class="headerlink" href="#revision-history-and-acknowledgements" title="Permalink to this headline">¶</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>
|
||
</div>
|
||
<div class="section" id="references">
|
||
<h2>References<a class="headerlink" href="#references" title="Permalink to this headline">¶</a></h2>
|
||
<div class="section" id="general">
|
||
<h3>General<a class="headerlink" href="#general" title="Permalink to this headline">¶</a></h3>
|
||
<p><strong>Structure and Interpretation of Computer Programs</strong>, by Harold Abelson and
|
||
Gerald Jay Sussman with Julie Sussman. Full text 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="http://www.defmacro.org/ramblings/fp.html">http://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/Currying">https://en.wikipedia.org/wiki/Currying</a>: Entry for the concept of currying.</p>
|
||
</div>
|
||
<div class="section" id="python-specific">
|
||
<h3>Python-specific<a class="headerlink" href="#python-specific" title="Permalink to this headline">¶</a></h3>
|
||
<p><a class="reference external" href="http://gnosis.cx/TPiP/">http://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://www.ibm.com/developerworks/linux/library/l-prog/index.html">part 1</a>,
|
||
<a class="reference external" href="https://www.ibm.com/developerworks/linux/library/l-prog2/index.html">part 2</a>, and
|
||
<a class="reference external" href="https://www.ibm.com/developerworks/linux/library/l-prog3/index.html">part 3</a>,</p>
|
||
</div>
|
||
<div class="section" id="python-documentation">
|
||
<h3>Python documentation<a class="headerlink" href="#python-documentation" title="Permalink to this headline">¶</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://www.python.org/dev/peps/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://www.python.org/dev/peps/pep-0342"><strong>PEP 342</strong></a>: “Coroutines via Enhanced Generators” describes the new generator
|
||
features in Python 2.5.</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
|
||
<div class="sphinxsidebarwrapper">
|
||
<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>
|
||
|
||
<h4>Previous topic</h4>
|
||
<p class="topless"><a href="descriptor.html"
|
||
title="previous chapter">Descriptor HowTo Guide</a></p>
|
||
<h4>Next topic</h4>
|
||
<p class="topless"><a href="logging.html"
|
||
title="next chapter">Logging HOWTO</a></p>
|
||
<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/3.7/Doc/howto/functional.rst"
|
||
rel="nofollow">Show Source
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
</div>
|
||
</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="descriptor.html" title="Descriptor HowTo Guide"
|
||
>previous</a> |</li>
|
||
<li><img src="../_static/py.png" alt=""
|
||
style="vertical-align: middle; margin-top: -1px"/></li>
|
||
<li><a href="https://www.python.org/">Python</a> »</li>
|
||
<li>
|
||
<span class="language_switcher_placeholder">en</span>
|
||
<span class="version_switcher_placeholder">3.7.4</span>
|
||
<a href="../index.html">Documentation </a> »
|
||
</li>
|
||
|
||
<li class="nav-item nav-item-1"><a href="index.html" >Python HOWTOs</a> »</li>
|
||
<li class="right">
|
||
|
||
|
||
<div class="inline-search" style="display: none" role="search">
|
||
<form class="inline-search" action="../search.html" method="get">
|
||
<input placeholder="Quick search" type="text" name="q" />
|
||
<input type="submit" value="Go" />
|
||
<input type="hidden" name="check_keywords" value="yes" />
|
||
<input type="hidden" name="area" value="default" />
|
||
</form>
|
||
</div>
|
||
<script type="text/javascript">$('.inline-search').show(0);</script>
|
||
|
|
||
</li>
|
||
|
||
</ul>
|
||
</div>
|
||
<div class="footer">
|
||
© <a href="../copyright.html">Copyright</a> 2001-2019, Python Software Foundation.
|
||
<br />
|
||
The Python Software Foundation is a non-profit corporation.
|
||
<a href="https://www.python.org/psf/donations/">Please donate.</a>
|
||
<br />
|
||
Last updated on Jul 13, 2019.
|
||
<a href="../bugs.html">Found a bug</a>?
|
||
<br />
|
||
Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 2.0.1.
|
||
</div>
|
||
|
||
</body>
|
||
</html> |