<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Real Python</title>
  <link href="https://realpython.com/atom.xml" rel="self"/>
  <link href="https://realpython.com/"/>
  <updated>2018-07-25T14:00:00+00:00</updated>
  <id>https://realpython.com/</id>
  <author>
    <name>Real Python</name>
  </author>

  
    <entry>
      <title>Documenting Python Code: A Complete Guide</title>
      <id>https://realpython.com/documenting-python-code/</id>
      <link href="https://realpython.com/documenting-python-code/"/>
      <updated>2018-07-25T14:00:00+00:00</updated>
      <summary>A complete guide to documenting Python code. Whether you&#39;re documenting a small script or a large project, whether you&#39;re a beginner or seasoned Pythonista, this guide will cover everything you need to know.</summary>
      <content type="html">
        &lt;p&gt;Welcome to your complete guide to documenting Python code. Whether you&amp;rsquo;re documenting a small script or a large project, whether you&amp;rsquo;re a beginner or seasoned Pythonista, this guide will cover everything you need to know.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ve broken up this tutorial into four major sections:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#why-documenting-your-code-is-so-important&quot;&gt;Why Documenting Your Code Is So Important&lt;/a&gt;:&lt;/strong&gt; An introduction to documentation and its importance&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#commenting-vs.-documenting-code&quot;&gt;Commenting vs. Documenting Code&lt;/a&gt;:&lt;/strong&gt; An overview of the major differences between commenting and documenting, as well as the appropriate times and ways to use commenting&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#documenting-your-python-code-base&quot;&gt;Documenting Your Python Code Base Using Docstrings&lt;/a&gt;:&lt;/strong&gt; A deep dive into docstrings for classes, class methods, functions, modules, packages, and scripts, as well as what should be found within each one&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#documenting-your-python-projects&quot;&gt;Documenting Your Python Projects&lt;/a&gt;:&lt;/strong&gt; The necessary elements and what they should contain for your Python projects&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Feel free to read through this tutorial from beginning to end or jump to a section you&amp;rsquo;re interested in. It was designed to work both ways.&lt;/p&gt;
&lt;h2 id=&quot;why-documenting-your-code-is-so-important&quot;&gt;Why Documenting Your Code Is So Important&lt;/h2&gt;
&lt;p&gt;Hopefully, if you&amp;rsquo;re reading this tutorial, you already know the importance of documenting your code. But if not, then let me quote something Guido mentioned to me at a recent PyCon:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Code is more often read than written.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;mdash; &lt;em&gt;Guido Van Rossum&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When you write code, you write it for two primary audiences: your users and your developers (including yourself). Both audiences are equally important. If you&amp;rsquo;re like me, you&amp;rsquo;ve probably opened up old codebases and wondered to yourself, &amp;ldquo;What in the world was I thinking?&amp;rdquo; If you&amp;rsquo;re having a problem reading your own code, imagine what your users or other developers are experiencing when they&amp;rsquo;re trying to use or contribute to your code.&lt;/p&gt;
&lt;p&gt;Conversely, I&amp;rsquo;m sure you&amp;rsquo;ve run into a situation where you wanted to do something in Python and found what looks like a great library that can get the job done. However, when you start using the library, you look for examples, write-ups, or even official documentation on how to do something specific and can&amp;rsquo;t immediately find the solution.&lt;/p&gt;
&lt;p&gt;After searching, you come to realize that the documentation is lacking or even worse, missing entirely. This is a frustrating feeling that deters you from using the library, no matter how great or efficient the code is. Daniele Procida summarized this situation best:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;It doesn&amp;rsquo;t matter how good your software is, because &lt;strong&gt;if the documentation is not good enough, people will not use it.&lt;/strong&gt;&amp;ldquo;&lt;/p&gt;
&lt;p&gt;&amp;mdash; &lt;em&gt;&lt;a href=&quot;https://www.divio.com/en/blog/documentation/&quot;&gt;Daniele Procida&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this guide, you&amp;rsquo;ll learn from the ground up how to properly document your Python code from the smallest of scripts to the largest of Python projects to help prevent your users from ever feeling too frustrated to use or contribute to your project.&lt;/p&gt;
&lt;h2 id=&quot;commenting-vs-documenting-code&quot;&gt;Commenting vs. Documenting Code&lt;/h2&gt;
&lt;p&gt;Before we can go into how to document your Python code, we need to distinguish documenting from commenting.&lt;/p&gt;
&lt;p&gt;In general, commenting is describing your code to/for developers. The intended main audience is the maintainers and developers of the Python code. In conjunction with well-written code, comments help to guide the reader to better understand your code and its purpose and design:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Code tells you how; Comments tell you why.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;mdash; &lt;em&gt;&lt;a href=&quot;https://blog.codinghorror.com/code-tells-you-how-comments-tell-you-why/&quot;&gt;Jeff Atwood&lt;/a&gt; (aka Coding Horror)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Documenting code is describing its use and functionality to your users. While it may be helpful in the development process, the main intended audience is the users. The following section describes how and when to comment your code.&lt;/p&gt;
&lt;h3 id=&quot;basics-of-commenting-code&quot;&gt;Basics of Commenting Code&lt;/h3&gt;
&lt;p&gt;Comments are created in Python using the pound sign (&lt;code&gt;#&lt;/code&gt;) and should be brief statements no longer than a few sentences. Here&amp;rsquo;s a simple example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hello_world&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# A simple comment preceding a simple print statement&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello World&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;According to &lt;a href=&quot;http://pep8.org/#maximum-line-length&quot;&gt;PEP 8&lt;/a&gt;, comments should have a maximum length of 72 characters. This is true even if your project changes the max line length to be greater than the recommended 80 characters. If a comment is going to be greater than the comment char limit, using multiple lines for the comment is appropriate:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hello_long_world&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# A very long statement that just goes on and on and on and on and&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# never ends until after it&amp;#39;s reached the 80 char limit&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hellooooooooooooooooooooooooooooooooooooooooooooooooooooooo World&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Commenting your code serves &lt;a href=&quot;https://en.wikipedia.org/wiki/Comment_(computer_programming)#Uses&quot;&gt;multiple purposes, including&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Planning and Reviewing:&lt;/strong&gt; When you are developing new portions of your code, it may be appropriate to first use comments as a way of planning or outlining that section of code. Remember to remove these comments once the actual coding has been implemented and reviewed/tested:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# First step&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Second step&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Third step&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Code Description:&lt;/strong&gt; Comments can be used to explain the intent of specific sections of code:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Attempt a connection based on previous settings. If unsuccessful,&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# prompt user for new settings.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Algorithmic Description:&lt;/strong&gt; When algorithms are used, especially complicated ones, it can be useful to explain how the algorithm works or how it&amp;rsquo;s implemented within your code. It may also be appropriate to describe why a specific algorithm was selected over another.&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Using quick sort for performance gains&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tagging:&lt;/strong&gt; The use of tagging can be used to label specific sections of code where known issues or areas of improvement are located. Some examples are: &lt;code&gt;BUG&lt;/code&gt;, &lt;code&gt;FIXME&lt;/code&gt;, and &lt;code&gt;TODO&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# TODO: Add condition for when val is None&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Comments to your code should be kept brief and focused. Avoid using long comments when possible. Additionally, you should use the following four essential rules as &lt;a href=&quot;https://blog.codinghorror.com/when-good-comments-go-bad/&quot;&gt;suggested by Jeff Atwood&lt;/a&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Keep comments as close to the code being described as possible. Comments that aren&amp;rsquo;t near their describing code are frustrating to the reader and easily missed when updates are made.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don&amp;rsquo;t use complex formatting (such as tables or ASCII figures). Complex formatting leads to distracting content and can be difficult to maintain over time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Don&amp;rsquo;t include redundant information. Assume the reader of the code has a basic understanding of programming principles and language syntax.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Design your code to comment itself. The easiest way to understand code is by reading it. When you design your code using clear, easy-to-understand concepts, the reader will be able to quickly conceptualize your intent.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Remember that comments are designed for the reader, including yourself, to help guide them in understanding the purpose and design of the software.&lt;/p&gt;
&lt;h3 id=&quot;commenting-code-via-type-hinting-python-35&quot;&gt;Commenting Code via Type Hinting (Python 3.5+)&lt;/h3&gt;
&lt;p&gt;Type hinting was added to Python 3.5 and is an additional form to help the readers of your code. In fact, it takes Jeff&amp;rsquo;s fourth suggestion from above to the next level. It allows the developer to design and explain portions of their code without commenting. Here&amp;rsquo;s a quick example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hello_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{name}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From examining the type hinting, you can immediately tell that the function expects the input &lt;code&gt;name&lt;/code&gt; to be of a type &lt;code&gt;str&lt;/code&gt;, or string. You can also tell that the expected output of the function will be of a type &lt;code&gt;str&lt;/code&gt;, or string, as well. While type hinting helps reduce comments, take into consideration that doing so may also make extra work when you are creating or updating your project documentation.&lt;/p&gt;
&lt;p&gt;You can learn more about type hinting and type checking from &lt;a href=&quot;https://www.youtube.com/watch?v=2xWhaALHTvU&quot;&gt;this video created by Dan Bader&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;documenting-your-python-code-base-using-docstrings&quot;&gt;Documenting Your Python Code Base Using Docstrings&lt;/h2&gt;
&lt;p&gt;Now that we&amp;rsquo;ve learned about commenting, let&amp;rsquo;s take a deep dive into documenting a Python code base. In this section, you&amp;rsquo;ll learn about docstrings and how to use them for documentation. This section is further divided into the following sub-sections:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#docstrings-background&quot;&gt;Docstrings Background&lt;/a&gt;:&lt;/strong&gt; A background on how docstrings work internally within Python&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#docstring-types&quot;&gt;Docstring Types&lt;/a&gt;:&lt;/strong&gt; The various docstring &amp;ldquo;types&amp;rdquo; (function, class, class method, module, package, and script)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;#docstring-formats&quot;&gt;Docstring Formats&lt;/a&gt;:&lt;/strong&gt; The different docstring &amp;ldquo;formats&amp;rdquo; (Google, NumPy/SciPy, reStructured Text, and Epytext)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;docstrings-background&quot;&gt;Docstrings Background&lt;/h3&gt;
&lt;p&gt;Documenting your Python code is all centered on docstrings. These are built-in strings that, when configured correctly, can help your users and yourself with your project&amp;rsquo;s documentation. Along with docstrings, Python also has the built-in function &lt;code&gt;help()&lt;/code&gt; that prints out the objects docstring to the console. Here&amp;rsquo;s a quick example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Help on class str in module builtins:&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;class str(object)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; |  str(object=&amp;#39;&amp;#39;) -&amp;gt; str&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; |  str(bytes_or_buffer[, encoding[, errors]]) -&amp;gt; str&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; |&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; |  Create a new string object from the given object. If encoding or&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; |  errors are specified, then the object must expose a data buffer&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; |  that will be decoded using the given encoding and error handler.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; |  Otherwise, returns the result of object.__str__() (if defined)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; |  or repr(object).&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; |  encoding defaults to sys.getdefaultencoding().&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; |  errors defaults to &amp;#39;strict&amp;#39;.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; # Truncated for readability&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;How is this output generated?  Since everything in Python is an object, you can examine the directory of the object using the &lt;code&gt;dir()&lt;/code&gt; command. Let&amp;rsquo;s do that and see what find:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;__add__&amp;#39;, ..., &amp;#39;__doc__&amp;#39;, ..., &amp;#39;zfill&amp;#39;] # Truncated for readability&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Within that directory output, there&amp;rsquo;s an interesting property, &lt;code&gt;__doc__&lt;/code&gt;. If you examine that property, you&amp;rsquo;ll discover this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__doc__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;str(object=&amp;#39;&amp;#39;) -&amp;gt; str&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;str(bytes_or_buffer[, encoding[, errors]]) -&amp;gt; str&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;Create a new string object from the given object. If encoding or&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;errors are specified, then the object must expose a data buffer&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;that will be decoded using the given encoding and error handler.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Otherwise, returns the result of object.__str__() (if defined)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;or repr(object).&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;encoding defaults to sys.getdefaultencoding().&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;errors defaults to &amp;#39;strict&amp;#39;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Voilà! You&amp;rsquo;ve found where docstrings are stored within the object. This means that you can directly manipulate that property. However, there are restrictions for builtins:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__doc__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;I&amp;#39;m a little string doc! Short and stout; here is my input and print me for my out&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;can&amp;#39;t set attributes of built-in/extension type &amp;#39;str&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Any other custom object can be manipulated:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;say_hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{name}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, is it me you&amp;#39;re looking for?&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;say_hello&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__doc__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;A simple function that says hello... Richie style&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;say_hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Help on function say_hello in module __main__:&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;say_hello(name)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    A simple function that says hello... Richie style&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Python has one more feature that simplifies docstring creation. Instead of directly manipulating the &lt;code&gt;__doc__&lt;/code&gt; property, the strategic placement of the string literal directly below the object will automatically set the &lt;code&gt;__doc__&lt;/code&gt; value. Here&amp;rsquo;s what happens with the same example as above:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;say_hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;A simple function that says hello... Richie style&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{name}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, is it me you&amp;#39;re looking for?&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;say_hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Help on function say_hello in module __main__:&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;say_hello(name)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    A simple function that says hello... Richie style&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There you go! Now you understand the background of docstrings. Now it&amp;rsquo;s time to learn about the different types of docstrings and what information they should contain.&lt;/p&gt;
&lt;h3 id=&quot;docstring-types&quot;&gt;Docstring Types&lt;/h3&gt;
&lt;p&gt;Docstring conventions are described within &lt;a href=&quot;https://www.python.org/dev/peps/pep-0257/&quot;&gt;PEP 257&lt;/a&gt;. Their purpose is to provide your users with a brief overview of the object. They should be kept concise enough to be easy to maintain but still be elaborate enough for new users to understand their purpose and how to use the documented object.&lt;/p&gt;
&lt;p&gt;In all cases, the docstrings should use the triple-double quote (&lt;code&gt;&quot;&quot;&quot;&lt;/code&gt;) string format. This should be done whether the docstring is multi-lined or not. At a bare minimum, a docstring should be a quick summary of whatever is it you&amp;rsquo;re describing and should be contained within a single line:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;This is a quick summary line used as a description of the object.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Multi-lined docstrings are used to further elaborate on the object beyond the summary. All multi-lined docstrings have the following parts:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A one-line summary line&lt;/li&gt;
&lt;li&gt;A blank line proceeding the summary&lt;/li&gt;
&lt;li&gt;Any further elaboration for the docstring&lt;/li&gt;
&lt;li&gt;Another blank line&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;This is the summary line&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;This is the further elaboration of the docstring. Within this section,&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;you can elaborate further on details as appropriate for the situation.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;Notice that the summary and the elaboration is separated by a blank new&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;line.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Notice the blank line above. Code should continue on this line.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;All docstrings should have the same max character length as comments (72 characters). Docstrings can be further broken up into three major categories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Class Docstrings:&lt;/strong&gt; Class and class methods&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Package and Module Docstrings:&lt;/strong&gt; Package, modules, and functions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Script Docstrings:&lt;/strong&gt; Script and functions&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;class-docstrings&quot;&gt;Class Docstrings&lt;/h4&gt;
&lt;p&gt;Class Docstrings are created for the class itself, as well as any class methods. The docstrings are placed immediately following the class or class method indented by one level:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SimpleClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Class docstrings go here.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;say_hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Class method docstrings go here.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hello &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{name}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Class docstrings should contain the following information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A brief summary of its purpose and behavior&lt;/li&gt;
&lt;li&gt;Any public methods, along with a brief description&lt;/li&gt;
&lt;li&gt;Any class properties (attributes)&lt;/li&gt;
&lt;li&gt;Anything related to the interface for subclassers, if the class is intended to be subclassed &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The class constructor parameters should be documented within the &lt;code&gt;__init__&lt;/code&gt; class method docstring. Individual methods should be documented using their individual docstrings. Class method docstrings should contain the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A brief description of what the method is and what it&amp;rsquo;s used for&lt;/li&gt;
&lt;li&gt;Any arguments (both required and optional) that are passed including keyword arguments&lt;/li&gt;
&lt;li&gt;Label any arguments that are considered optional or have a default value&lt;/li&gt;
&lt;li&gt;Any side effects that occur when executing the method&lt;/li&gt;
&lt;li&gt;Any exceptions that are raised&lt;/li&gt;
&lt;li&gt;Any restrictions on when the method can be called&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s take a simple example of a data class that represents an Animal. This class will contain a few class properties, instance properties, a &lt;code&gt;__init__&lt;/code&gt;, and a single instance method:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Animal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    A class used to represent an Animal&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    ...&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Attributes&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    ----------&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    says_str : str&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        a formatted string to print out what the animal says&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    name : str&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        the name of the animal&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    sound : str&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        the sound that the animal makes&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    num_legs : int&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        the number of legs the animal has (default 4)&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Methods&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    -------&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    says(sound=None)&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        Prints the animals name and what sound it makes&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;says_str&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;A &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{name}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; says &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{sound}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sound&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_legs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        Parameters&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        ----------&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        name : str&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;            The name of the animal&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        sound : str&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;            The sound the animal makes&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        num_legs : int, optional&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;            The number of legs the animal (default is 4)&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sound&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sound&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_legs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_legs&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;says&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sound&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Prints what the animals name is and what sound it makes.&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;        If the argument `sound` isn&amp;#39;t passed in, the default Animal&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        sound is used.&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;        Parameters&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        ----------&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        sound : str, optional&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;            The sound the animal makes (default is None)&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;        Raises&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        ------&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        NotImplementedError&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;            If no sound is set for the animal or passed in as a&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;            parameter.&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sound&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sound&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;NotImplementedError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Silent Animals are not supported!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;out_sound&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sound&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sound&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sound&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;says_str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sound&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;out_sound&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;package-and-module-docstrings&quot;&gt;Package and Module Docstrings&lt;/h4&gt;
&lt;p&gt;Package docstrings should be placed at the top of the package&amp;rsquo;s &lt;code&gt;__init__.py&lt;/code&gt; file. This docstring should list the modules and sub-packages that are exported by the package.&lt;/p&gt;
&lt;p&gt;Module docstrings are similar to class docstrings. Instead of classes and class methods being documented, it&amp;rsquo;s now the module and any functions found within. Module docstrings are placed at the top of the file even before any imports. Module docstrings should include the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A brief description of the module and its purpose&lt;/li&gt;
&lt;li&gt;A list of any classes, exception, functions, and any other objects exported by the module&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The docstring for a module function should include the same items as a class method:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A brief description of what the function is and what it&amp;rsquo;s used for&lt;/li&gt;
&lt;li&gt;Any arguments (both required and optional) that are passed including keyword arguments&lt;/li&gt;
&lt;li&gt;Label any arguments that are considered optional&lt;/li&gt;
&lt;li&gt;Any side effects that occur when executing the function&lt;/li&gt;
&lt;li&gt;Any exceptions that are raised&lt;/li&gt;
&lt;li&gt;Any restrictions on when the function can be called&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;script-docstrings&quot;&gt;Script Docstrings&lt;/h4&gt;
&lt;p&gt;Scripts are considered to be single file executables run from the console. Docstrings for scripts are placed at the top of the file and should be documented well enough for users to be able to have a sufficient understanding of how to use the script. It should be usable for its &amp;ldquo;usage&amp;rdquo; message, when the user incorrectly passes in a parameter or uses the &lt;code&gt;-h&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;If you use &lt;code&gt;argparse&lt;/code&gt;, then you can omit parameter-specific documentation, assuming it&amp;rsquo;s correctly been documented within the &lt;code&gt;help&lt;/code&gt; parameter of the &lt;code&gt;argparser.parser.add_argument&lt;/code&gt; function. It is recommended to use the &lt;code&gt;__doc__&lt;/code&gt; for the &lt;code&gt;description&lt;/code&gt; parameter within &lt;code&gt;argparse.ArgumentReader&lt;/code&gt;&amp;rsquo;s constructor. Check out our tutorial on &lt;a href=&quot;https://realpython.com/comparing-python-command-line-parsing-libraries-argparse-docopt-click/&quot;&gt;Command-Line Parsing Libraries&lt;/a&gt; for more details on how to use &lt;code&gt;argparse&lt;/code&gt; and other common command line parsers.&lt;/p&gt;
&lt;p&gt;Finally, any custom or third-party imports should be listed within the docstrings to allow users to know which packages may be required for running the script. Here&amp;rsquo;s an example of a script that is used to simply print out the column headers of a spreadsheet:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Spreadsheet Column Printer&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;This script allows the user to print to the console all columns in the&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;spreadsheet. It is assumed that the first row of the spreadsheet is the&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;location of the columns.&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;This tool accepts comma separated value files (.csv) as well as excel&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;(.xls, .xlsx) files.&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;This script requires that `pandas` be installed within the Python&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;environment you are running this script in.&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;This file can also be imported as a module and contains the following&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;functions:&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    * get_spreadsheet_cols - returns the column headers of the file&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    * main - the main function of the script&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;argparse&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pd&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_spreadsheet_cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_loc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print_cols&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Gets and prints the spreadsheet&amp;#39;s header columns&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Parameters&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    ----------&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    file_loc : str&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        The file location of the spreadsheet&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    print_cols : bool, optional&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        A flag used to print the columns to the console (default is&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        False)&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Returns&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    -------&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    list&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        a list of strings used that are the header columns&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;file_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_excel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_loc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;col_headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file_data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print_cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;col_headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;col_headers&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argparse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__doc__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s1&quot;&gt;&amp;#39;input_file&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;The spreadsheet file to pring the columns of&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;get_spreadsheet_cols&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print_cols&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;__main__&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;docstring-formats&quot;&gt;Docstring Formats&lt;/h3&gt;
&lt;p&gt;You may have noticed that, throughout the examples given in this tutorial, there has been specific formatting with common elements: &lt;code&gt;Arguments&lt;/code&gt;, &lt;code&gt;Returns&lt;/code&gt;, and &lt;code&gt;Attributes&lt;/code&gt;. There are specific docstrings formats that can be used to help docstring parsers and users have a familiar and known format. The formatting used within the examples in this tutorial are NumPy/SciPy-style docstrings. Some of the most common formats are the following:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Formatting Type&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;Supported by Sphynx&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;Formal Specification&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings&quot;&gt;Google docstrings&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Google&amp;rsquo;s recommended form of documentation&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Yes&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;http://docutils.sourceforge.net/rst.html&quot;&gt;reStructured Text&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Official Python documentation standard; Not beginner friendly but feature rich&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Yes&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://numpydoc.readthedocs.io/en/latest/format.html&quot;&gt;NumPy/SciPy docstrings&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;NumPy&amp;rsquo;s combination of reStructured and Google Docstrings&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Yes&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;http://epydoc.sourceforge.net/epytext.html&quot;&gt;Epytext&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;A Python adaptation of Epydoc; Great for Java developers&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Not officially&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;The selection of the docstring format is up to you, but you should stick with the same format throughout your document/project. The following are examples of each type to give you an idea of how each documentation format looks.&lt;/p&gt;
&lt;h4 id=&quot;google-docstrings-example&quot;&gt;Google Docstrings Example&lt;/h4&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Gets and prints the spreadsheet&amp;#39;s header columns&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;Parameters:&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    file_loc (str): The file location of the spreadsheet&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    print_cols (bool): A flag used to print the columns to the console&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        (default is False)&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;Returns:&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    list: a list of strings representing the header columns&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;restructured-text-example&quot;&gt;reStructured Text Example&lt;/h4&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Gets and prints the spreadsheet&amp;#39;s header columns&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;:param file_loc: The file location of the spreadsheet&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;:type file_loc: str&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;:param print_cols: A flag used to print the columns to the console&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    (default is False)&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;:type print_cols: bool&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;:returns: a list of strings representing the header columns&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;:rtype: list&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;numpyscipy-docstrings-example&quot;&gt;NumPy/SciPy Docstrings Example&lt;/h4&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Gets and prints the spreadsheet&amp;#39;s header columns&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;Parameters&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;----------&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;file_loc : str&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    The file location of the spreadsheet&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;print_cols : bool, optional&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    A flag used to print the columns to the console (default is False)&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;Returns&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;-------&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;list&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    a list of strings representing the header columns&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;epytext-example&quot;&gt;Epytext Example&lt;/h4&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Gets and prints the spreadsheet&amp;#39;s header columns&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;@type file_loc: str&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;@param file_loc: The file location of the spreadsheet&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;@type print_cols: bool&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;@param print_cols: A flag used to print the columns to the console&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    (default is False)&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;@rtype: list&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;@returns: a list of strings representing the header columns&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;documenting-your-python-projects&quot;&gt;Documenting Your Python Projects&lt;/h2&gt;
&lt;p&gt;Python projects come in all sorts of shapes, sizes, and purposes. The way you document your project should suit your specific situation. Keep in mind who the users of your project are going to be and adapt to their needs. Depending on the project type, certain aspects of documentation are recommended. The general layout of the project and its documentation should be as follows:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;project_root/
│
├── project/  # Project source code
├── docs/
├── README
├── HOW_TO_CONTRIBUTE
├── CODE_OF_CONDUCT
├── examples.py
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Projects can be generally subdivided into three major types: Private, Shared, and Public/Open Source.&lt;/p&gt;
&lt;h3 id=&quot;private-projects&quot;&gt;Private Projects&lt;/h3&gt;
&lt;p&gt;Private projects are projects intended for personal use only and generally aren&amp;rsquo;t shared with other users or developers. Documentation can be pretty light on these types of projects. There are some recommended parts to add as needed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Readme:&lt;/strong&gt; A brief summary of the project and its purpose. Include any special requirements for installation or operating the project.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;examples.py&lt;/code&gt;:&lt;/strong&gt; A Python script file that gives simple examples of how to use the project.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Remember, even though private projects are intended for you personally, you are also considered a user. Think about anything that may be confusing to you down the road and make sure to capture those in either comments, docstrings, or the readme.&lt;/p&gt;
&lt;h3 id=&quot;shared-projects&quot;&gt;Shared Projects&lt;/h3&gt;
&lt;p&gt;Shared projects are projects in which you collaborate with a few other people in the development and/or use of the project. The &amp;ldquo;customer&amp;rdquo; or user of the project continues to be yourself and those limited few that use the project as well.&lt;/p&gt;
&lt;p&gt;Documentation should be a little more rigorous than it needs to be for a private project, mainly to help onboard new members to the project or alert contributors/users of new changes to the project. Some of the recommended parts to add to the project are the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Readme:&lt;/strong&gt; A brief summary of the project and its purpose. Include any special requirements for installing or operating the project. Additionally, add any major changes since the previous version.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;examples.py&lt;/code&gt;:&lt;/strong&gt; A Python script file that gives simple examples of how to use the projects.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How to Contribute:&lt;/strong&gt; This should include how new contributors to the project can start contributing.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;public-and-open-source-projects&quot;&gt;Public and Open Source Projects&lt;/h3&gt;
&lt;p&gt;Public and Open Source projects are projects that are intended to be shared with a large group of users and can involve large development teams. These projects should place as high of a priority on project documentation as the actual development of the project itself. Some of the recommended parts to add to the project are the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Readme:&lt;/strong&gt; A brief summary of the project and its purpose. Include any special requirements for installing or operating the projects. Additionally, add any major changes since the previous version. Finally, add links to further documentation, bug reporting, and any other important information for the project. Dan Bader has put together &lt;a href=&quot;https://dbader.org/blog/write-a-great-readme-for-your-github-project&quot;&gt;a great tutorial&lt;/a&gt; on what all should be included in your readme.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;How to Contribute:&lt;/strong&gt; This should include how new contributors to the project can help. This includes developing new features, fixing known issues, adding documentation, adding new tests, or reporting issues.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Code of Conduct:&lt;/strong&gt; Defines how other contributors should treat each other when developing or using your software. This also states what will happen if this code is broken. If you&amp;rsquo;re using Github, a Code of Conduct &lt;a href=&quot;https://help.github.com/articles/adding-a-code-of-conduct-to-your-project/&quot;&gt;template&lt;/a&gt; can be generated with recommended wording. For Open Source projects especially, consider adding this.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;License:&lt;/strong&gt; A plaintext file that describes the license your project is using. For Open Source projects especially, consider adding this.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;docs:&lt;/strong&gt; A folder that contains further documentation. The next section describes more fully what should be included and how to organize the contents of this folder.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;the-four-main-sections-of-the-docs-folder&quot;&gt;The Four Main Sections of the &lt;code&gt;docs&lt;/code&gt; Folder&lt;/h4&gt;
&lt;p&gt;Daniele Procida gave a wonderful &lt;a href=&quot;https://help.github.com/articles/adding-a-code-of-conduct-to-your-project/&quot;&gt;PyCon 2017 talk&lt;/a&gt; and subsequent &lt;a href=&quot;https://www.divio.com/en/blog/documentation/&quot;&gt;blog post&lt;/a&gt; about documenting Python projects. He mentions that all projects should have the following four major sections to help you focus your work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tutorials&lt;/strong&gt;: Lessons that take the reader by the hand through a series of steps to complete a projects (or meaningful exercise). Geared towards the users learning.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How-To Guides&lt;/strong&gt;: Guides that take the reader through the steps required to solve a common problem (problem-oriented recipes).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;References&lt;/strong&gt;: Explanations that clarify and illuminate a particular topic. Geared towards understanding.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Explanations&lt;/strong&gt;: Technical descriptions of the machinery and how to operate it (key classes, functions, APIs, and so forth). Think Encyclopedia article.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The following table shows how all of these sections relates to each other as well as their overall purpose:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;right&quot;&gt;&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;Most Useful When We&amp;rsquo;re Studying&lt;/th&gt;
&lt;th align=&quot;center&quot;&gt;Most Useful When We&amp;rsquo;re Coding&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;strong&gt;Practical Step&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;em&gt;Tutorials&lt;/em&gt;&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;em&gt;How-To Guides&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;right&quot;&gt;&lt;strong&gt;Theoretical Knowledge&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;em&gt;Explanation&lt;/em&gt;&lt;/td&gt;
&lt;td align=&quot;center&quot;&gt;&lt;em&gt;Reference&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;In the end, you want to make sure that your users have access to the answers to any questions they may have. By organizing your project in this manner, you&amp;rsquo;ll be able to answer those questions easily and in a format they&amp;rsquo;ll be able to navigate quickly.&lt;/p&gt;
&lt;h3 id=&quot;documentation-tools-and-resources&quot;&gt;Documentation Tools and Resources&lt;/h3&gt;
&lt;p&gt;Documenting your code, especially large projects, can be daunting. Thankfully there are some tools out and references to get you started:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;http://www.sphinx-doc.org/en/stable/&quot;&gt;Sphinx&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;A collection of tools to auto-generate documentation in multiple formats&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;http://epydoc.sourceforge.net/&quot;&gt;Epydoc&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;A tool for generating API documentation for Python modules based on their docstrings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://readthedocs.org/&quot;&gt;Read The Docs&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Automatic building, versioning, and hosting of your docs for you&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html#pythonblocks&quot;&gt;Doxygen&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;A tool for generating documentation that supports Python as well as multiple other languages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://www.mkdocs.org/&quot;&gt;MkDocs&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;A static site generator to help build project documentation using the Markdown language&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://pycco-docs.github.io/pycco/&quot;&gt;pycco&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;A &amp;ldquo;quick and dirty&amp;rdquo; documentation generator that displays code and documentation side by side. Check out &lt;a href=&quot;https://realpython.com/generating-code-documentation-with-pycco/&quot;&gt;our tutorial on how to use it for more info&lt;/a&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Along with these tools, there are some additional tutorials, videos, and articles that can be useful when you are documenting your project:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=0ROZRNZkPS8&quot;&gt;Carol Willing - Practical Sphinx - PyCon 2018&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=bQSR1UpUdFQ&quot;&gt;Daniele Procida - Documentation-driven development - Lessons from the Django Project - PyCon 2016&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=hM4I58TA72g&quot;&gt;Eric Holscher - Documenting your project with Sphinx &amp;amp; Read the Docs - PyCon 2016&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/SUt3wT43AeM?t=6299&quot;&gt;Titus Brown, Luiz Irber - Creating, building, testing, and documenting a Python project: a hands-on HOWTO - PyCon 2016&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://docutils.sourceforge.net/rst.html&quot;&gt;Restructured Text Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html&quot;&gt;Sphinx&amp;rsquo;s reStructured Text Primer&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sometimes, the best way to learn is to mimic others. Here are some great examples of projects that use documentation well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Django:&lt;/strong&gt; &lt;a href=&quot;https://docs.djangoproject.com/en/2.0/&quot;&gt;Docs&lt;/a&gt; (&lt;a href=&quot;https://github.com/django/django/tree/master/docs&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Requests:&lt;/strong&gt; &lt;a href=&quot;http://docs.Python-requests.org/en/master/&quot;&gt;Docs&lt;/a&gt; (&lt;a href=&quot;https://github.com/requests/requests/tree/master/docs&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Click:&lt;/strong&gt; &lt;a href=&quot;http://click.pocoo.org/dev/&quot;&gt;Docs&lt;/a&gt; (&lt;a href=&quot;https://github.com/pallets/click/tree/master/docs&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pandas:&lt;/strong&gt; &lt;a href=&quot;http://pandas.pydata.org/pandas-docs/stable/&quot;&gt;Docs&lt;/a&gt; (&lt;a href=&quot;https://github.com/pandas-dev/pandas/tree/master/doc&quot;&gt;Source&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;where-do-i-start&quot;&gt;Where Do I Start?&lt;/h2&gt;
&lt;p&gt;The documentation of projects have a simple progression:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;No Documentation&lt;/li&gt;
&lt;li&gt;Some Documentation&lt;/li&gt;
&lt;li&gt;Complete Documentation&lt;/li&gt;
&lt;li&gt;Good Documentation&lt;/li&gt;
&lt;li&gt;Great Documentation&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you&amp;rsquo;re at a loss about where to go next with your documentation, look at where your project is now in relation to the progression above. Do you have any documentation? If not, then start there. If you have some documentation but are missing some of the key project files, get started by adding those.&lt;/p&gt;
&lt;p&gt;In the end, don&amp;rsquo;t get discouraged or overwhelmed by the amount of work required for documenting code. Once you get started documenting your code, it becomes easier to keep going. Feel free to comment if you have questions or reach out to the Real Python Team on social media, and we&amp;rsquo;ll help.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Fast, Flexible, Easy and Intuitive: How to Speed Up Your Pandas Projects</title>
      <id>https://realpython.com/fast-flexible-pandas/</id>
      <link href="https://realpython.com/fast-flexible-pandas/"/>
      <updated>2018-07-23T14:00:00+00:00</updated>
      <summary>What is it about Pandas that has data scientists, analysts, and engineers raving? This is a guide to using Pandas Pythonically to get the most out of its powerful and easy-to-use built-in features. Additionally, you will learn a couple of practical time-saving tips.</summary>
      <content type="html">
        &lt;p&gt;If you work with big data sets, you probably remember the &amp;ldquo;aha&amp;rdquo; moment along your Python journey when you discovered the &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/&quot;&gt;Pandas&lt;/a&gt; library. Pandas is a game-changer for data science and analytics, particularly if you came to Python because you were searching for something more powerful than Excel and VBA.&lt;/p&gt;
&lt;p&gt;So what is it about Pandas that has data scientists, analysts, and engineers like me raving? Well, the Pandas documentation says that it uses:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;&lt;strong&gt;fast&lt;/strong&gt;, &lt;strong&gt;flexible&lt;/strong&gt;, and expressive data structures designed to make working with &amp;ldquo;relational&amp;rdquo; or &amp;ldquo;labeled&amp;rdquo; data both &lt;strong&gt;easy&lt;/strong&gt; and &lt;strong&gt;intuitive&lt;/strong&gt;.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fast, flexible, easy, and intuitive? That sounds great! If your job involves building complicated data models, you don’t want to spend half of your development hours waiting for modules to churn through big data sets.  You want to dedicate your time and brainpower to interpreting your data, rather than painstakingly fumbling around with less powerful tools.&lt;/p&gt;
&lt;h2 id=&quot;but-i-heard-that-pandas-is-slow&quot;&gt;But I Heard That Pandas Is Slow&amp;hellip;&lt;/h2&gt;
&lt;p&gt;When I first started using Pandas, I was advised that, while it was a great tool for dissecting data, Pandas was too slow to use as a statistical modeling tool. Starting out, this proved true. I spent more than a few minutes twiddling my thumbs, waiting for Pandas to churn through data.&lt;/p&gt;
&lt;p&gt;But then I learned that Pandas is built on top of the NumPy array structure, and so many of its operations are carried out in C, either via NumPy or through Pandas&amp;rsquo; own &lt;a href=&quot;https://github.com/pandas-dev/pandas/tree/master/pandas/_libs&quot;&gt;library&lt;/a&gt; of Python extension modules that are written in Cython and compiled to C.  So, shouldn’t Pandas be fast too?&lt;/p&gt;
&lt;p&gt;It absolutely should be, if you use it the way it was intended!&lt;/p&gt;
&lt;p&gt;The paradox is that what may otherwise &amp;ldquo;look like&amp;rdquo; &lt;a href=&quot;https://stackoverflow.com/q/25011078/7954504&quot;&gt;Pythonic&lt;/a&gt; code can be suboptimal in Pandas as far as efficiency is concerned.  Like NumPy, &lt;a href=&quot;https://realpython.com/numpy-array-programming/#what-is-vectorization&quot;&gt;Pandas is designed for vectorized operations&lt;/a&gt; that operate on entire columns or datasets in one sweep.  Thinking about each &amp;ldquo;cell&amp;rdquo; or row individually should generally be a last resort, not a first.&lt;/p&gt;
&lt;h2 id=&quot;this-tutorial&quot;&gt;This Tutorial&lt;/h2&gt;
&lt;p&gt;To be clear, this is not a guide about how to over-optimize your Pandas code. Pandas is already built to run quickly if used correctly. Also, there’s a big difference between optimization and writing clean code.&lt;/p&gt;
&lt;p&gt;This is a guide to using Pandas Pythonically to get the most out of its powerful and easy-to-use built-in features. Additionally, you will learn a couple of practical time-saving tips, so you won’t be twiddling those thumbs every time you work with your data.&lt;/p&gt;
&lt;p&gt;In this tutorial, you&amp;rsquo;ll cover the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Advantages of using &lt;code&gt;datetime&lt;/code&gt; data with time series&lt;/li&gt;
&lt;li&gt;The most efficient route to doing batch calculations&lt;/li&gt;
&lt;li&gt;Saving time by storing data with HDFStore&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To demonstrate these topics, I&amp;rsquo;ll take an example from my day job that looks at a time series of electricity consumption.  After loading the data, you&amp;rsquo;ll successively progress through more efficient ways to get to the end result.  One adage that holds true for most of Pandas is that there is more than one way to get from A to B.  This doesn&amp;rsquo;t mean, however, that all of the available options will scale equally well to larger, more demanding datasets.&lt;/p&gt;
&lt;p&gt;Assuming that you already know how to do some basic &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/indexing.html&quot;&gt;data selection in Pandas&lt;/a&gt;, let&amp;rsquo;s get started.&lt;/p&gt;
&lt;h2 id=&quot;the-task-at-hand&quot;&gt;The Task at Hand&lt;/h2&gt;
&lt;p&gt;The goal of this example will be to apply time-of-use energy tariffs to find the total cost of energy consumption for one year. That is, at different hours of the day, the price for electricity varies, so the task is to multiply the electricity consumed for each hour by the correct price for the hour in which it was consumed.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s read our data from a &lt;a href=&quot;https://github.com/realpython/materials/blob/master/pandas-fast-flexible-intuitive/tutorial/demand_profile.csv&quot;&gt;CSV file&lt;/a&gt; that has two columns: one for date plus time and one for electrical energy consumed in kilowatt hours (kWh):&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/csv_image.86d313f7aab0.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/csv_image.86d313f7aab0.jpg&quot; width=&quot;502&quot; height=&quot;308&quot; alt=&quot;CSV data&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The rows contains the electricity used in each hour, so there are &lt;em&gt;365 x 24 = 8760&lt;/em&gt; rows for the whole year.  Each row indicates the usage for the &amp;ldquo;hour starting&amp;rdquo; at the time, so 1/1/13 0:00 indicates the usage for the first hour of January 1st.&lt;/p&gt;
&lt;h2 id=&quot;saving-time-with-datetime-data&quot;&gt;Saving Time With Datetime Data&lt;/h2&gt;
&lt;p&gt;The first thing you need to do is to read your data from the CSV file with one of Pandas&amp;rsquo; I/O functions:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pd&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__version__&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;0.23.1&amp;#39;&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;# Make sure that `demand_profile.csv` is in your&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;# current working directory.&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;demand_profile.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;     date_time  energy_kwh&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0  1/1/13 0:00       0.586&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1  1/1/13 1:00       0.580&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2  1/1/13 2:00       0.572&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3  1/1/13 3:00       0.596&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4  1/1/13 4:00       0.592&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This looks okay at first glance, but there&amp;rsquo;s a small issue.  Pandas and NumPy have a concept of &lt;code&gt;dtypes&lt;/code&gt; (data types). If no arguments are specified, &lt;code&gt;date_time&lt;/code&gt; will take on an &lt;code&gt;object&lt;/code&gt; dtype:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtypes&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;date_time      object&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;energy_kwh    float64&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;dtype: object&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;str&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is not ideal.  &lt;code&gt;object&lt;/code&gt; is a container for not just &lt;code&gt;str&lt;/code&gt;, but any column that can&amp;rsquo;t neatly fit into one data type.  It would be arduous and inefficient to work with dates as strings.  (It would also be memory-inefficient.)&lt;/p&gt;
&lt;p&gt;For working with time series data, you&amp;rsquo;ll want the &lt;code&gt;date_time&lt;/code&gt; column to be formatted as an array of datetime objects.  (Pandas calls this a &lt;code&gt;Timestamp&lt;/code&gt;.) Pandas makes each step here rather simple:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;date_time&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;date_time&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;date_time&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;datetime64[ns]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(Note that you could alternatively use a Pandas &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.PeriodIndex.html&quot;&gt;&lt;code&gt;PeriodIndex&lt;/code&gt;&lt;/a&gt; in this case.)&lt;/p&gt;
&lt;p&gt;You now have a DataFrame called &lt;code&gt;df&lt;/code&gt; that looks much like our CSV file.  It has two columns and a numerical index for referencing the rows.&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;               date_time    energy_kwh&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0    2013-01-01 00:00:00         0.586&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1    2013-01-01 01:00:00         0.580&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2    2013-01-01 02:00:00         0.572&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3    2013-01-01 03:00:00         0.596&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4    2013-01-01 04:00:00         0.592&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The code above is simple and easy, but how fast it? Let’s put it to the test using a &lt;a href=&quot;https://github.com/realpython/materials/blob/master/pandas-fast-flexible-intuitive/tutorial/timer.py&quot;&gt;timing decorator&lt;/a&gt;, which I have unoriginally called &lt;code&gt;@timeit&lt;/code&gt;.  This decorator largely mimics &lt;code&gt;timeit.repeat()&lt;/code&gt; from Python&amp;rsquo;s standard library, but it allows you to return the result of the function itself and print its average runtime from multiple trials.  (Python&amp;rsquo;s &lt;code&gt;timeit.repeat()&lt;/code&gt; returns the timing results, not the function result.)&lt;/p&gt;
&lt;p&gt;Creating a function and placing the &lt;code&gt;@timeit&lt;/code&gt; decorator directly above it will mean that every time the function is called, it will be timed.  The decorator runs an outer loop and an inner loop:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@timeit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;column_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Read in again so that we have `object` dtype to start &lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;date_time&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;convert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;date_time&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Best of 3 trials with 10 function calls per trial:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Function `convert` ran in average of 1.610 seconds.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The result? 1.6 seconds for 8760 rows of data. &amp;ldquo;Great,&amp;rdquo; you might say, &amp;ldquo;that’s no time at all.&amp;rdquo; But what if you encounter larger data sets&amp;mdash;say, one year of electricity use at one-minute intervals? That’s 60 times more data, so you’ll end up waiting around one and a half minutes. That&amp;rsquo;s starting to sound less tolerable. &lt;/p&gt;
&lt;p&gt;In actuality, I recently analyzed 10 years of hourly electricity data from 330 sites. Do you think I waited 88 minutes to convert datetimes? Absolutely not!&lt;/p&gt;
&lt;p&gt;How can you speed this up? As a general rule, Pandas will be far quicker the less it has to interpret your data. In this case, you will see huge speed improvements just by telling Pandas what your time and date data looks like, using the format parameter. You can do this by using the &lt;code&gt;strftime&lt;/code&gt; codes found &lt;a href=&quot;http://strftime.org/&quot;&gt;here&lt;/a&gt; and entering them like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@timeit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;convert_with_format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;column_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;column_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                          &lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;/%m/%y %H:%M&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Best of 3 trials with 100 function calls per trial:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Function `convert_with_format` ran in average of 0.032 seconds.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The new result? 0.032 seconds, which is 50 times faster! So you’ve just saved about 86 minutes of processing time for my 330 sites. Not a bad improvement!&lt;/p&gt;
&lt;p&gt;One finer detail is that the datetimes in the CSV are not in &lt;a href=&quot;https://en.wikipedia.org/wiki/ISO_8601&quot;&gt;ISO 8601 format&lt;/a&gt;: you&amp;rsquo;d need &lt;code&gt;YYYY-MM-DD HH:MM&lt;/code&gt;.  If you don&amp;rsquo;t specify a format, Pandas will use the &lt;a href=&quot;https://dateutil.readthedocs.io/en/stable/&quot;&gt;&lt;code&gt;dateutil&lt;/code&gt;&lt;/a&gt; package to convert each string to a date.  &lt;/p&gt;
&lt;p&gt;Conversely, if the raw datetime data is already in ISO 8601 format, Pandas can immediately take a &lt;a href=&quot;https://github.com/pandas-dev/pandas/blob/08158c076d89177a962d00e4851649f1ef76d12f/pandas/_libs/tslib.pyx#L2129&quot;&gt;fast route&lt;/a&gt; to parsing the dates.  This is one reason why being explicit about the format is so beneficial here.  Another option is to pass &lt;code&gt;infer_datetime_format=True&lt;/code&gt; parameter, but it generally pays to be explicit.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Pandas&amp;rsquo; &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html&quot;&gt;&lt;code&gt;read_csv()&lt;/code&gt;&lt;/a&gt; also allows you to parse dates as a part of the file I/O step.  See the &lt;code&gt;parse_dates&lt;/code&gt;, &lt;code&gt;infer_datetime_format&lt;/code&gt;, and &lt;code&gt;date_parser&lt;/code&gt; parameters.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;simple-looping-over-pandas-data&quot;&gt;Simple Looping Over Pandas Data&lt;/h2&gt;
&lt;p&gt;Now that your dates and times are in a convenient format, you are ready to get down to the business of calculating your electricity costs. Remember that cost varies by hour, so you will need to conditionally apply a cost factor to each hour of the day. In this example, the time-of-use costs will be defined as follows:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tariff Type&lt;/th&gt;
&lt;th&gt;Cents per kWh&lt;/th&gt;
&lt;th&gt;Time Range&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Peak&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;17:00 to 24:00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shoulder&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;7:00 to 17:00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Off-Peak&lt;/td&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;0:00 to 7:00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;If the price were a flat 28 cents per kWh for every hour of the day, most people familiar with Pandas would know that this calculation could be achieved in one line:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;cost_cents&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;energy_kwh&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will result in the creation of a new column with the cost of electricity for that hour:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;               &lt;span class=&quot;n&quot;&gt;date_time&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;energy_kwh&lt;/span&gt;       &lt;span class=&quot;n&quot;&gt;cost_cents&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;    &lt;span class=&quot;mi&quot;&gt;2013&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;         &lt;span class=&quot;mf&quot;&gt;0.586&lt;/span&gt;           &lt;span class=&quot;mf&quot;&gt;16.408&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;    &lt;span class=&quot;mi&quot;&gt;2013&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;         &lt;span class=&quot;mf&quot;&gt;0.580&lt;/span&gt;           &lt;span class=&quot;mf&quot;&gt;16.240&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;    &lt;span class=&quot;mi&quot;&gt;2013&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;02&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;         &lt;span class=&quot;mf&quot;&gt;0.572&lt;/span&gt;           &lt;span class=&quot;mf&quot;&gt;16.016&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;    &lt;span class=&quot;mi&quot;&gt;2013&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;03&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;         &lt;span class=&quot;mf&quot;&gt;0.596&lt;/span&gt;           &lt;span class=&quot;mf&quot;&gt;16.688&lt;/span&gt;
&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;    &lt;span class=&quot;mi&quot;&gt;2013&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;01&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;04&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;00&lt;/span&gt;         &lt;span class=&quot;mf&quot;&gt;0.592&lt;/span&gt;           &lt;span class=&quot;mf&quot;&gt;16.576&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But our cost calculation is conditional on the time of day. This is where you will see a lot of people using Pandas the way it was not intended: by writing a loop to do the conditional calculation. &lt;/p&gt;
&lt;p&gt;For the rest of this tutorial, you&amp;rsquo;ll start from a less-than-ideal baseline solution and work up to a Pythonic solution that fully leverages Pandas.&lt;/p&gt;
&lt;p&gt;But what is Pythonic in the case of Pandas?  The irony is that it is those who are experienced in other (less user-friendly) coding languages such as C++ or Java that are particularly susceptible to this because they instinctively &amp;ldquo;think in loops.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Let’s look at a &lt;a href=&quot;https://dbader.org/blog/pythonic-loops&quot;&gt;loop approach&lt;/a&gt; that is not Pythonic and that many people take when they are unaware of how Pandas is designed to be used. We will use &lt;code&gt;@timeit&lt;/code&gt; again to see how fast this approach is.&lt;/p&gt;
&lt;p&gt;First, let’s create a function to apply the appropriate tariff to a given hour:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply_tariff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kwh&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Calculates cost of electricity for given hour.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;    
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ValueError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Invalid hour: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{hour}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kwh&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here&amp;rsquo;s the loop that isn&amp;rsquo;t Pythonic, in all its glory:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# NOTE: Don&amp;#39;t do this!&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@timeit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply_tariff_loop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Calculate costs in loop.  Modifies `df` inplace.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;energy_cost_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# Get electricity used and hour of day&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;energy_used&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;energy_kwh&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;date_time&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;energy_cost&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apply_tariff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;energy_used&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;energy_cost_list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;energy_cost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;cost_cents&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;energy_cost_list&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply_tariff_loop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Best of 3 trials with 100 function calls per trial:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Function `apply_tariff_loop` ran in average of 3.152 seconds.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For people who picked up Pandas after having written &amp;ldquo;pure Python&amp;rdquo; for some time prior, this design might seem natural: you have a typical &amp;ldquo;for each &lt;em&gt;x&lt;/em&gt;, conditional on &lt;em&gt;y&lt;/em&gt;, do &lt;em&gt;z&lt;/em&gt;.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;However, this loop is clunky. You can consider the above to be an &amp;ldquo;antipattern&amp;rdquo; in Pandas for several reasons.  Firstly, it needs to initialize a list in which the outputs will be recorded.&lt;/p&gt;
&lt;p&gt;Secondly, it uses the opaque object &lt;code&gt;range(0, len(df))&lt;/code&gt; to loop over, and then after applying &lt;code&gt;apply_tariff()&lt;/code&gt;, it has to append the result to a list that is used to make the new DataFrame column.  It also does what is called &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/indexing.html#returning-a-view-versus-a-copy&quot;&gt;chained indexing&lt;/a&gt; with &lt;code&gt;df.iloc[i][&#39;date_time&#39;]&lt;/code&gt;, which often leads to unintended results.&lt;/p&gt;
&lt;p&gt;But the biggest issue with this approach is the time cost of the calculations. On my machine, this loop took over 3 seconds for 8760 rows of data.  Next, you&amp;rsquo;ll look at some improved solutions for iteration over Pandas structures.&lt;/p&gt;
&lt;h2 id=&quot;looping-with-itertuples-and-iterrows&quot;&gt;Looping with &lt;code&gt;.itertuples()&lt;/code&gt; and &lt;code&gt;.iterrows()&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;What other approaches can you take? Well, Pandas has actually made the &lt;code&gt;for i in range(len(df))&lt;/code&gt; syntax redundant by introducing the &lt;code&gt;DataFrame.itertuples()&lt;/code&gt; and &lt;code&gt;DataFrame.iterrows()&lt;/code&gt; methods.  These are both generator methods that &lt;code&gt;yield&lt;/code&gt; one row at a time. &lt;/p&gt;
&lt;p&gt;&lt;code&gt;.itertuples()&lt;/code&gt; yields a &lt;a href=&quot;https://docs.python.org/3.6/library/collections.html#collections.namedtuple&quot;&gt;&lt;code&gt;namedtuple&lt;/code&gt;&lt;/a&gt; for each row, with the row&amp;rsquo;s index value as the first element of the tuple.  A &lt;code&gt;nametuple&lt;/code&gt; is a data structure from Python&amp;rsquo;s &lt;code&gt;collections&lt;/code&gt; module that behaves like a Python tuple but has fields accessible by attribute lookup.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;.iterrows()&lt;/code&gt; yields pairs (tuples) of (index, &lt;code&gt;Series&lt;/code&gt;) for each row in the DataFrame.&lt;/p&gt;
&lt;p&gt;While &lt;code&gt;.itertuples()&lt;/code&gt; tends to be a bit faster, let&amp;rsquo;s stay in Pandas and use &lt;code&gt;.iterrows()&lt;/code&gt; in this example, because some readers might not have run across &lt;code&gt;nametuple&lt;/code&gt;.  Let’s see what this achieves:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@timeit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply_tariff_iterrows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;energy_cost_list&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterrows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# Get electricity used and hour of day&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;energy_used&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;energy_kwh&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;date_time&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# Append cost list&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;energy_cost&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apply_tariff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;energy_used&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;energy_cost_list&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;energy_cost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;cost_cents&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;energy_cost_list&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply_tariff_iterrows&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Best of 3 trials with 100 function calls per trial:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Function `apply_tariff_iterrows` ran in average of 0.713 seconds.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Some marginal gains have been made. The syntax is more explicit, and there is less clutter in your row value references, so it’s more readable. In terms of time gains, is almost 5 five times quicker!&lt;/p&gt;
&lt;p&gt;However, there is more room for improvement.  You&amp;rsquo;re still using some form of a Python for-loop, meaning that each and every function call is done in Python when it could ideally be done in a faster language built into Pandas&amp;rsquo; internal architecture.&lt;/p&gt;
&lt;h2 id=&quot;pandas-apply&quot;&gt;Pandas&amp;rsquo; &lt;code&gt;.apply()&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;You can further improve this operation using the &lt;code&gt;.apply()&lt;/code&gt; method instead of &lt;code&gt;.iterrows()&lt;/code&gt;. Pandas&amp;rsquo; &lt;code&gt;.apply()&lt;/code&gt; method takes functions (callables) and applies them along an axis of a DataFrame (all rows, or all columns). In this example, a &lt;a href=&quot;https://docs.python.org/3.6/tutorial/controlflow.html#lambda-expressions&quot;&gt;lambda function&lt;/a&gt; will help you pass the two columns of data into &lt;code&gt;apply_tariff()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@timeit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply_tariff_withapply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;cost_cents&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apply_tariff&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;kwh&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;energy_kwh&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;date_time&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply_tariff_withapply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Best of 3 trials with 100 function calls per trial:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Function `apply_tariff_withapply` ran in average of 0.272 seconds.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The syntactic advantages of &lt;code&gt;.apply()&lt;/code&gt; are clear, with a significant reduction in the number of lines and very readable, explicit code. In this case, the time taken was roughly half that of the &lt;code&gt;.iterrows()&lt;/code&gt; method. &lt;/p&gt;
&lt;p&gt;However, this is not yet &amp;ldquo;blazingly fast.&amp;rdquo;  One reason is that &lt;code&gt;.apply()&lt;/code&gt; will try internally to loop over &lt;a href=&quot;http://cython.org/&quot;&gt;Cython&lt;/a&gt; iterators.  But in this case, the &lt;code&gt;lambda&lt;/code&gt; that you passed isn&amp;rsquo;t something that can be handled in Cython, so it&amp;rsquo;s called in Python, which is consequently not all that fast.&lt;/p&gt;
&lt;p&gt;If you were to use &lt;code&gt;.apply()&lt;/code&gt; for my 10 years of hourly data for 330 sites, you’d be looking at around 15 minutes of processing time. If this calculation were intended to be a small part of a larger model, you’d really want to speed things up. That’s where vectorized operations come in handy.&lt;/p&gt;
&lt;h2 id=&quot;selecting-data-with-isin&quot;&gt;Selecting Data With &lt;code&gt;.isin()&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Earlier, you saw that if there were a single electricity price, you could apply that price across all the electricity consumption data in one line of code (&lt;code&gt;df[&#39;energy_kwh&#39;] * 28&lt;/code&gt;).  This particular operation was an example of a vectorized operation, and it is the fastest way to do things in Pandas.&lt;/p&gt;
&lt;p&gt;But how can you apply condition calculations as vectorized operations in Pandas? One trick is to select and group parts the DataFrame based on your conditions and then apply a vectorized operation to each selected group.&lt;/p&gt;
&lt;p&gt;In this next example, you will see how to select rows with Pandas&amp;rsquo; &lt;code&gt;.isin()&lt;/code&gt; method and then apply the appropriate tariff in a vectorized operation. Before you do this, it will make things a little more convenient if you set the &lt;code&gt;date_time&lt;/code&gt; column as the DataFrame&amp;rsquo;s index:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;date_time&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;inplace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@timeit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply_tariff_isin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Define hour range Boolean arrays&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;peak_hours&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;shoulder_hours&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;off_peak_hours&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# Apply tariffs to hour ranges&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;peak_hours&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;cost_cents&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;peak_hours&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;energy_kwh&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shoulder_hours&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;cost_cents&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shoulder_hours&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;energy_kwh&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;off_peak_hours&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;cost_cents&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;off_peak_hours&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;energy_kwh&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let&amp;rsquo;s see how this compares:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply_tariff_isin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Best of 3 trials with 100 function calls per trial:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Function `apply_tariff_isin` ran in average of 0.010 seconds.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To understand what’s happening in this code, you need to know that the &lt;code&gt;.isin()&lt;/code&gt; method is returning an array of Boolean values that looks like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;These values identify which DataFrame indices (datetimes) fall within the hour range specified. Then, when you pass these Boolean arrays to the DataFrame’s &lt;code&gt;.loc&lt;/code&gt; indexer, you get a slice of the DataFrame that only includes rows that match those hours. After that, it is simply a matter of multiplying the slice by the appropriate tariff, which is a speedy vectorized operation.&lt;/p&gt;
&lt;p&gt;How does this compare to our looping operations above? Firstly, you may notice that you no longer need &lt;code&gt;apply_tariff()&lt;/code&gt;, because all the conditional logic is applied in the selection of the rows. So there is a huge reduction in the lines of code you have to write and in the Python code that is called.&lt;/p&gt;
&lt;p&gt;What about the processing time? 315 times faster than the loop that wasn&amp;rsquo;t Pythonic, around 71 times faster than &lt;code&gt;.iterrows()&lt;/code&gt; and 27 times faster that &lt;code&gt;.apply()&lt;/code&gt;. Now you are moving at the kind of speed you need to get through big data sets nice and quickly.&lt;/p&gt;
&lt;h2 id=&quot;can-we-do-better&quot;&gt;Can We Do Better?&lt;/h2&gt;
&lt;p&gt;In &lt;code&gt;apply_tariff_isin()&lt;/code&gt;, we are still admittedly doing some &amp;ldquo;manual work&amp;rdquo; by calling &lt;code&gt;df.loc&lt;/code&gt; and &lt;code&gt;df.index.hour.isin()&lt;/code&gt; three times each.  You could argue that this solution isn&amp;rsquo;t scalable if we had a more granular range of time slots.  (A different rate for each hour would require 24 &lt;code&gt;.isin()&lt;/code&gt; calls.)  Luckily, you can do things even more programmatically with Pandas&amp;rsquo; &lt;code&gt;pd.cut()&lt;/code&gt; function in this case:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@timeit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply_tariff_cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cents_per_kwh&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                           &lt;span class=&quot;n&quot;&gt;bins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                           &lt;span class=&quot;n&quot;&gt;include_lowest&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                           &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;astype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;cost_cents&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cents_per_kwh&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;energy_kwh&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Let&amp;rsquo;s take a second to see what&amp;rsquo;s going on here.  &lt;code&gt;pd.cut()&lt;/code&gt; is applying an array of labels (our costs) according to which bin each hour belongs in. Note that the &lt;code&gt;include_lowest&lt;/code&gt; parameter indicates whether the first interval should be left-inclusive or not.  (You want to include &lt;code&gt;time=0&lt;/code&gt; in a group.)&lt;/p&gt;
&lt;p&gt;This is a fully vectorized way to get to your intended result, and it comes out on top in terms of timing:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply_tariff_cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Best of 3 trials with 100 function calls per trial:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Function `apply_tariff_cut` ran in average of 0.003 seconds.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So far, you&amp;rsquo;ve built up from taking potentially over an hour to under a second to process the full 300-site dataset.  Not bad!  There is one last option, though, which is to use NumPy functions to manipulate the underlying NumPy arrays for each DataFrame, and then to integrate the results back into Pandas data structures.&lt;/p&gt;
&lt;h2 id=&quot;dont-forget-numpy&quot;&gt;Don’t Forget NumPy!&lt;/h2&gt;
&lt;p&gt;One point that should not be forgotten when you are using Pandas is that Pandas Series and DataFrames are designed on top of the NumPy library. This gives you even more computation flexibility, because Pandas works seamlessly with NumPy arrays and operations.&lt;/p&gt;
&lt;p&gt;In this next case you&amp;rsquo;ll use NumPy&amp;rsquo;s &lt;code&gt;digitize()&lt;/code&gt; function. It is similar to Pandas&amp;rsquo; &lt;code&gt;cut()&lt;/code&gt; in that the data will be binned, but this time it will be represented by an array of indexes representing which bin each hour belongs to. These indexes are then applied to a prices array:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;nd&quot;&gt;@timeit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply_tariff_digitize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;prices&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bins&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;digitize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hour&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;cost_cents&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;energy_kwh&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;values&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Like the &lt;code&gt;cut()&lt;/code&gt; function, this syntax is wonderfully concise and easy to read. But how does it compare in speed? Let&amp;rsquo;s see:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;apply_tariff_digitize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Best of 3 trials with 100 function calls per trial:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Function `apply_tariff_digitize` ran in average of 0.002 seconds.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;At this point, there&amp;rsquo;s still a performance improvement, but it&amp;rsquo;s becoming more marginal in nature.  This is probably a good time to call it a day on hacking away at code improvement and think about the bigger picture.&lt;/p&gt;
&lt;p&gt;With Pandas, it can help to maintain &amp;ldquo;hierarchy,&amp;rdquo; if you will, of preferred options for doing batch calculations like you&amp;rsquo;ve done here.  These will usually rank from fastest to slowest (and most to least flexible):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Use vectorized operations: Pandas methods and functions with no for-loops.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;.apply()&lt;/code&gt; method with a callable.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;.itertuples()&lt;/code&gt;: iterate over DataFrame rows as &lt;a href=&quot;https://docs.python.org/3/library/collections.html#collections.namedtuple&quot;&gt;&lt;code&gt;namedtuples&lt;/code&gt;&lt;/a&gt; from Python&amp;rsquo;s &lt;code&gt;collections&lt;/code&gt; module.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;.iterrows()&lt;/code&gt;: iterate over DataFrame rows as (index, &lt;code&gt;pd.Series&lt;/code&gt;) pairs.  While a Pandas Series is a flexible data structure, it can be costly to construct each row into a Series and then access it.&lt;/li&gt;
&lt;li&gt;Use &amp;ldquo;element-by-element&amp;rdquo; for loops, updating each cell or row one at a time with &lt;code&gt;df.loc&lt;/code&gt; or &lt;code&gt;df.iloc&lt;/code&gt;.  (Or, &lt;code&gt;.at&lt;/code&gt;/&lt;code&gt;.iat&lt;/code&gt; for fast scalar access.)&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Don&amp;rsquo;t Take My Word For It:&lt;/strong&gt;  The order of precedence above is a suggestion &lt;a href=&quot;https://stackoverflow.com/a/24871316/7954504&quot;&gt;straight from a core Pandas developer&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Here&amp;rsquo;s the &amp;ldquo;order of precedence&amp;rdquo; above at work, with each function you&amp;rsquo;ve built here:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Runtime (seconds)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;apply_tariff_loop()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3.152&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;apply_tariff_iterrows()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.713&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;apply_tariff_withapply()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.272&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;apply_tariff_isin()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.010&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;apply_tariff_cut()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.003&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;apply_tariff_digitize()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;0.002&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h2 id=&quot;prevent-reprocessing-with-hdfstore&quot;&gt;Prevent Reprocessing with HDFStore&lt;/h2&gt;
&lt;p&gt;Now that you have looked at quick data processes in Pandas, let’s explore how to avoid reprocessing time altogether with &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/io.html#hdf5-pytables&quot;&gt;HDFStore&lt;/a&gt;, which was recently integrated into Pandas.&lt;/p&gt;
&lt;p&gt;Often when you are building a complex data model, it is convenient to do some pre-processing of your data. For example, if you had 10 years of minute-frequency electricity consumption data, simply converting the date and time to datetime might take 20 minutes, even if you specify the format parameter. You really only want to have to do this once, not every time you run your model, for testing or analysis.&lt;/p&gt;
&lt;p&gt;A very useful thing you can do here is pre-process and then store your data in its processed form to be used when needed. But how can you store data in the right format without having to reprocess it again? If you were to save as CSV, you would simply lose your datetime objects and have to re-process it when accessing again.&lt;/p&gt;
&lt;p&gt;Pandas has a built-in solution for this which uses &lt;a href=&quot;https://portal.hdfgroup.org/display/HDF5/HDF5&quot;&gt;HDF5&lt;/a&gt; , a high-performance storage format designed specifically for storing tabular arrays of data. Pandas’ &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/api.html#hdfstore-pytables-hdf5&quot;&gt;&lt;code&gt;HDFStore&lt;/code&gt;&lt;/a&gt; class allows you to store your DataFrame in an HDF5 file so that it can be accessed efficiently, while still retaining column types and other metadata. It is a dictionary-like class, so you can read and write just as you would for a Python &lt;code&gt;dict&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;Here’s how you would go about storing your pre-processed electricity consumption DataFrame, &lt;code&gt;df&lt;/code&gt;, in an HDF5 file:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Create storage object with filename `processed_data`&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;data_store&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HDFStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;processed_data.h5&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Put DataFrame into the object setting the key as &amp;#39;preprocessed_df&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;data_store&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;preprocessed_df&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;data_store&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now you can shut your computer down and take a break knowing that you can come back and your processed data will be waiting for you when you need it. No reprocessing required. Here’s how you would access your data from the HDF5 file, with data types preserved:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Access data store&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;data_store&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HDFStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;processed_data.h5&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Retrieve data using key&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;preprocessed_df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_store&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;preprocessed_df&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;data_store&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A data store can house multiple tables, with the name of each as a key.&lt;/p&gt;
&lt;p&gt;Just a note about using the HDFStore in Pandas: you will need to have PyTables &gt;= 3.0.0 installed, so after you have installed Pandas, make sure to update PyTables like this:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;pip install --upgrade tables&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;If you don’t feel like your Pandas project is &lt;strong&gt;fast&lt;/strong&gt;, &lt;strong&gt;flexible&lt;/strong&gt;, &lt;strong&gt;easy&lt;/strong&gt;, and &lt;strong&gt;intuitive&lt;/strong&gt;, consider rethinking how you&amp;rsquo;re using the library.&lt;/p&gt;
&lt;p&gt;The examples you&amp;rsquo;ve explored here are fairly straightforward but illustrate how the proper application of Pandas features can make vast improvements to runtime and code readability to boot. Here are a few rules of thumb that you can apply next time you&amp;rsquo;re working with large data sets in Pandas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Try to use &lt;a href=&quot;https://realpython.com/numpy-array-programming/#what-is-vectorization&quot;&gt;vectorized operations&lt;/a&gt; where possible rather than approaching problems with the &lt;code&gt;for x in df...&lt;/code&gt; mentality.  If your code is home to a lot of for-loops, it might be better suited to working with native Python data structures, because Pandas otherwise comes with a lot of overhead.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you have more complex operations where vectorization is simply impossible or too difficult to work out efficiently, use the &lt;code&gt;.apply()&lt;/code&gt; method.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you do have to loop over your array (which does happen), use &lt;code&gt;.iterrows()&lt;/code&gt; or &lt;code&gt;.itertuples()&lt;/code&gt; to improve speed and syntax.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Pandas has a lot of optionality, and there are almost always several ways to get from A to B.  Be mindful of this, compare how different routes perform, and choose the one that works best in the context of your project.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Once you&amp;rsquo;ve got a data cleaning script built, avoid reprocessing by storing your intermediate results with HDFStore.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Integrating NumPy into Pandas operations can often improve speed and simplify syntax.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Lists and Tuples in Python</title>
      <id>https://realpython.com/python-lists-tuples/</id>
      <link href="https://realpython.com/python-lists-tuples/"/>
      <updated>2018-07-18T14:00:00+00:00</updated>
      <summary>You&#39;ll cover the important characteristics of lists and tuples in Python 3. You&#39;ll learn how to define them and how to manipulate them. When you&#39;re finished, you should have a good feel for when and how to use these object types in a Python program.</summary>
      <content type="html">
        &lt;p&gt;&lt;strong&gt;Lists&lt;/strong&gt; and &lt;strong&gt;tuples&lt;/strong&gt; are arguably Python&amp;rsquo;s most versatile, useful data types.  You will find them in virtually every nontrivial Python program.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Here&amp;rsquo;s what you&amp;rsquo;ll learn in this tutorial:&lt;/strong&gt; You&amp;rsquo;ll cover the important characteristics of lists and tuples. You&amp;rsquo;ll learn how to define them and how to manipulate them.  When you&amp;rsquo;re finished, you should have a good feel for when and how to use these object types in a Python program.&lt;/p&gt;
&lt;h2 id=&quot;python-lists&quot;&gt;Python Lists&lt;/h2&gt;
&lt;p&gt;In short, a list is a collection of arbitrary objects, somewhat akin to an array in many other programming languages but more flexible.  Lists are defined in Python by enclosing a comma-separated sequence of objects in square brackets (&lt;code&gt;[]&lt;/code&gt;), as shown below:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt; a = [&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The important characteristics of Python lists are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lists are ordered.&lt;/li&gt;
&lt;li&gt;Lists can contain any arbitrary objects.&lt;/li&gt;
&lt;li&gt;List elements can be accessed by index.&lt;/li&gt;
&lt;li&gt;Lists can be nested to arbitrary depth.&lt;/li&gt;
&lt;li&gt;Lists are mutable.&lt;/li&gt;
&lt;li&gt;Lists are dynamic.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of these features is examined in more detail below.&lt;/p&gt;
&lt;h3 id=&quot;lists-are-ordered&quot;&gt;Lists Are Ordered&lt;/h3&gt;
&lt;p&gt;A list is not merely a collection of objects.  It is an ordered collection of objects.  The order in which you specify the elements when you define a list is an innate characteristic of that list and is maintained for that list&amp;rsquo;s lifetime.  (You will see a Python data type that is not ordered in the next tutorial on dictionaries.)&lt;/p&gt;
&lt;p&gt;Lists that have the same elements in a different order are not the same:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;lists-can-contain-arbitrary-objects&quot;&gt;Lists Can Contain Arbitrary Objects&lt;/h3&gt;
&lt;p&gt;A list can contain any assortment of objects.  The elements of a list can all be the same type:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[2, 4, 6, 8]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or the elements can be of varying types:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;21.42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bark&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14159&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[21.42, &amp;#39;foobar&amp;#39;, 3, 4, &amp;#39;bark&amp;#39;, False, 3.14159]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Lists can even contain complex objects, like functions, classes, and modules, which you will learn about in upcoming tutorials:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;int&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;built-in function len&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;function foo at 0x035B9030&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;math&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;math&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;module &amp;#39;math&amp;#39; (built-in)&amp;gt;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;lt;class &amp;#39;int&amp;#39;&amp;gt;, &amp;lt;built-in function len&amp;gt;, &amp;lt;function foo at 0x02CA2618&amp;gt;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;module &amp;#39;math&amp;#39; (built-in)&amp;gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A list can contain any number of objects, from zero to as many as your computer&amp;rsquo;s memory will allow:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;29&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;34&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;37&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;38&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;39&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;41&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;43&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;44&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;45&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;46&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;47&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;49&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;51&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;52&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;53&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;54&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;56&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;57&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;58&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;61&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;62&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;63&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;65&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;66&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;67&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;68&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;69&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;70&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;71&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;72&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;73&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;74&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;75&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;76&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;77&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;78&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;79&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;81&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;82&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;83&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;84&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;85&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;86&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;87&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;88&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;89&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;91&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;92&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;93&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;94&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;95&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;96&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;97&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;98&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;97, 98, 99, 100]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(A list with a single object is sometimes referred to as a singleton list.)&lt;/p&gt;
&lt;p&gt;List objects needn&amp;rsquo;t be unique.  A given object can appear in a list multiple times:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bark&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;meow&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;woof&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bark&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;cheep&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bark&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;bark&amp;#39;, &amp;#39;meow&amp;#39;, &amp;#39;woof&amp;#39;, &amp;#39;bark&amp;#39;, &amp;#39;cheep&amp;#39;, &amp;#39;bark&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;list-elements-can-be-accessed-by-index&quot;&gt;List Elements Can Be Accessed by Index&lt;/h3&gt;
&lt;p&gt;Individual elements in a list can be accessed using an index in square brackets.  This is exactly analogous to accessing individual characters in a string. List indexing is zero-based as it is with strings.&lt;/p&gt;
&lt;p&gt;Consider the following list:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The indices for the elements in &lt;code&gt;a&lt;/code&gt; are shown below:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.eb0b38e642c5.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/t.eb0b38e642c5.png&quot; width=&quot;1653&quot; height=&quot;312&quot; alt=&quot;Diagram of a Python list&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;List Indices&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Here is Python code to access some elements of &lt;code&gt;a&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Virtually everything about string indexing works similarly for lists.  For example, a negative list index counts from the end of the list:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.c11ea56e8ca2.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/t.c11ea56e8ca2.png&quot; width=&quot;1653&quot; height=&quot;429&quot; alt=&quot;Diagram of a Python list&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Negative List Indexing&lt;/figcaption&gt;&lt;/figure&gt;

&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Slicing also works.  If &lt;code&gt;a&lt;/code&gt; is a list, the expression &lt;code&gt;a[m:n]&lt;/code&gt; returns the portion of &lt;code&gt;a&lt;/code&gt; from index &lt;code&gt;m&lt;/code&gt; to, but not including, index &lt;code&gt;n&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Other features of string slicing work analogously for list slicing as well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Both positive and negative indices can be specified:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Omitting the first index starts the slice at the beginning of the list, and omitting the second index extends the slice to the end of the list:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;] [&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;] [&amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You can specify a stride&amp;mdash;either positive or negative:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;quux&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;bar&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;corge&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;bar&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The syntax for reversing a list works the same way it does for strings:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;corge&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;foo&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;[:]&lt;/code&gt; syntax works for lists.  However, there is an important difference between how this operation works with a list and how it works with a string.&lt;/p&gt;
&lt;p&gt;If &lt;code&gt;s&lt;/code&gt; is a string, &lt;code&gt;s[:]&lt;/code&gt; returns a reference to the same object:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Conversely, if &lt;code&gt;a&lt;/code&gt; is a list, &lt;code&gt;a[:]&lt;/code&gt; returns a new object that is a copy of &lt;code&gt;a&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:]&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Several Python operators and built-in functions can also be used with lists in ways that are analogous to strings:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;in&lt;/code&gt; and &lt;code&gt;not in&lt;/code&gt; operators:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;thud&amp;#39;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The concatenation (&lt;code&gt;+&lt;/code&gt;) and replication (&lt;code&gt;*&lt;/code&gt;) operators:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;grault&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;garply&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;, &amp;#39;grault&amp;#39;, &amp;#39;garply&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;, &amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;len()&lt;/code&gt;, &lt;code&gt;min()&lt;/code&gt;, and &lt;code&gt;max()&lt;/code&gt; functions:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;rsquo;s not an accident that strings and lists behave so similarly.  They are both special cases of a more general object type called an iterable, which you will encounter in more detail in the upcoming tutorial on definite iteration.&lt;/p&gt;
&lt;p&gt;By the way, in each example above, the list is always assigned to a variable before an operation is performed on it.  But you can operate on a list literal as well:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;corge&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;foo&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For that matter, you can do likewise with a string literal:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;If Comrade Napoleon says it, it must be right.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;.thgir eb tsum ti ,ti syas noelopaN edarmoC fI&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;lists-can-be-nested&quot;&gt;Lists Can Be Nested&lt;/h3&gt;
&lt;p&gt;You have seen that an element in a list can be any sort of object.  That includes another list.  A list can contain sublists, which in turn can contain sublists themselves, and so on to arbitrary depth.&lt;/p&gt;
&lt;p&gt;Consider this (admittedly contrived) example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bb&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ccc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;ddd&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;ee&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;ff&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;g&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;hh&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;ii&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;j&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, [&amp;#39;bb&amp;#39;, [&amp;#39;ccc&amp;#39;, &amp;#39;ddd&amp;#39;], &amp;#39;ee&amp;#39;, &amp;#39;ff&amp;#39;], &amp;#39;g&amp;#39;, [&amp;#39;hh&amp;#39;, &amp;#39;ii&amp;#39;], &amp;#39;j&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The object structure that &lt;code&gt;x&lt;/code&gt; references is diagrammed below:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.c952a91adf3d.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/t.c952a91adf3d.png&quot; width=&quot;2301&quot; height=&quot;1122&quot; alt=&quot;Nested lists diagram&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;A Nested List&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;&lt;code&gt;x[0]&lt;/code&gt;, &lt;code&gt;x[2]&lt;/code&gt;, and &lt;code&gt;x[4]&lt;/code&gt; are strings, each one character long:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;a g j&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But &lt;code&gt;x[1]&lt;/code&gt; and &lt;code&gt;x[3]&lt;/code&gt; are sublists:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;bb&amp;#39;, [&amp;#39;ccc&amp;#39;, &amp;#39;ddd&amp;#39;], &amp;#39;ee&amp;#39;, &amp;#39;ff&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;hh&amp;#39;, &amp;#39;ii&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To access the items in a sublist, simply append an additional index:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;bb&amp;#39;, [&amp;#39;ccc&amp;#39;, &amp;#39;ddd&amp;#39;], &amp;#39;ee&amp;#39;, &amp;#39;ff&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;bb&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;ccc&amp;#39;, &amp;#39;ddd&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;ee&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;ff&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;hh&amp;#39;, &amp;#39;ii&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;hh ii&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;x[1][1]&lt;/code&gt; is yet another sublist, so adding one more index accesses its elements:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;ccc&amp;#39;, &amp;#39;ddd&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;ccc ddd&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There is no limit, short of the extent of your computer&amp;rsquo;s memory, to the depth or complexity with which lists can be nested in this way.&lt;/p&gt;
&lt;p&gt;All the usual syntax regarding indices and slicing applies to sublists as well:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;ddd&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[[&amp;#39;ccc&amp;#39;, &amp;#39;ddd&amp;#39;], &amp;#39;ee&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;ii&amp;#39;, &amp;#39;hh&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, be aware that operators and functions apply to only the list at the level you specify and are not recursive.  Consider what happens when you query the length of &lt;code&gt;x&lt;/code&gt; using &lt;code&gt;len()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, [&amp;#39;bb&amp;#39;, [&amp;#39;ccc&amp;#39;, &amp;#39;ddd&amp;#39;], &amp;#39;ee&amp;#39;, &amp;#39;ff&amp;#39;], &amp;#39;g&amp;#39;, [&amp;#39;hh&amp;#39;, &amp;#39;ii&amp;#39;], &amp;#39;j&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;bb&amp;#39;, [&amp;#39;ccc&amp;#39;, &amp;#39;ddd&amp;#39;], &amp;#39;ee&amp;#39;, &amp;#39;ff&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;g&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;hh&amp;#39;, &amp;#39;ii&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;j&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;x&lt;/code&gt; has only five elements&amp;mdash;three strings and two sublists.  The individual elements in the sublists don&amp;rsquo;t count toward &lt;code&gt;x&lt;/code&gt;&amp;rsquo;s length.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;d encounter a similar situation when using the &lt;code&gt;in&lt;/code&gt; operator:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ddd&amp;#39;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ddd&amp;#39;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ddd&amp;#39;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;&#39;ddd&#39;&lt;/code&gt; is not one of the elements in &lt;code&gt;x&lt;/code&gt; or &lt;code&gt;x[1]&lt;/code&gt;. It is only directly an element in the sublist &lt;code&gt;x[1][1]&lt;/code&gt;.  An individual element in a sublist does not count as an element of the parent list(s).&lt;/p&gt;
&lt;h3 id=&quot;lists-are-mutable&quot;&gt;Lists Are Mutable&lt;/h3&gt;
&lt;p&gt;Most of the data types you have encountered so far have been atomic types.  Integer or float objects, for example, are primitive units that can&amp;rsquo;t be further broken down.  These types are immutable, meaning that they can&amp;rsquo;t be changed once they have been assigned. It doesn&amp;rsquo;t make much sense to think of changing the value of an integer.  If you want a different integer, you just assign a different one.&lt;/p&gt;
&lt;p&gt;By contrast, the string type is a composite type.  Strings are reducible to smaller parts&amp;mdash;the component characters.  It might make sense to think of changing the characters in a string.  But you can&amp;rsquo;t.  In Python, strings are also immutable.&lt;/p&gt;
&lt;p&gt;The list is the first mutable data type you have encountered.  Once a list has been created, elements can be added, deleted, shifted, and moved around at will.  Python provides a wide range of ways to modify lists.&lt;/p&gt;
&lt;h4 id=&quot;modifying-a-single-list-value&quot;&gt;Modifying a Single List Value&lt;/h4&gt;
&lt;p&gt;A single value in a list can be replaced by indexing and simple assignment:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, 10, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, 20]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You may recall from the tutorial &lt;a href=&quot;https://realpython.com/python-strings/#modifying-strings]&quot;&gt;Strings and Character Data in Python&lt;/a&gt; that you can&amp;rsquo;t do this with a string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobarbaz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;x&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&amp;#39;str&amp;#39; object does not support item assignment&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A list item can be deleted with the &lt;code&gt;del&lt;/code&gt; command:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;del&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;modifying-multiple-list-values&quot;&gt;Modifying Multiple List Values&lt;/h4&gt;
&lt;p&gt;What if you want to change several contiguous elements in a list at one time?  Python allows this with slice assignment, which has the following syntax:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Again, for the moment, think of an iterable as a list. This assignment replaces the specified slice of &lt;code&gt;a&lt;/code&gt; with &lt;code&gt;&amp;lt;iterable&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;4.4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;5.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, 1.1, 2.2, 3.3, 4.4, 5.5, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1.1, 2.2, 3.3, 4.4, 5.5]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Bark!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;Bark!&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The number of elements inserted need not be equal to the number replaced. Python just grows or shrinks the list as needed.&lt;/p&gt;
&lt;p&gt;You can insert multiple elements in place of a single element&amp;mdash;just use a slice that denotes only one element:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 2.1, 2.2, 2.3, 3]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that this is not the same as replacing the single element with a list:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, [2.1, 2.2, 2.3], 3]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can also insert elements into a list without removing anything. Simply specify a slice of the form &lt;code&gt;[n:n]&lt;/code&gt; (a zero-length slice) at the desired index:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 2, 3, 4, 5, 6, 7, 8]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can delete multiple elements out of the middle of a list by assigning the appropriate slice to an empty list.  You can also use the &lt;code&gt;del&lt;/code&gt; statement with the same slice:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;del&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;prepending-or-appending-items-to-a-list&quot;&gt;Prepending or Appending Items to a List&lt;/h4&gt;
&lt;p&gt;Additional items can be added to the start or end of a list using the &lt;code&gt;+&lt;/code&gt; concatenation operator or the &lt;code&gt;+=&lt;/code&gt; augmented assignment operator:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;grault&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;garply&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;, &amp;#39;grault&amp;#39;, &amp;#39;garply&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[10, 20, &amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that a list must be concatenated with another list, so if you want to add only one element, you need to specify it as a singleton list:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#58&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&amp;#39;int&amp;#39; object is not iterable&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;, 20]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Technically, it isn&amp;rsquo;t quite correct to say a list must be concatenated with another list. More precisely, a list must be concatenated with an object that is iterable.  Of course, lists are iterable, so it works to concatenate a list with another list.&lt;/p&gt;
&lt;p&gt;Strings are iterable also.  But watch what happens when you concatenate a string onto a list:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;c&amp;#39;, &amp;#39;o&amp;#39;, &amp;#39;r&amp;#39;, &amp;#39;g&amp;#39;, &amp;#39;e&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This result is perhaps not quite what you expected.  When a string is iterated through, the result is a list of its component characters.  In the above example, what gets concatenated onto list &lt;code&gt;a&lt;/code&gt; is a list of the characters in the string &lt;code&gt;&#39;corge&#39;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you really want to add just the single string &lt;code&gt;&#39;corge&#39;&lt;/code&gt; to the end of the list, you need to specify it as a singleton list:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If this seems mysterious, don&amp;rsquo;t fret too much.  You&amp;rsquo;ll learn about the ins and outs of iterables in the tutorial on definite iteration.&lt;/p&gt;
&lt;/div&gt;
&lt;h4 id=&quot;methods-that-modify-a-list&quot;&gt;Methods That Modify a List&lt;/h4&gt;
&lt;p&gt;Finally, Python supplies several built-in methods that can be used to modify lists.  Information on these methods is detailed below.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The string methods you saw in the previous tutorial did not modify the target string directly.  That is because strings are immutable.  Instead, string methods return a new string object that is modified as directed by the method. They leave the original target string unchanged:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foobar FOOBAR&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;List methods are different. Because lists are mutable, the list methods shown here modify the target list in place.&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;a.append(&amp;lt;obj&amp;gt;)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Appends an object to a list.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;a.append(&amp;lt;obj&amp;gt;)&lt;/code&gt; appends object &lt;code&gt;&amp;lt;obj&amp;gt;&lt;/code&gt; to the end of list &lt;code&gt;a&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, 123]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Remember, list methods modify the target list in place. They do not return a new list:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;None&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, 123]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Remember that when the &lt;code&gt;+&lt;/code&gt; operator is used to concatenate to a list, if the target operand is an iterable, then its elements are broken out and appended to the list individually:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, 1, 2, 3]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;.append()&lt;/code&gt; method does not work that way!  If an iterable is appended to a list with &lt;code&gt;.append()&lt;/code&gt;, it is added as a single object:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, [1, 2, 3]]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Thus, with &lt;code&gt;.append()&lt;/code&gt;, you can append a string as a single entity:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;foo&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;a.extend(&amp;lt;iterable&amp;gt;)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Extends a list with the objects from an iterable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes, this is probably what you think it is.  &lt;code&gt;.extend()&lt;/code&gt; also adds to the end of a list, but the argument is expected to be an iterable.  The items in &lt;code&gt;&amp;lt;iterable&amp;gt;&lt;/code&gt; are added individually:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, 1, 2, 3]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In other words, &lt;code&gt;.extend()&lt;/code&gt; behaves like the &lt;code&gt;+&lt;/code&gt; operator. More precisely, since it modifies the list in place, it behaves like the &lt;code&gt;+=&lt;/code&gt; operator:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, 1, 2, 3]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;a.insert(&amp;lt;index&amp;gt;, &amp;lt;obj&amp;gt;)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Inserts an object into a list.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;a.insert(&amp;lt;index&amp;gt;, &amp;lt;obj&amp;gt;)&lt;/code&gt; inserts object &lt;code&gt;&amp;lt;obj&amp;gt;&lt;/code&gt; into list &lt;code&gt;a&lt;/code&gt; at the specified &lt;code&gt;&amp;lt;index&amp;gt;&lt;/code&gt;.  Following the method call, &lt;code&gt;a[&amp;lt;index&amp;gt;]&lt;/code&gt; is &lt;code&gt;&amp;lt;obj&amp;gt;&lt;/code&gt;, and the remaining list elements are pushed to the right:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14159&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3.14159&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, 3.14159, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;a.remove(&amp;lt;obj&amp;gt;)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Removes an object from a list.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;a.remove(&amp;lt;obj&amp;gt;)&lt;/code&gt; removes object &lt;code&gt;&amp;lt;obj&amp;gt;&lt;/code&gt; from list &lt;code&gt;a&lt;/code&gt;.  If &lt;code&gt;&amp;lt;obj&amp;gt;&lt;/code&gt; isn&amp;rsquo;t in &lt;code&gt;a&lt;/code&gt;, an  exception is raised:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Bark!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#13&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Bark!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;ValueError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;list.remove(x): x not in list&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;a.pop(index=-1)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Removes an element from a list.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This method differs from &lt;code&gt;.remove()&lt;/code&gt; in two ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You specify the index of the item to remove, rather than the object itself.&lt;/li&gt;
&lt;li&gt;The method returns a value: the item that was removed.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;a.pop()&lt;/code&gt; simply removes the last item in the list:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the optional &lt;code&gt;&amp;lt;index&amp;gt;&lt;/code&gt; parameter is specified, the item at that index is removed and returned.  &lt;code&gt;&amp;lt;index&amp;gt;&lt;/code&gt; may be negative, as with string and list indexing:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;index&amp;gt;&lt;/code&gt; defaults to &lt;code&gt;-1&lt;/code&gt;, so &lt;code&gt;a.pop(-1)&lt;/code&gt; is equivalent to &lt;code&gt;a.pop()&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;lists-are-dynamic&quot;&gt;Lists Are Dynamic&lt;/h3&gt;
&lt;p&gt;This tutorial began with a list of six defining characteristics of Python lists.  The last one is that lists are dynamic.  You have seen many examples of this in the sections above.  When items are added to a list, it grows as needed:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.14159&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, 1, 2, 3, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;, 3.14159]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Similarly, a list shrinks to accommodate the removal of items:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;del&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;bar&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;python-tuples&quot;&gt;Python Tuples&lt;/h2&gt;
&lt;p&gt;Python provides another type that is an ordered collection of objects, called a tuple.&lt;/p&gt;
&lt;p&gt;Pronunciation varies depending on whom you ask.  Some pronounce it as though it were spelled &amp;ldquo;too-ple&amp;rdquo; (rhyming with &amp;ldquo;Mott the Hoople&amp;rdquo;), and others as though it were spelled &amp;ldquo;tup-ple&amp;rdquo; (rhyming with &amp;ldquo;supple&amp;rdquo;).  My inclination is the latter, since it presumably derives from the same origin as &amp;ldquo;quintuple,&amp;rdquo; &amp;ldquo;sextuple,&amp;rdquo; &amp;ldquo;octuple,&amp;rdquo; and so on, and everyone I know pronounces these latter as though they rhymed with &amp;ldquo;supple.&amp;rdquo;&lt;/p&gt;
&lt;h3 id=&quot;defining-and-using-tuples&quot;&gt;Defining and Using Tuples&lt;/h3&gt;
&lt;p&gt;Tuples are identical to lists in all respects, except for the following properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tuples are defined by enclosing the elements in parentheses (&lt;code&gt;()&lt;/code&gt;) instead of square brackets (&lt;code&gt;[]&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Tuples are immutable.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is a short example showing a tuple definition, indexing, and slicing:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;corge&amp;#39;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;bar&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;corge&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Never fear!  Our favorite string and list reversal mechanism works for tuples as well:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;corge&amp;#39;, &amp;#39;quux&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;foo&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Even though tuples are defined using parentheses, you still index and slice tuples using square brackets, just as for strings and lists.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Everything you&amp;rsquo;ve learned about lists&amp;mdash;they are ordered, they can contain arbitrary objects, they can be indexed and sliced, they can be nested&amp;mdash;is true of tuples as well.  But they can&amp;rsquo;t be modified:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Bark!&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#65&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Bark!&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&amp;#39;tuple&amp;#39; object does not support item assignment&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Why use a tuple instead of a list?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Program execution is faster when manipulating a tuple than it is for the equivalent list.  (This is probably not going to be noticeable when the list or tuple is small.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Sometimes you don&amp;rsquo;t want data to be modified.  If the values in the collection are meant to remain constant for the life of the program, using a tuple instead of a list guards against accidental modification.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There is another Python data type that you will encounter shortly called a dictionary, which requires as one of its components a value that is of an immutable type.  A tuple can be used for this purpose, whereas a list can&amp;rsquo;t be.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In a Python REPL session, you can display the values of several objects simultaneously by entering them directly at the &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; prompt, separated by commas:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.14159&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;foo&amp;#39;, 3.14159, 42)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Python displays the response in parentheses because it is implicitly interpreting the input as a tuple.&lt;/p&gt;
&lt;p&gt;There is one peculiarity regarding tuple definition that you should be aware of.  There is no ambiguity when defining an empty tuple, nor one with two or more elements.  Python knows you are defining a tuple:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;tuple&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;tuple&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;tuple&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But what happens when you try to define a tuple with one item:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;int&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Doh!&lt;/em&gt;  Since parentheses are also used to define operator precedence in expressions, Python evaluates the expression &lt;code&gt;(2)&lt;/code&gt; as simply the integer &lt;code&gt;2&lt;/code&gt; and creates an &lt;code&gt;int&lt;/code&gt; object.  To tell Python that you really want to define a singleton tuple, include a trailing comma (&lt;code&gt;,&lt;/code&gt;) just before the closing parenthesis:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;tuple&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You probably won&amp;rsquo;t need to define a singleton tuple often, but there has to be a way.&lt;/p&gt;
&lt;p&gt;When you display a singleton tuple, Python includes the comma, to remind you that it&amp;rsquo;s a tuple:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(2,)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;tuple-assignment-packing-and-unpacking&quot;&gt;Tuple Assignment, Packing, and Unpacking&lt;/h3&gt;
&lt;p&gt;As you have already seen above, a literal tuple containing several items can be assigned to a single object:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When this occurs, it is as though the items in the tuple have been &amp;ldquo;packed&amp;rdquo; into the object:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.feb20d10b75d.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/t.feb20d10b75d.png&quot; width=&quot;1611&quot; height=&quot;882&quot; alt=&quot;tuple packing&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Tuple Packing&lt;/figcaption&gt;&lt;/figure&gt;

&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If that &amp;ldquo;packed&amp;rdquo; object is subsequently assigned to a new tuple, the individual items are &amp;ldquo;unpacked&amp;rdquo; into the objects in the tuple:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.629d7402a412.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/t.629d7402a412.png&quot; width=&quot;1023&quot; height=&quot;894&quot; alt=&quot;tuple unpacking&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Tuple Unpacking&lt;/figcaption&gt;&lt;/figure&gt;

&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s4&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When unpacking, the number of variables on the left must match the number of values in the tuple:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#16&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;ValueError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;too many values to unpack (expected 3)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#17&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;ValueError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;not enough values to unpack (expected 5, got 4)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Packing and unpacking can be combined into one statement to make a compound assignment:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s4&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Again, the number of elements in the tuple on the left of the assignment must equal the number on the right:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#63&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;ValueError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;not enough values to unpack (expected 5, got 4)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In assignments like this and a small handful of other situations, Python allows the parentheses that are usually used for denoting a tuple to be left out:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(1, 2, 3)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(1, 2, 3)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(4, 5, 6)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(2,)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It works the same whether the parentheses are included or not, so if you have any doubt as to whether they&amp;rsquo;re needed, go ahead and include them.&lt;/p&gt;
&lt;p&gt;Tuple assignment allows for a curious bit of idiomatic Python.  Frequently when programming, you have two variables whose values you need to swap.  In most programming languages, it is necessary to store one of the values in a temporary variable while the swap occurs like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;)&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;# We need to define a temp variable to accomplish the swap.&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;temp&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;bar&amp;#39;, &amp;#39;foo&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In Python, the swap can be done with a single tuple assignment:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;)&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;# Magic time!&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;bar&amp;#39;, &amp;#39;foo&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As anyone who has ever had to swap values using a temporary variable knows, being able to do it this way in Python is the pinnacle of modern technological achievement.  It will never get better than this.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This tutorial covered the basic properties of Python &lt;strong&gt;lists&lt;/strong&gt; and &lt;strong&gt;tuples&lt;/strong&gt;, and how to manipulate them.  You will use these extensively in your Python programming.&lt;/p&gt;
&lt;p&gt;One of the chief characteristics of a list is that it is ordered.  The order of the elements in a list is an intrinsic property of that list and does not change, unless the list itself is modified.  (The same is true of tuples, except of course they can&amp;rsquo;t be modified.)&lt;/p&gt;
&lt;p&gt;The next tutorial will introduce you to the Python &lt;strong&gt;dictionary:&lt;/strong&gt; a composite data type that is unordered.  Read on!&lt;/p&gt;
&lt;div class=&quot;container py-3 series-nav mb-3&quot;&gt;
  &lt;div class=&quot;row justify-content-between&quot;&gt;
    &lt;div class=&quot;col-12 col-md-3 text-left text-muted ml-1&quot;&gt;&lt;a href=&quot;https://realpython.com/python-strings/&quot;&gt; «&amp;nbsp;Strings in Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-center text-muted&quot;&gt;&lt;a href=&quot;#&quot;&gt;Lists and Tuples in Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-right text-muted mr-1&quot;&gt;&lt;a &gt;Dictionaries in Python&amp;nbsp;»&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Reading and Writing CSV Files in Python</title>
      <id>https://realpython.com/python-csv/</id>
      <link href="https://realpython.com/python-csv/"/>
      <updated>2018-07-16T14:00:00+00:00</updated>
      <summary>Learn how to read, process, and parse CSV from text files using Python. You&#39;ll see how CSV files work, learn the all-important &quot;csv&quot; library built into Python, and see how CSV parsing works using the &quot;pandas&quot; library.</summary>
      <content type="html">
        &lt;p&gt;Let&amp;rsquo;s face it: you need to get information into and out of your programs through more than just the keyboard and console. Exchanging information through text files is a common way to share info between programs. One of the most popular formats for exchanging data is the CSV format. But how do you use it?&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s get one thing clear: you don&amp;rsquo;t have to (and you won&amp;rsquo;t) build your own CSV parser from scratch. There are several perfectly acceptable libraries you can use. The Python &lt;a href=&quot;https://docs.python.org/3/library/csv.html&quot;&gt;&lt;code&gt;csv&lt;/code&gt; library&lt;/a&gt; will work for most cases. If your work requires lots of data or  numerical analysis, the &lt;a href=&quot;http://pandas.pydata.org/&quot;&gt;&lt;code&gt;pandas&lt;/code&gt; library&lt;/a&gt; has CSV parsing capabilities as well, which should handle the rest.&lt;/p&gt;
&lt;p&gt;In this article, you&amp;rsquo;ll learn how to read, process, and parse CSV from text files using Python. You&amp;rsquo;ll see how CSV files work, learn the all-important &lt;code&gt;csv&lt;/code&gt; library built into Python, and see how CSV parsing works using the &lt;code&gt;pandas&lt;/code&gt; library.&lt;/p&gt;
&lt;p&gt;So let&amp;rsquo;s get started!&lt;/p&gt;
&lt;h2 id=&quot;what-is-a-csv-file&quot;&gt;What Is a CSV File?&lt;/h2&gt;
&lt;p&gt;A CSV file (Comma Separated Values file) is a type of plain text file that uses specific structuring to arrange tabular data. Because it&amp;rsquo;s a plain text file, it can contain only actual text data&amp;mdash;in other words, printable &lt;a href=&quot;https://en.wikipedia.org/wiki/ASCII&quot;&gt;ASCII&lt;/a&gt; or &lt;a href=&quot;https://en.wikipedia.org/wiki/Unicode&quot;&gt;Unicode&lt;/a&gt; characters.&lt;/p&gt;
&lt;p&gt;The structure of a CSV file is given away by its name. Normally, CSV files use a comma to separate each specific data value. Here&amp;rsquo;s what that structure looks like:&lt;/p&gt;
&lt;div class=&quot;highlight csv&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;column 1 name,column 2 name, column 3 name
first row data 1,first row data 2,first row data 3
second row data 1,second row data 2,second row data 3
...
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice how each piece of data is separated by a comma. Normally, the first line identifies each piece of data&amp;mdash;in other words, the name of a data column. Every subsequent line after that is actual data and is limited only by file size constraints.&lt;/p&gt;
&lt;p&gt;In general, the separator character is called a delimiter, and the comma is not the only one used. Other popular delimiters include the tab (&lt;code&gt;\t&lt;/code&gt;), colon (&lt;code&gt;:&lt;/code&gt;) and semi-colon (&lt;code&gt;;&lt;/code&gt;) characters. Properly parsing a CSV file requires us to know which delimiter is being used.&lt;/p&gt;
&lt;h3 id=&quot;where-do-csv-files-come-from&quot;&gt;Where Do CSV Files Come From?&lt;/h3&gt;
&lt;p&gt;CSV files are normally created by programs that handle large amounts of data. They are a convenient way to export data from spreadsheets and databases as well as import or use it in other programs. For example, you might export the results of a data mining program to a CSV file and then import that into a spreadsheet to analyze the data, generate graphs for a presentation, or prepare a report for publication.&lt;/p&gt;
&lt;p&gt;CSV files are very easy to work with programmatically. Any language that supports text file input and string manipulation (like Python) can work with CSV files directly.&lt;/p&gt;
&lt;h2 id=&quot;parsing-csv-files-with-pythons-built-in-csv-library&quot;&gt;Parsing CSV Files With Python&amp;rsquo;s Built-in CSV Library&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;https://docs.python.org/3/library/csv.html&quot;&gt;&lt;code&gt;csv&lt;/code&gt; library&lt;/a&gt; provides functionality to both read from and write to CSV files. Designed to work out of the box with Excel-generated CSV files, it is easily adapted to work with a variety of CSV formats. The &lt;code&gt;csv&lt;/code&gt; library contains objects and other code to read, write, and process data from and to CSV files.&lt;/p&gt;
&lt;h3 id=&quot;reading-csv-files-with-csv&quot;&gt;Reading CSV Files With &lt;code&gt;csv&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Reading from a CSV file is done using the &lt;code&gt;reader&lt;/code&gt; object. The CSV file is opened as a text file with Python&amp;rsquo;s built-in &lt;code&gt;open()&lt;/code&gt; function, which returns a file object. This is then passed to the &lt;code&gt;reader&lt;/code&gt;, which does the heavy lifting.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the &lt;code&gt;employee_birthday.txt&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;highlight csv&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;name,department,birthday month
John Smith,Accounting,November
Erica Meyers,IT,March
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here&amp;rsquo;s code to read it:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;csv&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;employee_birthday.txt&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;csv_reader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csv_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delimiter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv_reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Column names are {&amp;quot;, &amp;quot;.join(row)}&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;line_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{row[0]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; works in the &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{row[1]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; department, and was born in &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{row[2]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;line_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Processed &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{line_count}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; lines.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This results in the following output:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;Column names are name, department, birthday month&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    John Smith works in the Accounting department, and was born in November.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    Erica Meyers works in the IT department, and was born in March.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Processed 3 lines.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Each row returned by the &lt;code&gt;reader&lt;/code&gt; is a list of &lt;code&gt;String&lt;/code&gt; elements containing the data found by removing the delimiters. The first row returned contains the column names, which is handled in a special way.&lt;/p&gt;
&lt;h3 id=&quot;reading-csv-files-into-a-dictionary-with-csv&quot;&gt;Reading CSV Files Into a Dictionary With &lt;code&gt;csv&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Rather than deal with a list of individual &lt;code&gt;String&lt;/code&gt; elements, you can read CSV data directly into a dictionary (technically, an &lt;a href=&quot;https://docs.python.org/3/library/collections.html#collections.OrderedDict&quot;&gt;Ordered Dictionary&lt;/a&gt;) as well.&lt;/p&gt;
&lt;p&gt;Again, our input file, &lt;code&gt;employee_birthday.txt&lt;/code&gt; is as follows:&lt;/p&gt;
&lt;div class=&quot;highlight csv&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;name,department,birthday month
John Smith,Accounting,November
Erica Meyers,IT,March
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here&amp;rsquo;s the code to read it in as a dictionary this time:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;csv&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;employee_birthday.txt&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;csv_reader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DictReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csv_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv_reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Column names are {&amp;quot;, &amp;quot;.join(row)}&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;line_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{row[&amp;quot;name&amp;quot;]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; works in the &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{row[&amp;quot;department&amp;quot;]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; department, and was born in &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{row[&amp;quot;birthday month&amp;quot;]}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;line_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Processed &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{line_count}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; lines.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This results in the same output as before:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;Column names are name, department, birthday month&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    John Smith works in the Accounting department, and was born in November.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    Erica Meyers works in the IT department, and was born in March.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Processed 3 lines.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Where did the dictionary keys come from? The first line of the CSV file is assumed to contain the keys to use to build the dictionary. If you don&amp;rsquo;t have these in your CSV file, you should specify your own keys by setting the &lt;code&gt;fieldnames&lt;/code&gt; optional parameter to a list containing them.&lt;/p&gt;
&lt;h3 id=&quot;optional-python-csv-reader-parameters&quot;&gt;Optional Python CSV &lt;code&gt;reader&lt;/code&gt; Parameters&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;reader&lt;/code&gt; object can handle different styles of CSV files by specifying &lt;a href=&quot;https://docs.python.org/3/library/csv.html?highlight=csv#csv-fmt-params&quot;&gt;additional parameters&lt;/a&gt;, some of which are shown below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;delimiter&lt;/code&gt; specifies the character used to separate each field. The default is the comma (&lt;code&gt;&#39;,&#39;&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;quotechar&lt;/code&gt; specifies the character used to surround fields that contain the delimiter character. The default is a double quote (&lt;code&gt;&#39; &quot; &#39;&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;escapechar&lt;/code&gt; specifies the character used to escape the delimiter character, in case quotes aren&amp;rsquo;t used. The default is no escape character.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These parameters deserve some more explanation. Suppose you&amp;rsquo;re working with the following &lt;code&gt;employee_addresses.txt&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;highlight csv&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;name,address,date joined
john smith,1132 Anywhere Lane Hoboken NJ, 07030,Jan 4
erica meyers,1234 Smith Lane Hoboken NJ, 07030,March 2
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This CSV file contains three fields: &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;address&lt;/code&gt;, and &lt;code&gt;date joined&lt;/code&gt;, which are delimited by commas. The problem is that the data for the &lt;code&gt;address&lt;/code&gt; field also contains a comma to signify the zip code.&lt;/p&gt;
&lt;p&gt;There are three different ways to handle this situation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Use a different delimiter&lt;/strong&gt;&lt;br /&gt;
  That way, the comma can safely be used in the data itself. You use the &lt;code&gt;delimiter&lt;/code&gt; optional parameter to specify the new delimiter.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Wrap the data in quotes&lt;/strong&gt;&lt;br /&gt;
  The special nature of your chosen delimiter is ignored in quoted strings.  Therefore, you can specify the character used for quoting with the &lt;code&gt;quotechar&lt;/code&gt; optional parameter. As long as that character also doesn&amp;rsquo;t appear in the data, you&amp;rsquo;re fine.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Escape the delimiter characters in the data&lt;/strong&gt;&lt;br /&gt;
  Escape characters work just as they do in format strings, nullifying the interpretation of the character being escaped (in this case, the delimiter). If an escape character is used, it must be specified using the &lt;code&gt;escapechar&lt;/code&gt; optional parameter.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;writing-csv-files-with-csv&quot;&gt;Writing CSV Files With &lt;code&gt;csv&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;You can also write to a CSV file using a &lt;code&gt;writer&lt;/code&gt; object and the &lt;code&gt;.write_row()&lt;/code&gt; method:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;csv&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;employee_file.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;employee_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;employee_writer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;employee_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;delimiter&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quotechar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;quot;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;quoting&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;QUOTE_MINIMAL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;employee_writer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;writerow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;John Smith&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Accounting&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;November&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;employee_writer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;writerow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Erica Meyers&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;IT&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;March&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;quotechar&lt;/code&gt; optional parameter tells the &lt;code&gt;writer&lt;/code&gt; which character to use to quote fields when writing. Whether quoting is used or not, however, is determined by the &lt;code&gt;quoting&lt;/code&gt; optional parameter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;quoting&lt;/code&gt; is set to &lt;code&gt;csv.QUOTE_MINIMAL&lt;/code&gt;, then &lt;code&gt;.writerow()&lt;/code&gt; will quote fields only if they contain the &lt;code&gt;delimiter&lt;/code&gt; or the &lt;code&gt;quotechar&lt;/code&gt;. This is the default case.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;quoting&lt;/code&gt; is set to &lt;code&gt;csv.QUOTE_ALL&lt;/code&gt;, then &lt;code&gt;.writerow()&lt;/code&gt; will quote all fields.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;quoting&lt;/code&gt; is set to &lt;code&gt;csv.QUOTE_NONNUMERIC&lt;/code&gt;, then &lt;code&gt;.writerow()&lt;/code&gt; will quote all fields containing text data and convert all numeric fields to the &lt;code&gt;float&lt;/code&gt; data type.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;quoting&lt;/code&gt; is set to &lt;code&gt;csv.QUOTE_NONE&lt;/code&gt;, then &lt;code&gt;.writerow()&lt;/code&gt; will escape delimiters instead of quoting them. In this case, you also must provide a value for the &lt;code&gt;escapechar&lt;/code&gt; optional parameter.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Reading the file back in plain text shows that the file is created as follows:&lt;/p&gt;
&lt;div class=&quot;highlight csv&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;John Smith,Accounting,November
Erica Meyers,IT,March
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;writing-csv-file-from-a-dictionary-with-csv&quot;&gt;Writing CSV File From a Dictionary With &lt;code&gt;csv&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Since you can read our data into a dictionary, it&amp;rsquo;s only fair that you should be able to write it out from a dictionary as well:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;csv&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;employee_file2.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mode&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fieldnames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;emp_name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;dept&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;birth_month&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DictWriter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csv_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fieldnames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fieldnames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;writeheader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;writerow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;emp_name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;John Smith&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;dept&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Accounting&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;birth_month&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;November&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;writer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;writerow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;emp_name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Erica Meyers&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;dept&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;IT&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;birth_month&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;March&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Unlike &lt;code&gt;DictReader&lt;/code&gt;, the &lt;code&gt;fieldnames&lt;/code&gt; parameter is required when writing a dictionary. This makes sense, when you think about it: without a list of &lt;code&gt;fieldnames&lt;/code&gt;, the &lt;code&gt;DictWriter&lt;/code&gt; can&amp;rsquo;t know which keys to use to retrieve values from your dictionaries. It also uses the keys in &lt;code&gt;fieldnames&lt;/code&gt; to write out the first row as column names.&lt;/p&gt;
&lt;p&gt;The code above generates the following output file:&lt;/p&gt;
&lt;div class=&quot;highlight csv&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;emp_name,dept,birth_month
John Smith,Accounting,November
Erica Meyers,IT,March
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;parsing-csv-files-with-the-pandas-library&quot;&gt;Parsing CSV Files With the &lt;code&gt;pandas&lt;/code&gt; Library&lt;/h2&gt;
&lt;p&gt;Of course, the Python CSV library isn&amp;rsquo;t the only game in town. Reading CSV files is possible in &lt;a href=&quot;http://pandas.pydata.org/index.html&quot;&gt;&lt;code&gt;pandas&lt;/code&gt;&lt;/a&gt; as well. It is highly recommended if you have a lot of data to analyze.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pandas&lt;/code&gt; is an open-source Python library that provides high performance data analysis tools and easy to use data structures. &lt;code&gt;pandas&lt;/code&gt; is available for all Python installations, but it is a key part of the &lt;a href=&quot;https://www.anaconda.com/&quot;&gt;Anaconda&lt;/a&gt; distribution and works extremely well in &lt;a href=&quot;https://jupyter.org/&quot;&gt;Jupyter notebooks&lt;/a&gt; to share data, code, analysis results, visualizations, and narrative text.&lt;/p&gt;
&lt;p&gt;Installing &lt;code&gt;pandas&lt;/code&gt; and its dependencies in &lt;code&gt;Anaconda&lt;/code&gt; is easily done:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; conda install pandas
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As is using &lt;code&gt;pip&lt;/code&gt;/&lt;code&gt;pipenv&lt;/code&gt; for other Python installations:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; pip install pandas
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We won&amp;rsquo;t delve into the specifics of how &lt;code&gt;pandas&lt;/code&gt; works or how to use it.  For an in-depth treatment on using &lt;code&gt;pandas&lt;/code&gt; to read and analyze large data sets, check out &lt;a href=&quot;https://realpython.com/team/stiwari/&quot;&gt;Shantnu Tiwari&amp;rsquo;s&lt;/a&gt; superb article on &lt;a href=&quot;https://realpython.com/working-with-large-excel-files-in-pandas/&quot;&gt;working with large Excel files in pandas&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;reading-csv-files-with-pandas&quot;&gt;Reading CSV Files With &lt;code&gt;pandas&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;To show some of the power of &lt;code&gt;pandas&lt;/code&gt; CSV capabilities, I&amp;rsquo;ve created a slightly more complicated file to read, called &lt;code&gt;hrdata.csv&lt;/code&gt;. It contains data on company employees:&lt;/p&gt;
&lt;div class=&quot;highlight csv&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Name,Hire Date,Salary,Sick Days remaining
Graham Chapman,03/15/14,50000.00,10
John Cleese,06/01/15,65000.00,8
Eric Idle,05/12/14,45000.00,10
Terry Jones,11/01/13,70000.00,3
Terry Gilliam,08/12/14,48000.00,7
Michael Palin,05/23/13,66000.00,8
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Reading the CSV into a &lt;code&gt;pandas&lt;/code&gt; &lt;code&gt;DataFrame&lt;/code&gt; is quick and straightforward:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pandas&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;hrdata.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That&amp;rsquo;s it: three lines of code, and only one of them is doing the actual work. &lt;code&gt;pandas.read_csv()&lt;/code&gt; opens, analyzes, and reads the CSV file provided, and stores the data in a &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html&quot;&gt;DataFrame&lt;/a&gt;. Printing the &lt;code&gt;DataFrame&lt;/code&gt; results in the following output:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;             Name Hire Date   Salary  Sick Days remaining&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0  Graham Chapman  03/15/14  50000.0                   10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1     John Cleese  06/01/15  65000.0                    8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2       Eric Idle  05/12/14  45000.0                   10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3     Terry Jones  11/01/13  70000.0                    3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4   Terry Gilliam  08/12/14  48000.0                    7&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5   Michael Palin  05/23/13  66000.0                    8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here are a few points worth noting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First, &lt;code&gt;pandas&lt;/code&gt; recognized that the first line of the CSV contained column names, and used them automatically. I call this Goodness.&lt;/li&gt;
&lt;li&gt;However, &lt;code&gt;pandas&lt;/code&gt; is also using zero-based integer indices in the &lt;code&gt;DataFrame&lt;/code&gt;. That&amp;rsquo;s because we didn&amp;rsquo;t tell it what our index should be.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Further, if you look at the data types of our columns , you&amp;rsquo;ll see &lt;code&gt;pandas&lt;/code&gt; has properly converted the &lt;code&gt;Salary&lt;/code&gt; and &lt;code&gt;Sick Days remaining&lt;/code&gt; columns to numbers, but the &lt;code&gt;Hire Date&lt;/code&gt; column is still a &lt;code&gt;String&lt;/code&gt;. This is easily confirmed in interactive mode:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hire Date&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;str&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s tackle these issues one at a time. To use a different column as the &lt;code&gt;DataFrame&lt;/code&gt; index, add the &lt;code&gt;index_col&lt;/code&gt; optional parameter:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pandas&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;hrdata.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now the &lt;code&gt;Name&lt;/code&gt; field is our &lt;code&gt;DataFrame&lt;/code&gt; index:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;               Hire Date   Salary  Sick Days remaining&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Name                                                  &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Graham Chapman  03/15/14  50000.0                   10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;John Cleese     06/01/15  65000.0                    8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Eric Idle       05/12/14  45000.0                   10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Terry Jones     11/01/13  70000.0                    3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Terry Gilliam   08/12/14  48000.0                    7&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Michael Palin   05/23/13  66000.0                    8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, let&amp;rsquo;s fix the data type of the  &lt;code&gt;Hire Date&lt;/code&gt; field. You can force &lt;code&gt;pandas&lt;/code&gt; to read data as a date with the &lt;code&gt;parse_dates&lt;/code&gt; optional parameter, which is defined as a list of column names to treat as dates:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pandas&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;hrdata.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse_dates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hire Date&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice the difference in the output:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;                Hire Date   Salary  Sick Days remaining&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Name                                                   &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Graham Chapman 2014-03-15  50000.0                   10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;John Cleese    2015-06-01  65000.0                    8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Eric Idle      2014-05-12  45000.0                   10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Terry Jones    2013-11-01  70000.0                    3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Terry Gilliam  2014-08-12  48000.0                    7&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Michael Palin  2013-05-23  66000.0                    8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The date is now formatted properly, which is easily confirmed in interactive mode:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hire Date&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;pandas._libs.tslibs.timestamps.Timestamp&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If your CSV files doesn&amp;rsquo;t have column names in the first line, you can use the &lt;code&gt;names&lt;/code&gt; optional parameter to provide a list of column names. You can also use this if you want to override the column names provided in the first line. In this case, you must also tell &lt;code&gt;pandas.read_csv()&lt;/code&gt; to ignore existing column names using the &lt;code&gt;header=0&lt;/code&gt; optional parameter:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pandas&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;hrdata.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;index_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Employee&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;parse_dates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hired&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Employee&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Hired&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Salary&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Sick Days&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice that, since the column names changed, the columns specified in the &lt;code&gt;index_col&lt;/code&gt; and &lt;code&gt;parse_dates&lt;/code&gt; optional parameters must also be changed. This now results in the following output:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;                    Hired   Salary  Sick Days&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Employee                                     &lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Graham Chapman 2014-03-15  50000.0         10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;John Cleese    2015-06-01  65000.0          8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Eric Idle      2014-05-12  45000.0         10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Terry Jones    2013-11-01  70000.0          3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Terry Gilliam  2014-08-12  48000.0          7&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Michael Palin  2013-05-23  66000.0          8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;writing-csv-files-with-pandas&quot;&gt;Writing CSV Files With &lt;code&gt;pandas&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Of course, if you can&amp;rsquo;t get your data out of &lt;code&gt;pandas&lt;/code&gt; again, it doesn&amp;rsquo;t do you much good. Writing a &lt;code&gt;DataFrame&lt;/code&gt; to a CSV file is just as easy as reading one in. Let&amp;rsquo;s write the data with the new column names to a new CSV file:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pandas&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;hrdata.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;index_col&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Employee&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;parse_dates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hired&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;header&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Employee&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Hired&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Salary&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Sick Days&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;df&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_csv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;hrdata_modified.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The only difference between this code and the reading code above is that the &lt;code&gt;print(df)&lt;/code&gt; call was replaced with &lt;code&gt;df.to_csv()&lt;/code&gt;, providing the file name. The new CSV file looks like this:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;Employee,Hired,Salary,Sick Days&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Graham Chapman,2014-03-15,50000.0,10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;John Cleese,2015-06-01,65000.0,8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Eric Idle,2014-05-12,45000.0,10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Terry Jones,2013-11-01,70000.0,3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Terry Gilliam,2014-08-12,48000.0,7&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Michael Palin,2013-05-23,66000.0,8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If you understand the basics of reading CSV files, then you won&amp;rsquo;t ever be caught flat footed when you need to deal with importing data. Most CSV reading, processing, and writing tasks can be easily handled by the basic &lt;code&gt;csv&lt;/code&gt; Python library. If you have a lot of data to read and process, the &lt;code&gt;pandas&lt;/code&gt; library provides quick and easy CSV handling capabilities as well.&lt;/p&gt;
&lt;p&gt;Are there other ways to parse text files? Of course! Libraries like &lt;a href=&quot;http://www.antlr.org/&quot;&gt;ANTLR&lt;/a&gt;, &lt;a href=&quot;http://www.dabeaz.com/ply/&quot;&gt;PLY&lt;/a&gt;, and &lt;a href=&quot;https://pypi.org/project/PlyPlus/&quot;&gt;PlyPlus&lt;/a&gt; can all handle heavy-duty parsing, and if simple &lt;code&gt;String&lt;/code&gt; manipulation won&amp;rsquo;t work, there are always regular expressions.&lt;/p&gt;
&lt;p&gt;But those are topics for other articles&amp;hellip;&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Generating Random Data in Python (Guide)</title>
      <id>https://realpython.com/python-random/</id>
      <link href="https://realpython.com/python-random/"/>
      <updated>2018-07-11T14:00:00+00:00</updated>
      <summary>You&#39;ll cover a handful of different options for generating random data in Python, and then build up to a comparison of each in terms of its level of security, versatility, purpose, and speed.</summary>
      <content type="html">
        &lt;p&gt;How random is random?  This is a weird question to ask, but it is one of paramount importance in cases where information security is concerned.  Whenever you&amp;rsquo;re generating random data, strings, or numbers in Python, it&amp;rsquo;s a good idea to have at least a rough idea of how that data was generated.&lt;/p&gt;
&lt;p&gt;Here, you&amp;rsquo;ll cover a handful of different options for generating random data in Python, and then build up to a comparison of each in terms of its level of security, versatility, purpose, and speed.&lt;/p&gt;
&lt;p&gt;I promise that this tutorial will not be a lesson in mathematics or cryptography, which I wouldn&amp;rsquo;t be well equipped to lecture on in the first place.  You&amp;rsquo;ll get into just as much math as needed, and no more.&lt;/p&gt;
&lt;h2 id=&quot;how-random-is-random&quot;&gt;How Random Is Random?&lt;/h2&gt;
&lt;p&gt;First, a prominent disclaimer is necessary.  Most random data generated with Python is not fully random in the scientific sense of the word.  Rather, it is &lt;strong&gt;pseudorandom&lt;/strong&gt;: generated with a pseudorandom number generator (PRNG), which is essentially any algorithm for generating seemingly random but still reproducible data.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;True&amp;rdquo; random numbers can be generated by, you guessed it, a true random number generator (TRNG).  One example is to repeatedly pick up a die off the floor, toss it in the air, and let it land how it may.&lt;/p&gt;
&lt;p&gt;Assuming that your toss is unbiased, you have truly no idea what number the die will land on.  Rolling a die is a crude form of using hardware to generate a number that is not deterministic whatsoever.  (Or, you can have the &lt;a href=&quot;https://hackaday.com/2009/05/26/dice-o-matic/&quot;&gt;dice-o-matic&lt;/a&gt; do this for you.)  TRNGs are out of the scope of this article but worth a mention nonetheless for comparison&amp;rsquo;s sake.&lt;/p&gt;
&lt;p&gt;PRNGs, usually done with software rather than hardware, work slightly differently.  Here&amp;rsquo;s a concise description:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;They start with a random number, known as the seed, and then use an algorithm to generate a pseudo-random sequence of bits based on it.  &lt;a href=&quot;https://bit.ly/2dUfzGb&quot;&gt;(Source)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You&amp;rsquo;ve likely been told to &amp;ldquo;read the docs!&amp;rdquo; at some point.  Well, those people are not wrong.  Here&amp;rsquo;s a particularly notable snippet from the &lt;code&gt;random&lt;/code&gt; module&amp;rsquo;s documentation that you don&amp;rsquo;t want to miss:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: The pseudo-random generators of this module should not be used for security purposes. &lt;a href=&quot;https://docs.python.org/3/library/random.html&quot;&gt;(Source)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You&amp;rsquo;ve probably seen &lt;code&gt;random.seed(999)&lt;/code&gt;, &lt;code&gt;random.seed(1234)&lt;/code&gt;, or the like, in Python.  This function call is seeding the underlying random number generator used by Python&amp;rsquo;s &lt;code&gt;random&lt;/code&gt; module. It is what makes subsequent calls to generate random numbers deterministic: input A always produces output B.  This blessing can also be a curse if it is used maliciously.  &lt;/p&gt;
&lt;p&gt;Perhaps the terms &amp;ldquo;random&amp;rdquo; and &amp;ldquo;deterministic&amp;rdquo; seem like they cannot exist next to each other.  To make that clearer, here&amp;rsquo;s an extremely trimmed down version of &lt;code&gt;random()&lt;/code&gt; that iteratively creates a &amp;ldquo;random&amp;rdquo; number by using &lt;code&gt;x = (x * 3) % 19&lt;/code&gt;.  &lt;code&gt;x&lt;/code&gt; is originally defined as a seed value and then morphs into a deterministic sequence of numbers based on that seed:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NotSoRandom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Seed the world&amp;#39;s most mysterious random number generator.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seedval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Look, random numbers!&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seedval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seedval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seedval&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;_inst&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NotSoRandom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_inst&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_inst&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Don&amp;rsquo;t take this example too literally, as it&amp;rsquo;s meant mainly to illustrate the concept.  If you use the seed value 1234, the subsequent sequence of calls to &lt;code&gt;random()&lt;/code&gt; should always be identical:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1234&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1234&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[16, 10, 11, 14, 4, 12, 17, 13, 1, 3]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You&amp;rsquo;ll see a more serious illustration of this shortly.&lt;/p&gt;
&lt;h2 id=&quot;what-is-cryptographically-secure&quot;&gt;What Is &amp;ldquo;Cryptographically Secure?&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;If you haven&amp;rsquo;t had enough with the &amp;ldquo;RNG&amp;rdquo; acronyms, let&amp;rsquo;s throw one more into the mix: a CSPRNG, or cryptographically secure PRNG.  CSPRNGs are suitable for generating sensitive data such as passwords, authenticators, and tokens.  Given a random string, there is realistically no way for Malicious Joe to determine what string came before or after that string in a sequence of random strings.&lt;/p&gt;
&lt;p&gt;One other term that you may see is &lt;strong&gt;entropy&lt;/strong&gt;.  In a nutshell, this refers to the amount of randomness introduced or desired.  For example, one Python &lt;a href=&quot;https://github.com/python/cpython/blob/78392885c9b08021c89649728053d31503d8a509/Lib/secrets.py#L33&quot;&gt;module&lt;/a&gt; that you&amp;rsquo;ll cover here defines &lt;code&gt;DEFAULT_ENTROPY = 32&lt;/code&gt;, the number of bytes to return by default.  The developers deem this to be &amp;ldquo;enough&amp;rdquo; bytes to be a sufficient amount of noise.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Through this tutorial, I assume that a byte refers to 8 bits, as it has since the 1960s, rather than some other unit of data storage.  You are free to call this an &lt;a href=&quot;https://en.wikipedia.org/wiki/Octet_(computing)&quot;&gt;&lt;em&gt;octet&lt;/em&gt;&lt;/a&gt; if you so prefer.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;A key point about CSPRNGs is that they are still pseudorandom.  They are engineered in some way that is internally deterministic, but they add some other variable or have some property that makes them &amp;ldquo;random enough&amp;rdquo; to prohibit backing into whatever function enforces determinism.&lt;/p&gt;
&lt;h2 id=&quot;what-youll-cover-here&quot;&gt;What You&amp;rsquo;ll Cover Here&lt;/h2&gt;
&lt;p&gt;In practical terms, this means that you should use plain PRNGs for statistical modeling, simulation, and to make random data reproducible.  They&amp;rsquo;re also significantly faster than CSPRNGs, as you&amp;rsquo;ll see later on.  Use CSPRNGs for security and cryptographic applications where data sensitivity is imperative.&lt;/p&gt;
&lt;p&gt;In addition to expanding on the use cases above, in this tutorial, you&amp;rsquo;ll delve into Python tools for using both PRNGs and CSPRNGs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PRNG options include the &lt;code&gt;random&lt;/code&gt; module from Python&amp;rsquo;s standard library and its array-based NumPy counterpart, &lt;code&gt;numpy.random&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Python&amp;rsquo;s &lt;code&gt;os&lt;/code&gt;, &lt;code&gt;secrets&lt;/code&gt;, and &lt;code&gt;uuid&lt;/code&gt; modules contain functions for generating cryptographically secure objects.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You&amp;rsquo;ll touch on all of the above and wrap up with a high-level comparison.&lt;/p&gt;
&lt;h2 id=&quot;prngs-in-python&quot;&gt;PRNGs in Python&lt;/h2&gt;
&lt;h3 id=&quot;the-random-module&quot;&gt;The &lt;code&gt;random&lt;/code&gt; Module&lt;/h3&gt;
&lt;p&gt;Probably the most widely known tool for generating random data in Python is its &lt;code&gt;random&lt;/code&gt; module, which uses the &lt;a href=&quot;https://github.com/python/cpython/blob/master/Modules/_randommodule.c&quot;&gt;Mersenne Twister&lt;/a&gt; PRNG algorithm as its core generator.&lt;/p&gt;
&lt;p&gt;Earlier, you touched briefly on &lt;code&gt;random.seed()&lt;/code&gt;, and now is a good time to see how it works.  First, let&amp;rsquo;s build some random data without seeding.  The &lt;code&gt;random.random()&lt;/code&gt; function returns a random float in the interval [0.0, 1.0). The result will always be less than the right-hand endpoint (1.0). This is also known as a semi-open range:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Don&amp;#39;t call `random.seed()` yet&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.35553263284394376&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.6101992345575074&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you run this code yourself, I&amp;rsquo;ll bet my life savings that the numbers returned on your machine will be different.  The &lt;a href=&quot;https://github.com/python/cpython/blob/78392885c9b08021c89649728053d31503d8a509/Lib/random.py#L93&quot;&gt;default&lt;/a&gt; when you don&amp;rsquo;t seed the generator is to use your current system time or a &amp;ldquo;randomness source&amp;rdquo; from your OS if one is available.&lt;/p&gt;
&lt;p&gt;With &lt;code&gt;random.seed()&lt;/code&gt;, you can make results reproducible, and the chain of calls after &lt;code&gt;random.seed()&lt;/code&gt; will produce the same trail of data:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;444&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.3088946587429545&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.01323751590501987&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;444&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Re-seed&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.3088946587429545&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.01323751590501987&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice the repetition of &amp;ldquo;random&amp;rdquo; numbers.  The sequence of random numbers becomes deterministic, or completely determined by the seed value, 444.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at some more basic functionality of &lt;code&gt;random&lt;/code&gt;.  Above, you generated a random float.  You can generate a random integer between two endpoints in Python with the &lt;code&gt;random.randint()&lt;/code&gt; function. This spans the full [x, y] interval and may include both endpoints:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;18601&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With &lt;code&gt;random.randrange()&lt;/code&gt;, you can exclude the right-hand side of the interval, meaning the generated number always lies within [x, y) and will always be smaller than the right endpoint:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randrange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you need to generate random floats that lie within a specific [x, y] interval, you can use &lt;code&gt;random.uniform()&lt;/code&gt;, which plucks from the &lt;a href=&quot;https://en.wikipedia.org/wiki/continuous_uniform_distribution&quot;&gt;continuous uniform distribution&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uniform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;27.42639687016509&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uniform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;36.33865802745107&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To pick a random element from a non-empty sequence (like a list or a tuple), you can use &lt;code&gt;random.choice()&lt;/code&gt;.  There is also &lt;code&gt;random.choices()&lt;/code&gt; for choosing multiple elements from a sequence with replacement (duplicates are possible):&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;items&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;one&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;two&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;three&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;four&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;five&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;s1&quot;&gt;&amp;#39;four&amp;#39;&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;three&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;three&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;three&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;five&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;four&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To mimic sampling without replacement, use &lt;code&gt;random.sample()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sample&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;one&amp;#39;, &amp;#39;five&amp;#39;, &amp;#39;four&amp;#39;, &amp;#39;three&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can randomize a sequence in-place using &lt;code&gt;random.shuffle()&lt;/code&gt;. This will modify the sequence object and randomize the order of elements:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;four&amp;#39;, &amp;#39;three&amp;#39;, &amp;#39;two&amp;#39;, &amp;#39;one&amp;#39;, &amp;#39;five&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you’d rather not mutate the original list, you’ll need to &lt;a href=&quot;https://realpython.com/copying-python-objects/&quot;&gt;make a copy first&lt;/a&gt; and then shuffle the copy. You can create copies of Python lists with the &lt;a href=&quot;https://docs.python.org/library/copy.html&quot;&gt;&lt;code&gt;copy&lt;/code&gt;&lt;/a&gt; module, or just &lt;code&gt;x[:]&lt;/code&gt; or &lt;code&gt;x.copy()&lt;/code&gt;, where &lt;code&gt;x&lt;/code&gt; is the list.&lt;/p&gt;
&lt;p&gt;Before moving on to generating random data with NumPy, let&amp;rsquo;s look at one more slightly involved application: generating a sequence of unique random strings of uniform length.&lt;/p&gt;
&lt;p&gt;It can help to think about the design of the function first.  You need to choose from a &amp;ldquo;pool&amp;rdquo; of characters such as letters, numbers, and/or punctuation, combine these into a single string, and then check that this string has not already been generated.  A Python &lt;code&gt;set&lt;/code&gt; works well for this type of membership testing:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;string&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;unique_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ntokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
               &lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ascii_letters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Generate a set of unique string tokens.&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    k: Length of each token&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    ntokens: Number of tokens&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    pool: Iterable of characters to choose from&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    For a highly optimized version:&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    https://stackoverflow.com/a/48421303/7954504&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;seen&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# An optimization for tightly-bound loops:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Bind these methods outside of a loop&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seen&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ntokens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seen&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;&#39;&#39;.join()&lt;/code&gt; joins the letters from &lt;code&gt;random.choices()&lt;/code&gt; into a single Python &lt;code&gt;str&lt;/code&gt; of length &lt;code&gt;k&lt;/code&gt;.  This token is added to the set, which can&amp;rsquo;t contain duplicates, and the &lt;code&gt;while&lt;/code&gt; loop executes until the set has the number of elements that you specify.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Resource&lt;/strong&gt;: Python&amp;rsquo;s &lt;a href=&quot;https://docs.python.org/3/library/string.html&quot;&gt;&lt;code&gt;string&lt;/code&gt;&lt;/a&gt; module contains a number of useful constants: &lt;code&gt;ascii_lowercase&lt;/code&gt;, &lt;code&gt;ascii_uppercase&lt;/code&gt;, &lt;code&gt;string.punctuation&lt;/code&gt;, &lt;code&gt;ascii_whitespace&lt;/code&gt;, and a handful of others.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Let&amp;rsquo;s try this function out:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ntokens&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;#39;AsMk&amp;#39;, &amp;#39;Cvmi&amp;#39;, &amp;#39;GIxv&amp;#39;, &amp;#39;HGsZ&amp;#39;, &amp;#39;eurU&amp;#39;}&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_strings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;printable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;quot;&amp;#39;O*1!&amp;quot;, &amp;#39;9Ien%&amp;#39;, &amp;#39;W=m7&amp;lt;&amp;#39;, &amp;#39;mUD|z&amp;#39;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For a fine-tuned version of this function, &lt;a href=&quot;https://stackoverflow.com/a/48421303/7954504&quot;&gt;this Stack Overflow answer&lt;/a&gt; uses generator functions, name binding, and some other advanced tricks to make a faster, cryptographically secure version of &lt;code&gt;unique_strings()&lt;/code&gt; above.&lt;/p&gt;
&lt;h3 id=&quot;prngs-for-arrays-numpyrandom&quot;&gt;PRNGs for Arrays: &lt;code&gt;numpy.random&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;One thing you might have noticed is that a majority of the functions from &lt;code&gt;random&lt;/code&gt; return a scalar value (a single &lt;code&gt;int&lt;/code&gt;, &lt;code&gt;float&lt;/code&gt;, or other object).  If you wanted to generate a sequence of random numbers, one way to achieve that would be with a Python list comprehension:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[0.021655420657909374,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; 0.4031628347066195,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; 0.6609991871223335,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; 0.5854998250783767,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; 0.42886606317322706]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But there is another option that is specifically designed for this.  You can think of NumPy&amp;rsquo;s own &lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/routines.random.html&quot;&gt;&lt;code&gt;numpy.random&lt;/code&gt;&lt;/a&gt; package as being like the standard library&amp;rsquo;s &lt;code&gt;random&lt;/code&gt;, but for &lt;a href=&quot;https://realpython.com/numpy-array-programming/&quot;&gt;NumPy arrays&lt;/a&gt;.  (It also comes loaded with the ability to draw from a lot more statistical distributions.)&lt;/p&gt;
&lt;p&gt;Take note that &lt;code&gt;numpy.random&lt;/code&gt; uses its own PRNG that is separate from plain old &lt;code&gt;random&lt;/code&gt;.  You won&amp;rsquo;t produce deterministically random NumPy arrays with a call to Python&amp;rsquo;s own &lt;code&gt;random.seed()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;np&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;444&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_printoptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;precision&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Output decimal fmt.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Without further ado, here are a few examples to whet your appetite:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Return samples from the standard normal distribution&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([ 0.36,  0.38,  1.38,  1.18, -0.94])&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([[-1.14, -0.54, -0.55,  0.21],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [ 0.21,  1.27, -0.81, -3.3 ],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [-0.81, -0.36, -0.88,  0.15]])&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# `p` is the probability of choosing each element&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([[0, 0, 1, 0],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [0, 1, 1, 1],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [1, 1, 1, 0],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [0, 0, 0, 1],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [0, 1, 0, 1]])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the syntax for &lt;code&gt;randn(d0, d1, ..., dn)&lt;/code&gt;, the parameters &lt;code&gt;d0, d1, ..., dn&lt;/code&gt; are optional and indicate the shape of the final object.  Here, &lt;code&gt;np.random.randn(3, 4)&lt;/code&gt; creates a 2d array with 3 rows and 4 columns.  The data will be &lt;a href=&quot;https://en.wikipedia.org/wiki/Independent_and_identically_distributed_random_variables&quot;&gt;i.i.d.&lt;/a&gt;, meaning that each data point is drawn independent of the others.&lt;/p&gt;
&lt;p&gt;Another common operation is to create a sequence of random Boolean values, &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;.  One way to do this would be with &lt;code&gt;np.random.choice([True, False])&lt;/code&gt;.  However, it&amp;rsquo;s actually about 4x faster to choose from &lt;code&gt;(0, 1)&lt;/code&gt; and then &lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.view.html&quot;&gt;view-cast&lt;/a&gt; these integers to their corresponding Boolean values:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# NumPy&amp;#39;s `randint` is [inclusive, exclusive), unlike `random.randint()`&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uint8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([ True, False,  True,  True, False,  True, False, False, False,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       False, False,  True,  True, False, False, False,  True, False,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;        True, False,  True,  True,  True, False,  True])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What about generating correlated data?  Let&amp;rsquo;s say you want to simulate two correlated time series.  One way of going about this is with NumPy&amp;rsquo;s &lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.multivariate_normal.html#numpy.random.multivariate_normal&quot;&gt;&lt;code&gt;multivariate_normal()&lt;/code&gt;&lt;/a&gt; function, which takes a covariance matrix into account.  In other words, to draw from a single normally distributed random variable, you need to specify its mean and variance (or standard deviation).&lt;/p&gt;
&lt;p&gt;To sample from the &lt;a href=&quot;https://en.wikipedia.org/wiki/Multivariate_normal&quot;&gt;multivariate normal&lt;/a&gt; distribution, you specify the means and covariance matrix, and you end up with  multiple, correlated series of data that are each approximately normally distributed.&lt;/p&gt;
&lt;p&gt;However, rather than covariance, &lt;a href=&quot;https://en.wikipedia.org/wiki/correlation&quot;&gt;correlation&lt;/a&gt; is a measure that is more familiar and intuitive to most.  It&amp;rsquo;s the covariance normalized by the product of standard deviations, and so you can also define covariance in terms of correlation and standard deviation:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/scalar_equation.2ef9746c8834.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/scalar_equation.2ef9746c8834.jpg&quot; width=&quot;620&quot; height=&quot;88&quot; alt=&quot;Covariance in Scalar Form&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So, could you draw random samples from a multivariate normal distribution by specifying a correlation matrix and standard deviations?  Yes, but you&amp;rsquo;ll need to get the above &lt;a href=&quot;https://blogs.sas.com/content/iml/2010/12/10/converting-between-correlation-and-covariance-matrices.html&quot;&gt;into matrix form&lt;/a&gt; first.  Here, &lt;em&gt;&lt;strong&gt;S&lt;/strong&gt;&lt;/em&gt; is a vector of the standard deviations, &lt;em&gt;&lt;strong&gt;P&lt;/strong&gt;&lt;/em&gt; is their correlation matrix, and &lt;em&gt;&lt;strong&gt;C&lt;/strong&gt;&lt;/em&gt; is the resulting (square) covariance matrix:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/matrix_equation.d70f9fd73960.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/matrix_equation.d70f9fd73960.jpg&quot; width=&quot;610&quot; height=&quot;78&quot; alt=&quot;Covariance in Matrix Form&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This can be expressed in NumPy as follows:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;corr2cov&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ndarray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ndarray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ndarray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Covariance matrix from correlation &amp;amp; standard deviations&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;diag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;@&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, you can generate two time series that are correlated but still random:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Start with a correlation matrix and standard deviations.&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# -0.40 is the correlation between A and B, and the correlation&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# of a variable with itself is 1.0.&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;corr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                 &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]])&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Standard deviations/means of A and B, respectively&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdev&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;6.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cov&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;corr2cov&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;corr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stdev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# `size` is the length of time series for 2d data&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# (500 months, days, and so on).&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;multivariate_normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cov&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cov&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([[ 0.58,  1.87],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [-7.31,  0.74],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [-6.24,  0.33],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [-0.77,  1.19],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [ 1.71,  0.7 ],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [-3.33,  1.57],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [-1.13,  1.23],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [-6.58,  1.81],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [-0.82, -0.34],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [-2.32,  1.1 ]])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(500, 2)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can think of &lt;code&gt;data&lt;/code&gt; as 500 pairs of inversely correlated data points.  Here&amp;rsquo;s a sanity check that you can back into the original inputs, which approximate &lt;code&gt;corr&lt;/code&gt;, &lt;code&gt;stdev&lt;/code&gt;, and &lt;code&gt;mean&lt;/code&gt; from above:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;corrcoef&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rowvar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([[ 1.  , -0.39],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [-0.39,  1.  ]])&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([5.96, 1.01])&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([2.13, 0.49])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Before we move on to CSPRNGs, it might be helpful to summarize some &lt;code&gt;random&lt;/code&gt; functions and their &lt;code&gt;numpy.random&lt;/code&gt; counterparts:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Python &lt;code&gt;random&lt;/code&gt; Module&lt;/th&gt;
&lt;th&gt;NumPy Counterpart&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;random()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.rand.html#numpy.random.rand&quot;&gt;&lt;code&gt;rand()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Random float in [0.0, 1.0)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;randint(a, b)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.random_integers.html#numpy.random.random_integers&quot;&gt;&lt;code&gt;random_integers()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Random integer in [a, b]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;randrange(a, b[, step])&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.randint.html#numpy.random.randint&quot;&gt;&lt;code&gt;randint()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Random integer in [a, b)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;uniform(a, b)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.uniform.html#numpy.random.uniform&quot;&gt;&lt;code&gt;uniform()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Random float in [a, b]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;choice(seq)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.choice.html#numpy.random.choice&quot;&gt;&lt;code&gt;choice()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Random element from &lt;code&gt;seq&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;choices(seq, k=1)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.choice.html#numpy.random.choice&quot;&gt;&lt;code&gt;choice()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Random &lt;code&gt;k&lt;/code&gt; elements from &lt;code&gt;seq&lt;/code&gt; with replacement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sample(population, k)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.choice.html#numpy.random.choice&quot;&gt;&lt;code&gt;choice()&lt;/code&gt;&lt;/a&gt; with &lt;code&gt;replace=False&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Random &lt;code&gt;k&lt;/code&gt; elements from &lt;code&gt;seq&lt;/code&gt; without replacement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;shuffle(x[, random])&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html#numpy.random.shuffle&quot;&gt;&lt;code&gt;shuffle()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Shuffle the sequence &lt;code&gt;x&lt;/code&gt; in place&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;normalvariate(mu, sigma)&lt;/code&gt; or &lt;code&gt;gauss(mu, sigma)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.random.normal.html#numpy.random.normal&quot;&gt;&lt;code&gt;normal()&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Sample from a normal distribution with mean &lt;code&gt;mu&lt;/code&gt; and standard deviation &lt;code&gt;sigma&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: NumPy is specialized for building and manipulating large, multidimensional arrays.  If you just need a single value, &lt;code&gt;random&lt;/code&gt; will suffice and will probably be faster as well.  For small sequences, &lt;code&gt;random&lt;/code&gt; may even be faster too, because NumPy does come with some overhead.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Now that you&amp;rsquo;ve covered two fundamental options for PRNGs, let&amp;rsquo;s move onto a few more secure adaptations.&lt;/p&gt;
&lt;h2 id=&quot;csprngs-in-python&quot;&gt;CSPRNGs in Python&lt;/h2&gt;
&lt;h3 id=&quot;osurandom-about-as-random-as-it-gets&quot;&gt;&lt;code&gt;os.urandom()&lt;/code&gt;: About as Random as It Gets&lt;/h3&gt;
&lt;p&gt;Python&amp;rsquo;s &lt;a href=&quot;https://docs.python.org/library/os.html#os.urandom&quot;&gt;&lt;code&gt;os.urandom()&lt;/code&gt;&lt;/a&gt; function is used by both &lt;a href=&quot;https://github.com/python/cpython/blob/b225cb770fb17596298f5a05c41a7c90c470c4f8/Lib/secrets.py#L47&quot;&gt;&lt;code&gt;secrets&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://github.com/python/cpython/blob/b225cb770fb17596298f5a05c41a7c90c470c4f8/Lib/uuid.py#L621&quot;&gt;&lt;code&gt;uuid&lt;/code&gt;&lt;/a&gt; (both of which you&amp;rsquo;ll see here in a moment).  Without getting into too much detail, &lt;code&gt;os.urandom()&lt;/code&gt; generates operating-system-dependent random bytes that can safely be called cryptographically secure:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;On Unix operating systems, it reads random bytes from the special file &lt;code&gt;/dev/urandom&lt;/code&gt;, which in turn &amp;ldquo;allow access to environmental noise collected from device drivers and other sources.&amp;rdquo;  (Thank you, &lt;a href=&quot;https://en.wikipedia.org/wiki//dev/random&quot;&gt;Wikipedia&lt;/a&gt;.)  This is garbled information that is particular to your hardware and system state at an instance in time but at the same time sufficiently random.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;On Windows, the C++ function &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/windows/desktop/aa379942(v=vs.85).aspx&quot;&gt;&lt;code&gt;CryptGenRandom()&lt;/code&gt;&lt;/a&gt; is used.  This function is still technically pseudorandom, but it works by generating a seed value from variables such as the process ID, memory status, and so on.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With &lt;code&gt;os.urandom()&lt;/code&gt;, there is no concept of manually seeding. While still technically pseudorandom, this function better aligns with how we think of randomness.  The only argument is the number of &lt;a href=&quot;https://docs.python.org/library/stdtypes.html#bytes&quot;&gt;bytes&lt;/a&gt; to return:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urandom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;\xa2\xe8\x02&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urandom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;\xce\x11\xe7&amp;quot;!\x84&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(bytes, 6)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Before we go any further, this might be a good time to delve into a mini-lesson on &lt;a href=&quot;https://docs.python.org/howto/unicode.html&quot;&gt;character encoding&lt;/a&gt;.  Many people, including myself, have some type of allergic reaction when they see &lt;code&gt;bytes&lt;/code&gt; objects and a long line of &lt;code&gt;\x&lt;/code&gt; characters.  However, it&amp;rsquo;s useful to know how sequences such as &lt;code&gt;x&lt;/code&gt; above eventually get turned into strings or numbers.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;os.urandom()&lt;/code&gt; returns a sequence of single bytes:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;\xce\x11\xe7&amp;quot;!\x84&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But how does this eventually get turned into a Python &lt;code&gt;str&lt;/code&gt; or sequence of numbers?&lt;/p&gt;
&lt;p&gt;First, recall one of the fundamental concepts of computing, which is that a byte is made up of 8 bits.  You can think of a bit as a single digit that is either 0 or 1.  A byte effectively chooses between 0 and 1 eight times, so both &lt;code&gt;01101100&lt;/code&gt; and &lt;code&gt;11110000&lt;/code&gt; could represent bytes.  Try this, which makes use of Python &lt;a href=&quot;https://realpython.com/python-f-strings/&quot;&gt;f-strings&lt;/a&gt; introduced in Python 3.6, in your interpreter:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{i:0&amp;gt;8b}&amp;#39;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;00000000&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00000001&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00000010&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00000011&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00000100&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00000101&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00000110&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00000111&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00001000&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00001001&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00001010&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00001011&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00001100&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00001101&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00001110&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;00001111&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is equivalent to &lt;code&gt;[bin(i) for i in range(256)]&lt;/code&gt;, with some special formatting.  &lt;a href=&quot;https://docs.python.org/3/library/functions.html#bin&quot;&gt;&lt;code&gt;bin()&lt;/code&gt;&lt;/a&gt; converts an integer to its binary representation as a string.&lt;/p&gt;
&lt;p&gt;Where does that leave us?  Using &lt;code&gt;range(256)&lt;/code&gt; above is not a random choice. (No pun intended.)  Given that we are allowed 8 bits, each with 2 choices, there are &lt;code&gt;2 ** 8 == 256&lt;/code&gt; possible bytes &amp;ldquo;combinations.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;This means that each byte maps to an integer between 0 and 255.  In other words, we would need more than 8 bits to express the integer 256.  You can verify this by checking that &lt;code&gt;len(f&#39;{256:0&amp;gt;8b}&#39;)&lt;/code&gt; is now 9, not 8.&lt;/p&gt;
&lt;p&gt;Okay, now let&amp;rsquo;s get back to the &lt;code&gt;bytes&lt;/code&gt; data type that you saw above, by constructing a sequence of the bytes that correspond to integers 0 through 255:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bites&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you call &lt;code&gt;list(bites)&lt;/code&gt;, you&amp;rsquo;ll get back to a Python list that runs from 0 to 255.  But if you just print &lt;code&gt;bites&lt;/code&gt;, you get an ugly looking sequence littered with backslashes:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bites&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !&amp;quot;#$%&amp;amp;\&amp;#39;()*+,-./0123456789:;&amp;lt;=&amp;gt;?@ABCDEFGHIJK&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;LMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b&amp;#39;&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt; # ...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;These backslashes are escape sequences, and &lt;code&gt;\xhh&lt;/code&gt; &lt;a href=&quot;https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals&quot;&gt;represents&lt;/a&gt; the character with hex value &lt;code&gt;hh&lt;/code&gt;.  Some of the elements of &lt;code&gt;bites&lt;/code&gt; are displayed literally (printable characters such as letters, numbers, and punctuation).  Most are expressed with escapes.  &lt;code&gt;\x08&lt;/code&gt; represents a keyboard&amp;rsquo;s backspace, while &lt;code&gt;\x13&lt;/code&gt; is a &lt;a href=&quot;https://en.wikipedia.org/wiki/Carriage_return&quot;&gt;carriage return&lt;/a&gt; (part of a new line, on Windows systems).&lt;/p&gt;
&lt;p&gt;If you need a refresher on hexadecimal, Charles Petzold&amp;rsquo;s &lt;a href=&quot;https://realpython.com/asins/0735611319/&quot;&gt;&lt;em&gt;Code: The Hidden Language&lt;/em&gt;&lt;/a&gt; is a great place for that.  Hex is a base-16 numbering system that, instead of using 0 through 9, uses 0 through 9 and &lt;em&gt;a&lt;/em&gt; through &lt;em&gt;f&lt;/em&gt; as its basic digits.&lt;/p&gt;
&lt;p&gt;Finally, let&amp;rsquo;s get back to where you started, with the sequence of random bytes &lt;code&gt;x&lt;/code&gt;.  Hopefully this makes a little more sense now.  Calling &lt;code&gt;.hex()&lt;/code&gt; on a &lt;code&gt;bytes&lt;/code&gt; object gives a &lt;code&gt;str&lt;/code&gt; of hexadecimal numbers, with each corresponding to a decimal number from 0 through 255:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;\xce\x11\xe7&amp;quot;!\x84&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[206, 17, 231, 34, 33, 132]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;ce11e7222184&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;One last question: how is &lt;code&gt;b.hex()&lt;/code&gt; 12 characters long above, even though &lt;code&gt;x&lt;/code&gt; is only 6 bytes?  This is because two hexadecimal digits correspond precisely to a single byte.  The &lt;code&gt;str&lt;/code&gt; version of &lt;code&gt;bytes&lt;/code&gt; will always be twice as long as far as our eyes are concerned.&lt;/p&gt;
&lt;p&gt;Even if the byte (such as &lt;code&gt;\x01&lt;/code&gt;) does not need a full 8 bits to be represented, &lt;code&gt;b.hex()&lt;/code&gt; will always use two hex digits per byte, so the number 1 will be represented as &lt;code&gt;01&lt;/code&gt; rather than just &lt;code&gt;1&lt;/code&gt;.  Mathematically, though, both of these are the same size.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Technical Detail&lt;/strong&gt;: What you&amp;rsquo;ve mainly dissected here is how a &lt;code&gt;bytes&lt;/code&gt; object becomes a Python &lt;code&gt;str&lt;/code&gt;.  One other technicality is how &lt;code&gt;bytes&lt;/code&gt; produced by &lt;code&gt;os.urandom()&lt;/code&gt; get converted to a &lt;code&gt;float&lt;/code&gt; in the interval [0.0, 1.0), as in the &lt;a href=&quot;https://github.com/python/cpython/blob/c6040638aa1537709add895d24cdbbb9ee310fde/Lib/random.py#L676&quot;&gt;cryptographically secure version&lt;/a&gt; of &lt;code&gt;random.random()&lt;/code&gt;.  If you&amp;rsquo;re interested in exploring this further, &lt;a href=&quot;https://github.com/realpython/materials/blob/master/random-data/bytes_to_int.py&quot;&gt;this code snippet&lt;/a&gt; demonstrates how &lt;code&gt;int.from_bytes()&lt;/code&gt; makes the initial conversion to an integer, using a base-256 numbering system.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;With that under your belt, let&amp;rsquo;s touch on a recently introduced module, &lt;code&gt;secrets&lt;/code&gt;, which makes generating secure tokens much more user-friendly.&lt;/p&gt;
&lt;h3 id=&quot;pythons-best-kept-secrets&quot;&gt;Python&amp;rsquo;s Best Kept &lt;code&gt;secrets&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Introduced in Python 3.6 by &lt;a href=&quot;https://www.python.org/dev/peps/pep-0506/&quot;&gt;one of the more colorful PEPs&lt;/a&gt; out there, the &lt;code&gt;secrets&lt;/code&gt; module is intended to be the de facto Python module for generating cryptographically secure random bytes and strings.&lt;/p&gt;
&lt;p&gt;You can check out the &lt;a href=&quot;https://github.com/python/cpython/blob/3.6/Lib/secrets.py&quot;&gt;source code&lt;/a&gt; for the module, which is short and sweet at about 25 lines of code.  &lt;code&gt;secrets&lt;/code&gt; is basically a wrapper around &lt;code&gt;os.urandom()&lt;/code&gt;.  It exports just a handful of functions for generating random numbers, bytes, and strings.  Most of these examples should be fairly self-explanatory:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Generate secure tokens&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;secrets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token_bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;A\x8cz\xe1o\xf9!;\x8b\xf2\x80pJ\x8b\xd4\xd3&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;secrets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token_hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;9cb190491e01230ec4239cae643f286f&amp;#39;  &lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;secrets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;token_urlsafe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;MJoi7CknFu3YN41m88SEgQ&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Secure version of `random.choice()`&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;secrets&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;rain&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, how about a concrete example?  You&amp;rsquo;ve probably used URL shortener services like &lt;a href=&quot;https://tinyurl.com&quot;&gt;tinyurl.com&lt;/a&gt; or &lt;a href=&quot;https://bit.ly&quot;&gt;bit.ly&lt;/a&gt; that turn an unwieldy URL into something like &lt;a href=&quot;https://bit.ly/2IcCp9u&quot;&gt;https://bit.ly/2IcCp9u&lt;/a&gt;.  Most shorteners don&amp;rsquo;t do any complicated hashing from input to output; they just generate a random string, make sure that string has not already been generated previously, and then tie that back to the input URL.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s say that after taking a look at the &lt;a href=&quot;https://www.iana.org/domains/root/db&quot;&gt;Root Zone Database&lt;/a&gt;, you&amp;rsquo;ve registered the site &lt;strong&gt;short.ly&lt;/strong&gt;.  Here&amp;rsquo;s a function to get you started with your service:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# shortly.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;secrets&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token_urlsafe&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;DATABASE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;shorten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nbytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ext&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;token_urlsafe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nbytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nbytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ext&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DATABASE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shorten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nbytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nbytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DATABASE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;short.ly/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{ext}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Is this a full-fledged real illustration?  No.  I would wager that bit.ly does things in a slightly more advanced way than storing its gold mine in a global Python dictionary that is not persistent between sessions.  However, it&amp;rsquo;s roughly accurate conceptually:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39;https://realpython.com/&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s1&quot;&gt;&amp;#39;https://docs.python.org/3/howto/regex.html&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urls&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shorten&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;short.ly/p_Z4fLI&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;short.ly/fuxSyNY&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DATABASE&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;#39;p_Z4fLI&amp;#39;: &amp;#39;https://realpython.com/&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;fuxSyNY&amp;#39;: &amp;#39;https://docs.python.org/3/howto/regex.html&amp;#39;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Hold On:&lt;/strong&gt; One thing you may notice is that both of these results are of length 7 when you requested 5 bytes.  &lt;em&gt;Wait, I thought that you said the result would be twice as long?&lt;/em&gt;  Well, not exactly, in this case.  There is one more thing going on here: &lt;code&gt;token_urlsafe()&lt;/code&gt; uses base64 encoding, where each character is 6 bits of data.  (It&amp;rsquo;s 0 through 63, and corresponding characters. The characters are A-Z, a-z, 0-9, and +/.)&lt;/p&gt;
&lt;p&gt;If you originally specify a certain number of bytes &lt;code&gt;nbytes&lt;/code&gt;, the resulting length from &lt;code&gt;secrets.token_urlsafe(nbytes)&lt;/code&gt; will be &lt;code&gt;math.ceil(nbytes * 8 / 6)&lt;/code&gt;, which you can &lt;a href=&quot;https://github.com/realpython/materials/blob/master/random-data/urlsafe.py&quot;&gt;prove&lt;/a&gt; and investigate further if you&amp;rsquo;re curious.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The bottom line here is that, while &lt;code&gt;secrets&lt;/code&gt; is really just a wrapper around existing Python functions, it can be your go-to when security is your foremost concern. &lt;/p&gt;
&lt;h2 id=&quot;one-last-candidate-uuid&quot;&gt;One Last Candidate: &lt;code&gt;uuid&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;One last option for generating a random token is the &lt;code&gt;uuid4()&lt;/code&gt; function from Python&amp;rsquo;s &lt;a href=&quot;https://docs.python.org/library/uuid.html&quot;&gt;&lt;code&gt;uuid&lt;/code&gt;&lt;/a&gt; module.  A &lt;a href=&quot;https://tools.ietf.org/html/rfc4122.html&quot;&gt;UUID&lt;/a&gt; is a Universally Unique IDentifier, a 128-bit sequence (&lt;code&gt;str&lt;/code&gt; of length 32) designed to &amp;ldquo;guarantee uniqueness across space and time.&amp;rdquo;  &lt;code&gt;uuid4()&lt;/code&gt; is one of the module&amp;rsquo;s most useful functions, and this function &lt;a href=&quot;https://github.com/python/cpython/blob/78392885c9b08021c89649728053d31503d8a509/Lib/uuid.py#L623&quot;&gt;also uses &lt;code&gt;os.urandom()&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;uuid&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uuid4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;UUID(&amp;#39;3e3ef28d-3ff0-4933-9bba-e5ee91ce0e7b&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uuid4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;UUID(&amp;#39;2e115fcb-5761-4fa1-8287-19f4ee2877ac&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The nice thing is that all of &lt;code&gt;uuid&lt;/code&gt;&amp;rsquo;s functions produce an instance of the &lt;code&gt;UUID&lt;/code&gt; class, which encapsulates the ID and has properties like &lt;code&gt;.int&lt;/code&gt;, &lt;code&gt;.bytes&lt;/code&gt;, and &lt;code&gt;.hex&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tok&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uuid4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;.\xb7\x80\xfd\xbfIG\xb3\xae\x1d\xe3\x97\xee\xc5\xd5\x81&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;16&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# In bits&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;128&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;2eb780fdbf4947b3ae1de397eec5d581&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tok&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;int&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;62097294383572614195530565389543396737&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You may also have seen some other variations: &lt;code&gt;uuid1()&lt;/code&gt;, &lt;code&gt;uuid3()&lt;/code&gt;, and &lt;code&gt;uuid5()&lt;/code&gt;.  The key difference between these and &lt;code&gt;uuid4()&lt;/code&gt; is that those three functions all take some form of input and therefore don&amp;rsquo;t meet the definition of &amp;ldquo;random&amp;rdquo; to the extent that a Version 4 UUID does:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;uuid1()&lt;/code&gt; uses your machine&amp;rsquo;s host ID and current time by default.  Because of the reliance on current time down to nanosecond resolution, this version is where UUID derives the claim &amp;ldquo;guaranteed uniqueness across time.&amp;rdquo;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;uuid3()&lt;/code&gt; and &lt;code&gt;uuid5()&lt;/code&gt; both take a namespace identifier and a name.  The former uses an &lt;a href=&quot;https://en.wikipedia.org/wiki/MD5&quot;&gt;MD5&lt;/a&gt; hash and the latter uses SHA-1.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;uuid4()&lt;/code&gt;, conversely, is entirely pseudorandom (or random).  It consists of getting 16 bytes via &lt;code&gt;os.urandom()&lt;/code&gt;, converting this to a &lt;a href=&quot;https://en.wikipedia.org/wiki/Endianness&quot;&gt;big-endian&lt;/a&gt; integer, and doing a number of bitwise operations to comply with the &lt;a href=&quot;https://tools.ietf.org/html/rfc4122.html#section-4.1.1&quot;&gt;formal specification&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Hopefully, by now you have a good idea of the distinction between different &amp;ldquo;types&amp;rdquo; of random data and how to create them.  However, one other issue that might come to mind is that of collisions.&lt;/p&gt;
&lt;p&gt;In this case, a collision would simply refer to generating two matching UUIDs.  What is the chance of that?  Well, it is technically not zero, but perhaps it is close enough: there are &lt;code&gt;2 ** 128&lt;/code&gt; or 340 &lt;a href=&quot;https://en.wikipedia.org/wiki/Names_of_large_numbers&quot;&gt;undecillion&lt;/a&gt; possible &lt;code&gt;uuid4&lt;/code&gt; values.  So, I&amp;rsquo;ll leave it up to you to judge whether this is enough of a guarantee to sleep well.&lt;/p&gt;
&lt;p&gt;One common use of &lt;code&gt;uuid&lt;/code&gt; is in Django, which has a &lt;a href=&quot;https://docs.djangoproject.com/en/2.0/ref/models/fields/#uuidfield&quot;&gt;&lt;code&gt;UUIDField&lt;/code&gt;&lt;/a&gt; that is often used as a primary key in a model&amp;rsquo;s underlying relational database.&lt;/p&gt;
&lt;h2 id=&quot;why-not-just-default-to-systemrandom&quot;&gt;Why Not Just &amp;ldquo;Default to&amp;rdquo; &lt;code&gt;SystemRandom&lt;/code&gt;?&lt;/h2&gt;
&lt;p&gt;In addition to the secure modules discussed here such as &lt;code&gt;secrets&lt;/code&gt;, Python&amp;rsquo;s &lt;code&gt;random&lt;/code&gt; module actually has a little-used class called &lt;a href=&quot;https://github.com/python/cpython/blob/b225cb770fb17596298f5a05c41a7c90c470c4f8/Lib/random.py#L666&quot;&gt;&lt;code&gt;SystemRandom&lt;/code&gt;&lt;/a&gt; that uses &lt;code&gt;os.urandom()&lt;/code&gt;.  (&lt;code&gt;SystemRandom&lt;/code&gt;, in turn, is also used by &lt;code&gt;secrets&lt;/code&gt;.  It&amp;rsquo;s all a bit of a web that traces back to &lt;code&gt;urandom()&lt;/code&gt;.)&lt;/p&gt;
&lt;p&gt;At this point, you might be asking yourself why you wouldn&amp;rsquo;t just &amp;ldquo;default to&amp;rdquo; this version?  Why not &amp;ldquo;always be safe&amp;rdquo; rather than defaulting to the deterministic &lt;code&gt;random&lt;/code&gt; functions that aren&amp;rsquo;t cryptographically secure ?&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve already mentioned one reason: sometimes you want your data to be deterministic and reproducible for others to follow along with.&lt;/p&gt;
&lt;p&gt;But the second reason is that CSPRNGs, at least in Python, tend to be meaningfully slower than PRNGs.  Let&amp;rsquo;s test that with a script, &lt;a href=&quot;https://github.com/realpython/materials/blob/master/random-data/timed.py&quot;&gt;&lt;code&gt;timed.py&lt;/code&gt;&lt;/a&gt;, that compares the PRNG and CSPRNG versions of &lt;code&gt;randint()&lt;/code&gt; using Python&amp;rsquo;s &lt;code&gt;timeit.repeat()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# timed.py&lt;/span&gt;

&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;timeit&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# The &amp;quot;default&amp;quot; random is actually an instance of `random.Random()`.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# The CSPRNG version uses `SystemRandom()` and `os.urandom()` in turn.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;_sysrand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SystemRandom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;prng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;95&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;csprng&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_sysrand&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;95&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;import random; from __main__ import prng, csprng&amp;#39;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Best of 3 trials with 1,000,000 loops per trial:&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;prng()&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;csprng()&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;best&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timeit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:8s}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{:0.2f}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; seconds total time.&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;best&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now to execute this from the shell:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3 ./timed.py
&lt;span class=&quot;go&quot;&gt;Best of 3 trials with 1,000,000 loops per trial:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;        prng()   1.07 seconds total time.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;        csprng() 6.20 seconds total time.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A 5x timing difference is certainly a valid consideration in addition to cryptographic security when choosing between the two.&lt;/p&gt;
&lt;h2 id=&quot;odds-and-ends-hashing&quot;&gt;Odds and Ends: Hashing&lt;/h2&gt;
&lt;p&gt;One concept that hasn&amp;rsquo;t received much attention in this tutorial is that of &lt;a href=&quot;https://en.wikipedia.org/wiki/Cryptographic_hash_function&quot;&gt;hashing&lt;/a&gt;, which can be done with Python&amp;rsquo;s &lt;a href=&quot;https://docs.python.org/3/library/hashlib.html&quot;&gt;&lt;code&gt;hashlib&lt;/code&gt;&lt;/a&gt; module.&lt;/p&gt;
&lt;p&gt;A hash is designed to be a one-way mapping from an input value to a fixed-size string that is virtually impossible to reverse engineer.  As such, while the result of a hash function may &amp;ldquo;look like&amp;rdquo; random data, it doesn&amp;rsquo;t really qualify under the definition here.&lt;/p&gt;
&lt;h2 id=&quot;recap&quot;&gt;Recap&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ve covered a lot of ground in this tutorial.  To recap, here is a high-level comparison of the options available to you for engineering randomness in Python:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Package/Module&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Cryptographically Secure&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.python.org/library/random.html&quot;&gt;&lt;code&gt;random&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Fasty &amp;amp; easy random data using Mersenne Twister&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/routines.random.html&quot;&gt;&lt;code&gt;numpy.random&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Like &lt;code&gt;random&lt;/code&gt; but for (possibly multidimensional) arrays&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.python.org/library/os.html&quot;&gt;&lt;code&gt;os&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Contains &lt;code&gt;urandom()&lt;/code&gt;, the base of other functions covered here&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.python.org/library/secrets.html&quot;&gt;&lt;code&gt;secrets&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Designed to be Python&amp;rsquo;s de facto module for generating secure random numbers, bytes, and strings&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.python.org/library/uuid.html&quot;&gt;&lt;code&gt;uuid&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Home to a handful of functions for building 128-bit identifiers&lt;/td&gt;
&lt;td&gt;Yes, &lt;code&gt;uuid4()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Feel free to leave some totally random comments below, and thanks for reading.&lt;/p&gt;
&lt;h2 id=&quot;additional-links&quot;&gt;Additional Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.random.org/&quot;&gt;Random.org&lt;/a&gt; offers &amp;ldquo;true random numbers to anyone on the Internet&amp;rdquo; derived from atmospheric noise.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;https://docs.python.org/3.6/library/random.html#examples-and-recipes&quot;&gt;Recipes&lt;/a&gt; section from the &lt;code&gt;random&lt;/code&gt; module has some additional tricks.&lt;/li&gt;
&lt;li&gt;The seminal paper on the &lt;a href=&quot;http://www.math.sci.hiroshima-u.ac.jp/%7Em-mat/MT/ARTICLES/mt.pdf&quot;&gt;Mersienne Twister&lt;/a&gt; appeared in 1997, if you&amp;rsquo;re into that kind of thing.&lt;/li&gt;
&lt;li&gt;The &lt;a href=&quot;https://docs.python.org/3.6/library/itertools.html#itertools-recipes&quot;&gt;Itertools Recipes&lt;/a&gt; define functions for choosing randomly from a combinatoric set, such as from combinations or permutations.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://scikit-learn.org/stable/datasets/index.html#sample-generators&quot;&gt;Scikit-Learn&lt;/a&gt; includes various random sample generators that can be used to build artificial datasets of controlled size and complexity.&lt;/li&gt;
&lt;li&gt;Eli Bendersky digs into &lt;code&gt;random.randint()&lt;/code&gt; in his article &lt;a href=&quot;https://eli.thegreenplace.net/2018/slow-and-fast-methods-for-generating-random-integers-in-python/#id2&quot;&gt;Slow and Fast Methods for Generating Random Integers in Python&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Peter Norvig&amp;rsquo;s a &lt;a href=&quot;http://nbviewer.jupyter.org/url/norvig.com/ipython/Probability.ipynb&quot;&gt;Concrete Introduction to Probability using Python&lt;/a&gt; is a comprehensive resource as well.&lt;/li&gt;
&lt;li&gt;The Pandas library includes a &lt;a href=&quot;https://github.com/pandas-dev/pandas/blob/f9cc39fb1391cb05f55232367f6547ff9ea615b8/pandas/util/testing.py#L2513&quot;&gt;context manager&lt;/a&gt; that can be used to set a temporary random state.&lt;/li&gt;
&lt;li&gt;From Stack Overflow:&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/q/50559078/7954504&quot;&gt;Generating Random Dates In a Given Range&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/q/48421142/7954504&quot;&gt;Fastest Way to Generate a Random-like Unique String with Random Length&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/q/21187131/7954504&quot;&gt;How to Use &lt;code&gt;random.shuffle()&lt;/code&gt; on a Generator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/q/31389481/7954504&quot;&gt;Replace Random Elements in a NumPy Array&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/q/14720799/7954504&quot;&gt;Getting Numbers from /dev/random in Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Strings and Character Data in Python</title>
      <id>https://realpython.com/python-strings/</id>
      <link href="https://realpython.com/python-strings/"/>
      <updated>2018-07-09T14:00:00+00:00</updated>
      <summary>In this tutorial you&#39;ll learn how to use Python&#39;s rich set of operators, functions, and methods for working with strings. You&#39;ll learn how to access and extract portions of strings, and also become familiar with the methods that are available to manipulate and modify string data in Python 3.</summary>
      <content type="html">
        &lt;p&gt;In the tutorial on &lt;a href=&quot;https://realpython.com/python-data-types/&quot;&gt;Basic Data Types in Python&lt;/a&gt;, you learned how to define &lt;strong&gt;strings:&lt;/strong&gt; objects that contain sequences of character data.  Processing character data is integral to programming.  It is a rare application that doesn&amp;rsquo;t need to manipulate strings at least to some extent.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Here&amp;rsquo;s what you&amp;rsquo;ll learn in this tutorial:&lt;/strong&gt; Python provides a rich set of operators, functions, and methods for working with strings. When you are finished with this tutorial, you will know how to access and extract portions of strings, and also be familiar with the methods that are available to manipulate and modify string data.&lt;/p&gt;
&lt;p&gt;You will also be introduced to two other Python objects used to represent raw byte data, the &lt;code&gt;bytes&lt;/code&gt; and &lt;code&gt;bytearray&lt;/code&gt; types.&lt;/p&gt;
&lt;h2 id=&quot;string-manipulation&quot;&gt;String Manipulation&lt;/h2&gt;
&lt;p&gt;The sections below highlight the operators, methods, and functions that are available for working with strings.&lt;/p&gt;
&lt;h3 id=&quot;string-operators&quot;&gt;String Operators&lt;/h3&gt;
&lt;p&gt;You have already seen the operators &lt;code&gt;+&lt;/code&gt; and &lt;code&gt;*&lt;/code&gt; applied to numeric operands in the tutorial on &lt;a href=&quot;https://realpython.com/python-operators-expressions/&quot;&gt;Operators and Expressions in Python&lt;/a&gt;.  These two operators can be applied to strings as well.&lt;/p&gt;
&lt;h4 id=&quot;the-operator&quot;&gt;The &lt;code&gt;+&lt;/code&gt; Operator&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;+&lt;/code&gt; operator concatenates strings.  It returns a string consisting of the operands joined together, as shown here:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;u&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foobarbaz&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Go team&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;!!!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Go team!!!&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;the-operator_1&quot;&gt;The &lt;code&gt;*&lt;/code&gt; Operator&lt;/h4&gt;
&lt;p&gt;The &lt;code&gt;*&lt;/code&gt; operator creates multiple copies of a string.  If &lt;code&gt;s&lt;/code&gt; is a string and &lt;code&gt;n&lt;/code&gt; is an integer, either of the following expressions returns a string consisting of &lt;code&gt;n&lt;/code&gt; concatenated copies of &lt;code&gt;s&lt;/code&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;s * n&lt;/code&gt;&lt;br&gt;
&lt;code&gt;n * s&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here are examples of both forms:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo.&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo.foo.foo.foo.&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo.foo.foo.foo.&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The multiplier operand &lt;code&gt;n&lt;/code&gt; must be an integer.  You&amp;rsquo;d think it would be required to be a positive integer, but amusingly, it can be zero or negative, in which case the result is an empty string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you were to create a string variable and initialize it to the empty string by assigning it the value &lt;code&gt;&#39;foo&#39; * -8&lt;/code&gt;, anyone would rightly think you were a bit daft. But it would work.&lt;/p&gt;
&lt;h4 id=&quot;the-in-operator&quot;&gt;The &lt;code&gt;in&lt;/code&gt; Operator&lt;/h4&gt;
&lt;p&gt;Python also provides a membership operator that can be used with strings.  The &lt;code&gt;in&lt;/code&gt; operator returns &lt;code&gt;True&lt;/code&gt; if the first operand is contained within the second, and &lt;code&gt;False&lt;/code&gt; otherwise:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;That&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;s food for thought.&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;That&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;s good for now.&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There is also a &lt;code&gt;not in&lt;/code&gt; operator, which does the opposite:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;z&amp;#39;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;abc&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;z&amp;#39;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;xyz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;built-in-string-functions&quot;&gt;Built-in String Functions&lt;/h3&gt;
&lt;p&gt;As you saw in the tutorial on &lt;a href=&quot;https://realpython.com/python-data-types/&quot;&gt;Basic Data Types in Python&lt;/a&gt;, Python provides many functions that are built-in to the interpreter and always available.  Here are a few that work with strings:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chr()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Converts an integer to a character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ord()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Converts a character to an integer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;len()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the length of a string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;str()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a string representation of an object&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;These are explored more fully below.&lt;/p&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;ord(c)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Returns an integer value for the given character.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At the most basic level, computers store all information as numbers.  To represent character data, a translation scheme is used which maps each character to its representative number.&lt;/p&gt;
&lt;p&gt;The simplest scheme in common use is called &lt;a href=&quot;https://en.wikipedia.org/wiki/ASCII&quot;&gt;ASCII&lt;/a&gt;. It covers the common Latin characters you are probably most accustomed to working with.  For these characters, &lt;code&gt;ord(c)&lt;/code&gt; returns the ASCII value for character &lt;code&gt;c&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;97&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;#&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;35&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;ASCII is fine as far as it goes.  But there are many different languages in use in the world and countless symbols and glyphs that appear in digital media.  The full set of characters that potentially may need to be represented in computer code far surpasses the ordinary Latin letters, numbers, and symbols you usually see.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.unicode.org/standard/WhatIsUnicode.html&quot;&gt;Unicode&lt;/a&gt; is an ambitious standard that attempts to provide a numeric code for every possible character, in every possible language, on every possible platform.  Python 3 supports Unicode extensively, including allowing Unicode characters within strings.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;For More Information:&lt;/strong&gt; See &lt;a href=&quot;https://docs.python.org/3/howto/unicode.html#python-s-unicode-support&quot;&gt;Python&amp;rsquo;s Unicode Support&lt;/a&gt; in the Python documentation.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;As long as you stay in the domain of the common characters, there is little practical difference between ASCII and Unicode.  But the &lt;code&gt;ord()&lt;/code&gt; function will return numeric values for Unicode characters as well:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;€&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;8364&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ord&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;∑&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;8721&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;chr(n)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Returns a character value for the given integer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;chr()&lt;/code&gt; does the reverse of &lt;code&gt;ord()&lt;/code&gt;.  Given a numeric value &lt;code&gt;n&lt;/code&gt;, &lt;code&gt;chr(n)&lt;/code&gt; returns a string representing the character that corresponds to &lt;code&gt;n&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;97&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;#&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;chr()&lt;/code&gt; handles Unicode characters as well:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8364&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;€&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8721&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;∑&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;len(s)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Returns the length of a string.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;len(s)&lt;/code&gt; returns the number of characters in &lt;code&gt;s&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;I am a string.&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;14&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;str(obj)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Returns a string representation of an object.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Virtually any object in Python can be rendered as a string.  &lt;code&gt;str(obj)&lt;/code&gt; returns the string representation of object &lt;code&gt;obj&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;49.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;49.2&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;(3+4j)&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;29&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;32&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;string-indexing&quot;&gt;String Indexing&lt;/h3&gt;
&lt;p&gt;Often in programming languages, individual items in an ordered set of data can be accessed directly using a numeric index or key value.  This process is referred to as indexing.&lt;/p&gt;
&lt;p&gt;In Python, strings are ordered sequences of character data, and thus can be indexed in this way.  Individual characters in a string can be accessed by specifying the string name followed by a number in square brackets (&lt;code&gt;[]&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;String indexing in Python is zero-based: the first character in the string has index &lt;code&gt;0&lt;/code&gt;, the next has index &lt;code&gt;1&lt;/code&gt;, and so on. The index of the last character will be the length of the string minus one.&lt;/p&gt;
&lt;p&gt;For example, a schematic diagram of the indices of the string &lt;code&gt;&#39;foobar&#39;&lt;/code&gt; would look like this:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.f398a9e25af0.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/t.f398a9e25af0.png&quot; width=&quot;1086&quot; height=&quot;282&quot; alt=&quot;String index 1&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;String Indices&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;The individual characters can be accessed by index as follows:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;f&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;o&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Attempting to index beyond the end of the string results in an error:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#17&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;IndexError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;string index out of range&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;String indices can also be specified with negative numbers, in which case indexing occurs from the end of the string backward: &lt;code&gt;-1&lt;/code&gt; refers to the last character, &lt;code&gt;-2&lt;/code&gt; the second-to-last character, and so on.  Here is the same diagram showing both the positive and negative indices into the string &lt;code&gt;&#39;foobar&#39;&lt;/code&gt;:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.5089888b3d9f.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/t.5089888b3d9f.png&quot; width=&quot;1086&quot; height=&quot;366&quot; alt=&quot;String index 2&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Positive and Negative String Indices&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Here are some examples of negative indexing:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;f&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Attempting to index with negative numbers beyond the start of the string results in an error:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#26&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;IndexError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;string index out of range&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For any non-empty string &lt;code&gt;s&lt;/code&gt;, &lt;code&gt;s[len(s)-1]&lt;/code&gt; and &lt;code&gt;s[-1]&lt;/code&gt; both return the last character.  There isn&amp;rsquo;t any index that makes sense for an empty string.&lt;/p&gt;
&lt;h3 id=&quot;string-slicing&quot;&gt;String Slicing&lt;/h3&gt;
&lt;p&gt;Python also allows a form of indexing syntax that extracts substrings from a string, known as string slicing.  If &lt;code&gt;s&lt;/code&gt; is a string, an expression of the form &lt;code&gt;s[m:n]&lt;/code&gt; returns the portion of &lt;code&gt;s&lt;/code&gt; starting with position &lt;code&gt;m&lt;/code&gt;, and up to but not including position &lt;code&gt;n&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;oba&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Remember:&lt;/strong&gt; String indices are zero-based. The first character in a string has index &lt;code&gt;0&lt;/code&gt;.  This applies to both standard indexing and slicing.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Again, the second index specifies the first character that is not included in the result&amp;mdash;the character &lt;code&gt;&#39;r&#39;&lt;/code&gt; (&lt;code&gt;s[5]&lt;/code&gt;) in the example above.  That may seem slightly unintuitive, but it produces this result which makes sense:  the expression &lt;code&gt;s[m:n]&lt;/code&gt; will return a substring that is &lt;code&gt;n - m&lt;/code&gt; characters in length, in this case, &lt;code&gt;5 - 2 = 3&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you omit the first index, the slice starts at the beginning of the string. Thus, &lt;code&gt;s[:m]&lt;/code&gt; and &lt;code&gt;s[0:m]&lt;/code&gt; are equivalent:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foob&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foob&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Similarly, if you omit the second index as in &lt;code&gt;s[n:]&lt;/code&gt;, the slice extends from the first index through the end of the string.  This is a nice, concise alternative to the more cumbersome &lt;code&gt;s[n:len(s)]&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;obar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;obar&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For any string &lt;code&gt;s&lt;/code&gt; and any integer &lt;code&gt;n&lt;/code&gt; (&lt;code&gt;0 ≤ n ≤ len(s)&lt;/code&gt;), &lt;code&gt;s[:n] + s[n:]&lt;/code&gt; will be equal to &lt;code&gt;s&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Omitting both indices returns the original string, in its entirety.  Literally.  It&amp;rsquo;s not a copy, it&amp;rsquo;s a reference to the original string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;59598496&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;59598496&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the first index in a slice is greater than or equal to the second index, Python returns an empty string.  This is yet another obfuscated way to generate an empty string, in case you were looking for one:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Negative indices can be used with slicing as well.  &lt;code&gt;-1&lt;/code&gt; refers to the last character, &lt;code&gt;-2&lt;/code&gt; the second-to-last, and so on, just as with simple indexing.  The diagram below shows how to slice the substring &lt;code&gt;&#39;oob&#39;&lt;/code&gt; from the string &lt;code&gt;&#39;foobar&#39;&lt;/code&gt; using both positive and negative indices:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.ed50396b1e71.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/t.ed50396b1e71.png&quot; width=&quot;1086&quot; height=&quot;366&quot; alt=&quot;String index 3&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;String Slicing with Positive and Negative Indices&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Here is the corresponding Python code:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;oob&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;oob&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;specifying-a-stride-in-a-string-slice&quot;&gt;Specifying a Stride in a String Slice&lt;/h3&gt;
&lt;p&gt;There is one more variant of the slicing syntax to discuss.  Adding an additional &lt;code&gt;:&lt;/code&gt; and a third index designates a stride (also called a step), which indicates how many characters to jump after retrieving each character in the slice.&lt;/p&gt;
&lt;p&gt;For example, for the string &lt;code&gt;&#39;foobar&#39;&lt;/code&gt;, the slice &lt;code&gt;0:6:2&lt;/code&gt; starts with the first character and ends with the last character (the whole string), and every second character is skipped.  This is shown in the following diagram:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.1fb308cf7573.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/t.1fb308cf7573.png&quot; width=&quot;1086&quot; height=&quot;366&quot; alt=&quot;String stride 1&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;String Indexing with Stride&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Similarly, &lt;code&gt;1:6:2&lt;/code&gt; specifies a slice starting with the second character (index &lt;code&gt;1&lt;/code&gt;) and ending with the last character, and again the stride value &lt;code&gt;2&lt;/code&gt; causes every other character to be skipped:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.8a1e853f9509.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/t.8a1e853f9509.png&quot; width=&quot;1086&quot; height=&quot;366&quot; alt=&quot;String stride 2&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Another String Indexing with Stride&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;The illustrative REPL code is shown here:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foa&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;obr&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As with any slicing, the first and second indices can be omitted, and default to the first and last characters respectively:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;12345&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1234512345123451234512345&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;11111&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;55555&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can specify a negative stride value as well, in which case Python steps backward through the string.  In that case, the starting/first index should be greater than the ending/second index:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;rbo&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the above example, &lt;code&gt;5:0:-2&lt;/code&gt; means &amp;ldquo;start at the last character and step backward by &lt;code&gt;2&lt;/code&gt;, up to but not including the first character.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;When you are stepping backward, if the first and second indices are omitted, the defaults are reversed in an intuitive way: the first index defaults to the end of the string, and the second index defaults to the beginning.  Here is an example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;12345&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;1234512345123451234512345&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;55555&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is a common paradigm for reversing a string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;If Comrade Napoleon says it, it must be right.&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[::&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;.thgir eb tsum ti ,ti syas noelopaN edarmoC fI&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;interpolating-variables-into-a-string&quot;&gt;Interpolating Variables Into a String&lt;/h3&gt;
&lt;p&gt;In Python version 3.6, a new string formatting mechanism was introduced.  This feature is formally named the Formatted String Literal, but is more usually referred to by its nickname &lt;strong&gt;f-string&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The formatting capability provided by f-strings is extensive and won&amp;rsquo;t be covered in full detail here.  If you want to learn more, you can check out the Real Python article &lt;a href=&quot;https://realpython.com/python-f-strings/&quot;&gt;Python 3&amp;rsquo;s f-Strings: An Improved String Formatting Syntax (Guide)&lt;/a&gt;. There is also a tutorial on Formatted Output coming up later in this series that digs deeper into f-strings.&lt;/p&gt;
&lt;p&gt;One simple feature of f-strings you can start using right away is variable interpolation.  You can specify a variable name directly within an f-string literal, and Python will replace the name with the corresponding value.&lt;/p&gt;
&lt;p&gt;For example, suppose you want to display the result of an arithmetic calculation.  You can do this with a straightforward &lt;code&gt;print()&lt;/code&gt; statement, separating numeric values and string literals by commas:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;The product of&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;and&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;is&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prod&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;The product of 20 and 25 is 500&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But this is cumbersome. To accomplish the same thing using an f-string:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Specify either a lowercase &lt;code&gt;f&lt;/code&gt; or uppercase &lt;code&gt;F&lt;/code&gt; directly before the opening quote of the string literal. This tells Python it is an f-string instead of a standard string.&lt;/li&gt;
&lt;li&gt;Specify any variables to be interpolated in curly braces (&lt;code&gt;{}&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Recast using an f-string, the above example looks much cleaner:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;The product of {n} and {m} is {prod}&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;The product of 20 and 25 is 500&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Any of Python&amp;rsquo;s three quoting mechanisms can be used to define an f-string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Bark&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;A dog says {var}!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;A dog says Bark!&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A dog says {var}!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;A dog says Bark!&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&amp;#39;A dog says {var}!&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;A dog says Bark!&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;modifying-strings&quot;&gt;Modifying Strings&lt;/h3&gt;
&lt;p&gt;In a nutshell, you can&amp;rsquo;t.  Strings are one of the data types Python considers immutable, meaning not able to be changed.  In fact, all the data types you have seen so far are immutable. (Python does provide data types that are mutable, as you will soon see.)&lt;/p&gt;
&lt;p&gt;A statement like this will cause an error:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;x&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#40&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;x&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&amp;#39;str&amp;#39; object does not support item assignment&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In truth, there really isn&amp;rsquo;t much need to modify strings.  You can usually easily accomplish what you want by generating a copy of the original string that has the desired change in place.  There are very many ways to do this in Python.  Here is one possibility:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;x&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;fooxar&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There is also a built-in string method to accomplish this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;x&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;fooxar&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Read on for more information about built-in string methods!&lt;/p&gt;
&lt;h3 id=&quot;built-in-string-methods&quot;&gt;Built-in String Methods&lt;/h3&gt;
&lt;p&gt;You learned in the tutorial on &lt;a href=&quot;https://realpython.com/python-variables/&quot;&gt;Variables in Python&lt;/a&gt; that Python is a highly object-oriented language.  Every item of data in a Python program is an object.&lt;/p&gt;
&lt;p&gt;You are also familiar with functions: callable procedures that you can invoke to perform specific tasks.&lt;/p&gt;
&lt;p&gt;Methods are similar to functions.  A method is a specialized type of callable procedure that is tightly associated with an object.  Like a function, a method is called to perform a distinct task, but it is invoked on a specific object and has knowledge of its target object during execution.&lt;/p&gt;
&lt;p&gt;The syntax for invoking a method on an object is as follows:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This invokes method &lt;code&gt;.foo()&lt;/code&gt; on object &lt;code&gt;obj&lt;/code&gt;. &lt;code&gt;&amp;lt;args&amp;gt;&lt;/code&gt; specifies the arguments passed to the method (if any).&lt;/p&gt;
&lt;p&gt;You will explore much more about defining and calling methods later in the discussion of object-oriented programming.  For now, the goal is to present some of the more commonly used built-in methods Python supports for operating on string objects.&lt;/p&gt;
&lt;p&gt;In the following method definitions, arguments specified in square brackets (&lt;code&gt;[]&lt;/code&gt;) are optional.&lt;/p&gt;
&lt;h4 id=&quot;case-conversion&quot;&gt;Case Conversion&lt;/h4&gt;
&lt;p&gt;Methods in this group perform case conversion on the target string.&lt;/p&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.capitalize()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Capitalizes the target string.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.capitalize()&lt;/code&gt; returns a copy of &lt;code&gt;s&lt;/code&gt; with the first character converted to uppercase and all other characters converted to lowercase:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foO BaR BAZ quX&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;Foo bar baz qux&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Non-alphabetic characters are unchanged:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo123#BAR#.&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;Foo123#bar#.&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.lower()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Converts alphabetic characters to lowercase.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.lower()&lt;/code&gt; returns a copy of &lt;code&gt;s&lt;/code&gt; with all alphabetic characters converted to lowercase:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;FOO Bar 123 baz qUX&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo bar 123 baz qux&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.swapcase()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Swaps case of alphabetic characters.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.swapcase()&lt;/code&gt; returns a copy of &lt;code&gt;s&lt;/code&gt; with uppercase alphabetic characters converted to lowercase and vice versa:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;FOO Bar 123 baz qUX&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;swapcase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo bAR 123 BAZ Qux&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.title()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Converts the target string to &amp;ldquo;title case.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.title()&lt;/code&gt; returns a copy of &lt;code&gt;s&lt;/code&gt; in which the first letter of each word is converted to uppercase and remaining letters are lowercase:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;the sun also rises&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;The Sun Also Rises&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This method uses a fairly simple algorithm.  It does not attempt to distinguish between important and unimportant words, and it does not handle apostrophes, possessives, or acronyms gracefully:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;what&amp;#39;s happened to ted&amp;#39;s IBM stock?&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;quot;What&amp;#39;S Happened To Ted&amp;#39;S Ibm Stock?&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.upper()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Converts alphabetic characters to uppercase.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.upper()&lt;/code&gt; returns a copy of &lt;code&gt;s&lt;/code&gt; with all alphabetic characters converted to uppercase:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;FOO Bar 123 baz qUX&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;FOO BAR 123 BAZ QUX&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;find-and-replace&quot;&gt;Find and Replace&lt;/h4&gt;
&lt;p&gt;These methods provide various means of searching the target string for a specified substring.&lt;/p&gt;
&lt;p&gt;Each method in this group supports optional &lt;code&gt;&amp;lt;start&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;end&amp;gt;&lt;/code&gt; arguments. These are interpreted as for string slicing: the action of the method is restricted to the portion of the target string starting at character position &lt;code&gt;&amp;lt;start&amp;gt;&lt;/code&gt; and proceeding up to but not including character position &lt;code&gt;&amp;lt;end&amp;gt;&lt;/code&gt;.  If &lt;code&gt;&amp;lt;start&amp;gt;&lt;/code&gt; is specified but &lt;code&gt;&amp;lt;end&amp;gt;&lt;/code&gt; is not, the method applies to the portion of the target string from &lt;code&gt;&amp;lt;start&amp;gt;&lt;/code&gt; through the end of the string.&lt;/p&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.count(&amp;lt;sub&amp;gt;[, &amp;lt;start&amp;gt;[, &amp;lt;end&amp;gt;]])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Counts occurrences of a substring in the target string.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.count(&amp;lt;sub&amp;gt;)&lt;/code&gt; returns the number of non-overlapping occurrences of substring &lt;code&gt;&amp;lt;sub&amp;gt;&lt;/code&gt; in &lt;code&gt;s&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo goo moo&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;oo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The count is restricted to the number of occurrences within the substring indicated by &lt;code&gt;&amp;lt;start&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;end&amp;gt;&lt;/code&gt;, if they are specified:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo goo moo&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;oo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.endswith(&amp;lt;suffix&amp;gt;[, &amp;lt;start&amp;gt;[, &amp;lt;end&amp;gt;]])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Determines whether the target string ends with a given substring.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.endswith(&amp;lt;suffix&amp;gt;)&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; ends with the specified &lt;code&gt;&amp;lt;suffix&amp;gt;&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt; otherwise:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The comparison is restricted to the substring indicated by &lt;code&gt;&amp;lt;start&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;end&amp;gt;&lt;/code&gt;, if they are specified:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;oob&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;oob&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.find(&amp;lt;sub&amp;gt;[, &amp;lt;start&amp;gt;[, &amp;lt;end&amp;gt;]])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Searches the target string for a given substring.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.find(&amp;lt;sub&amp;gt;)&lt;/code&gt; returns the lowest index in &lt;code&gt;s&lt;/code&gt; where substring &lt;code&gt;&amp;lt;sub&amp;gt;&lt;/code&gt; is found:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This method returns &lt;code&gt;-1&lt;/code&gt; if the specified substring is not found:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;grault&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The search is restricted to the substring indicated by &lt;code&gt;&amp;lt;start&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;end&amp;gt;&lt;/code&gt;, if they are specified:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.index(&amp;lt;sub&amp;gt;[, &amp;lt;start&amp;gt;[, &amp;lt;end&amp;gt;]])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Searches the target string for a given substring.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This method is identical to &lt;code&gt;.find()&lt;/code&gt;, except that it raises an exception if &lt;code&gt;&amp;lt;sub&amp;gt;&lt;/code&gt; is not found rather than returning &lt;code&gt;-1&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;grault&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#0&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;grault&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;ValueError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;substring not found&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.rfind(&amp;lt;sub&amp;gt;[, &amp;lt;start&amp;gt;[, &amp;lt;end&amp;gt;]])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Searches the target string for a given substring starting at the end.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.rfind(&amp;lt;sub&amp;gt;)&lt;/code&gt; returns the highest index in &lt;code&gt;s&lt;/code&gt; where substring &lt;code&gt;&amp;lt;sub&amp;gt;&lt;/code&gt; is found:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rfind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;16&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As with &lt;code&gt;.find()&lt;/code&gt;, if the substring is not found, &lt;code&gt;-1&lt;/code&gt; is returned:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rfind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;grault&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The search is restricted to the substring indicated by &lt;code&gt;&amp;lt;start&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;end&amp;gt;&lt;/code&gt;, if they are specified:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rfind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;8&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rfind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.rindex(&amp;lt;sub&amp;gt;[, &amp;lt;start&amp;gt;[, &amp;lt;end&amp;gt;]])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Searches the target string for a given substring starting at the end.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This method is identical to &lt;code&gt;.rfind()&lt;/code&gt;, except that it raises an exception if &lt;code&gt;&amp;lt;sub&amp;gt;&lt;/code&gt; is not found rather than returning &lt;code&gt;-1&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rindex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;grault&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#1&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rindex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;grault&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;ValueError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;substring not found&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.startswith(&amp;lt;prefix&amp;gt;[, &amp;lt;start&amp;gt;[, &amp;lt;end&amp;gt;]])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Determines whether the target string starts with a given substring.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.startswith(&amp;lt;suffix&amp;gt;)&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; starts with the specified &lt;code&gt;&amp;lt;suffix&amp;gt;&lt;/code&gt; and &lt;code&gt;False&lt;/code&gt; otherwise:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The comparison is restricted to the substring indicated by &lt;code&gt;&amp;lt;start&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;end&amp;gt;&lt;/code&gt;, if they are specified:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;character-classification&quot;&gt;Character Classification&lt;/h4&gt;
&lt;p&gt;Methods in this group classify a string based on the characters it contains.&lt;/p&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.isalnum()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Determines whether the target string consists of alphanumeric characters.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.isalnum()&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; is nonempty and all its characters are alphanumeric (either a letter or a number), and &lt;code&gt;False&lt;/code&gt; otherwise:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abc123&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isalnum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abc$123&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isalnum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isalnum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.isalpha()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Determines whether the target string consists of alphabetic characters.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.isalpha()&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; is nonempty and all its characters are alphabetic, and &lt;code&gt;False&lt;/code&gt; otherwise:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ABCabc&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isalpha&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abc123&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isalpha&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.isdigit()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Determines whether the target string consists of digit characters.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.digit()&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; is nonempty and all its characters are numeric digits, and &lt;code&gt;False&lt;/code&gt; otherwise:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;123&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isdigit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;123abc&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isdigit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.isidentifier()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Determines whether the target string is a valid Python identifier.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.isidentifier()&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; is a valid Python identifier according to the language definition, and &lt;code&gt;False&lt;/code&gt; otherwise:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo32&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isidentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;32foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isidentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo$32&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isidentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;.isidentifier()&lt;/code&gt; will return &lt;code&gt;True&lt;/code&gt; for a string that matches a Python keyword even though that would not actually be a valid identifier:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;and&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isidentifier&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can test whether a string matches a Python keyword using a function called &lt;code&gt;iskeyword()&lt;/code&gt;, which is contained in a module called &lt;code&gt;keyword&lt;/code&gt;.  One possible way to do this is shown below:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;keyword&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iskeyword&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iskeyword&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;and&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you really want to ensure that a string would serve as a valid Python identifier, you should check that &lt;code&gt;.isidentifier()&lt;/code&gt; is &lt;code&gt;True&lt;/code&gt; and that &lt;code&gt;iskeyword()&lt;/code&gt; is &lt;code&gt;False&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&quot;https://realpython.com/python-modules-packages/&quot;&gt;Python Modules and Packages&amp;mdash;An Introduction&lt;/a&gt; to read more about Python modules.&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.islower()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Determines whether the target string&amp;rsquo;s alphabetic characters are lowercase.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.islower()&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; is nonempty and all the alphabetic characters it contains are lowercase, and &lt;code&gt;False&lt;/code&gt; otherwise.  Non-alphabetic characters are ignored:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abc&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abc1$d&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Abc1$D&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islower&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.isprintable()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Determines whether the target string consists entirely of printable characters.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.isprintable()&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; is empty or all the alphabetic characters it contains are printable.  It returns &lt;code&gt;False&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; contains at least one non-printable character. Non-alphabetic characters are ignored:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isprintable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a b&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isprintable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isprintable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isprintable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This is the only &lt;code&gt;.isxxxx()&lt;/code&gt; method that returns &lt;code&gt;True&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; is an empty string. All the others return &lt;code&gt;False&lt;/code&gt; for an empty string.&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.isspace()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Determines whether the target string consists of whitespace characters.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.isspace()&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; is nonempty and all characters are whitespace characters, and &lt;code&gt;False&lt;/code&gt; otherwise.&lt;/p&gt;
&lt;p&gt;The most commonly encountered whitespace characters are space &lt;code&gt;&#39; &#39;&lt;/code&gt;, tab &lt;code&gt;&#39;\t&#39;&lt;/code&gt;, and newline &lt;code&gt;&#39;\n&#39;&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isspace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;   a   &amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isspace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, there are a few other ASCII characters that qualify as whitespace, and if you account for Unicode characters, there are quite a few beyond that:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\f\u2005\r&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isspace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(&lt;code&gt;&#39;\f&#39;&lt;/code&gt; and &lt;code&gt;&#39;\r&#39;&lt;/code&gt; are the escape sequences for the ASCII Form Feed and Carriage Return characters; &lt;code&gt;&#39;\u2005&#39;&lt;/code&gt; is the escape sequence for the Unicode Four-Per-Em Space.)&lt;/p&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.istitle()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Determines whether the target string is title cased.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.istitle()&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; is nonempty, the first alphabetic character of each word is uppercase, and all other alphabetic characters in each word are lowercase.  It returns &lt;code&gt;False&lt;/code&gt; otherwise:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;This Is A Title&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;istitle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;This is a title&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;istitle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Give Me The #$#@ Ball!&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;istitle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Here is how the Python documentation describes &lt;code&gt;.istitle()&lt;/code&gt;, in case you find this more intuitive:  &amp;ldquo;Uppercase characters may only follow uncased characters and lowercase characters only cased ones.&amp;rdquo;&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.isupper()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Determines whether the target string&amp;rsquo;s alphabetic characters are uppercase.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.isupper()&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; if &lt;code&gt;s&lt;/code&gt; is nonempty and all the alphabetic characters it contains are uppercase, and &lt;code&gt;False&lt;/code&gt; otherwise.  Non-alphabetic characters are ignored:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ABC&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isupper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ABC1$D&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isupper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Abc1$D&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isupper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;string-formatting&quot;&gt;String Formatting&lt;/h4&gt;
&lt;p&gt;Methods in this group modify or enhance the format of a string.&lt;/p&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.center(&amp;lt;width&amp;gt;[, &amp;lt;fill&amp;gt;])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Centers a string in a field.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.center(&amp;lt;width&amp;gt;)&lt;/code&gt; returns a string consisting of &lt;code&gt;s&lt;/code&gt; centered in a field of width &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt;.  By default, padding consists of the ASCII space character:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;   foo    &amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the optional &lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt; argument is specified, it is used as the padding character:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;---bar----&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;s&lt;/code&gt; is already at least as long as &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt;, it is returned unchanged:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.expandtabs(tabsize=8)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Expands tabs in a string.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.expandtabs()&lt;/code&gt; replaces each tab character (&lt;code&gt;&#39;\t&#39;&lt;/code&gt;) with spaces.  By default, spaces are filled in assuming a tab stop at every eighth column:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expandtabs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;a       b       c&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;aaa&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bbb&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expandtabs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;aaa     bbb     c&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;tabsize&lt;/code&gt; is an optional keyword parameter specifying alternate tab stop columns:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expandtabs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;a   b   c&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;aaa&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bbb&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expandtabs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tabsize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;aaa bbb c&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.ljust(&amp;lt;width&amp;gt;[, &amp;lt;fill&amp;gt;])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Left-justifies a string in field.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.ljust(&amp;lt;width&amp;gt;)&lt;/code&gt; returns a string consisting of &lt;code&gt;s&lt;/code&gt; left-justified in a field of width &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt;.  By default, padding consists of the ASCII space character:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo       &amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the optional &lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt; argument is specified, it is used as the padding character:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo-------&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;s&lt;/code&gt; is already at least as long as &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt;, it is returned unchanged:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ljust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.lstrip([&amp;lt;chars&amp;gt;])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Trims leading characters from a string.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.lstrip()&lt;/code&gt; returns a copy of &lt;code&gt;s&lt;/code&gt; with any whitespace characters removed from the left end:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;   foo bar baz   &amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo bar baz   &amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo\t\nbar\t\nbaz&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the optional &lt;code&gt;&amp;lt;chars&amp;gt;&lt;/code&gt; argument is specified, it is a string that specifies the set of characters to be removed:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;http://www.realpython.com&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/:pth&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;www.realpython.com&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.replace(&amp;lt;old&amp;gt;, &amp;lt;new&amp;gt;[, &amp;lt;count&amp;gt;])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Replaces occurrences of a substring within a string.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.replace(&amp;lt;old&amp;gt;, &amp;lt;new&amp;gt;)&lt;/code&gt; returns a copy of &lt;code&gt;s&lt;/code&gt; with all occurrences of substring &lt;code&gt;&amp;lt;old&amp;gt;&lt;/code&gt; replaced by &lt;code&gt;&amp;lt;new&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;grault&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;grault bar grault baz grault qux&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the optional &lt;code&gt;&amp;lt;count&amp;gt;&lt;/code&gt; argument is specified, a maximum of &lt;code&gt;&amp;lt;count&amp;gt;&lt;/code&gt; replacements are performed, starting at the left end of &lt;code&gt;s&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar foo baz foo qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;grault&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;grault bar grault baz foo qux&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.rjust(&amp;lt;width&amp;gt;[, &amp;lt;fill&amp;gt;])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Right-justifies a string in a field.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.rjust(&amp;lt;width&amp;gt;)&lt;/code&gt; returns a string consisting of &lt;code&gt;s&lt;/code&gt; right-justified in a field of width &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt;.  By default, padding consists of the ASCII space character:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rjust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;       foo&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the optional &lt;code&gt;&amp;lt;fill&amp;gt;&lt;/code&gt; argument is specified, it is used as the padding character:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rjust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;-------foo&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;s&lt;/code&gt; is already at least as long as &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt;, it is returned unchanged:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rjust&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.rstrip([&amp;lt;chars&amp;gt;])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Trims trailing characters from a string.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.rstrip()&lt;/code&gt; returns a copy of &lt;code&gt;s&lt;/code&gt; with any whitespace characters removed from the right end:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;   foo bar baz   &amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;   foo bar baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo\t\nbar\t\nbaz&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the optional &lt;code&gt;&amp;lt;chars&amp;gt;&lt;/code&gt; argument is specified, it is a string that specifies the set of characters to be removed:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo.$$$;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;;$.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.strip([&amp;lt;chars&amp;gt;])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Strips characters from the left and right ends of a string.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.strip()&lt;/code&gt; is essentially equivalent to invoking &lt;code&gt;s.lstrip()&lt;/code&gt; and &lt;code&gt;s.rstrip()&lt;/code&gt; in succession.  Without the &lt;code&gt;&amp;lt;chars&amp;gt;&lt;/code&gt; argument, it removes leading and trailing whitespace:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;   foo bar baz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t\t\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo bar baz&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As with &lt;code&gt;.lstrip()&lt;/code&gt; and &lt;code&gt;.rstrip()&lt;/code&gt;, the optional &lt;code&gt;&amp;lt;chars&amp;gt;&lt;/code&gt; argument specifies the set of characters to be removed:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;www.realpython.com&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;w.moc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;realpython&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; When the return value of a string method is another string, as is often the case, methods can be invoked in succession by chaining the calls:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;   foo bar baz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t\t\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo bar baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;   foo bar baz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t\t\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo bar baz&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;www.realpython.com&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;w.moc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rstrip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;w.moc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;realpython&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;www.realpython.com&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;w.moc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;realpython&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.zfill(&amp;lt;width&amp;gt;)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Pads a string on the left with zeros.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.zfill(&amp;lt;width&amp;gt;)&lt;/code&gt; returns a copy of &lt;code&gt;s&lt;/code&gt; left-padded with &lt;code&gt;&#39;0&#39;&lt;/code&gt; characters to the specified &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;42&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zfill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;00042&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;s&lt;/code&gt; contains a leading sign, it remains at the left edge of the result string after zeros are inserted:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;+42&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zfill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;+0000042&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;-42&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zfill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;-0000042&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;s&lt;/code&gt; is already at least as long as &lt;code&gt;&amp;lt;width&amp;gt;&lt;/code&gt;, it is returned unchanged:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;-42&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zfill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;-42&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;.zfill()&lt;/code&gt; is most useful for string representations of numbers, but Python will still happily zero-pad a string that isn&amp;rsquo;t:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zfill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;000foo&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;converting-between-strings-and-lists&quot;&gt;Converting Between Strings and Lists&lt;/h4&gt;
&lt;p&gt;Methods in this group convert between a string and some composite data type by either pasting objects together to make a string, or by breaking a string up into pieces.&lt;/p&gt;
&lt;p&gt;These methods operate on or return &lt;strong&gt;iterables&lt;/strong&gt;, the general Python term for a sequential collection of objects.  You will explore the inner workings of iterables in much more detail in the upcoming tutorial on definite iteration.&lt;/p&gt;
&lt;p&gt;Many of these methods return either a list or a tuple.  These are two similar composite data types that are prototypical examples of iterables in Python.  They are covered in the next tutorial, so you&amp;rsquo;re about to learn about them soon!  Until then, simply think of them as sequences of values.  A list is enclosed in square brackets (&lt;code&gt;[]&lt;/code&gt;), and a tuple is enclosed in parentheses (&lt;code&gt;()&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;With that introduction, let&amp;rsquo;s take a look at this last group of string methods.&lt;/p&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.join(&amp;lt;iterable&amp;gt;)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Concatenates strings from an iterable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.join(&amp;lt;iterable&amp;gt;)&lt;/code&gt; returns the string that results from concatenating the objects in &lt;code&gt;&amp;lt;iterable&amp;gt;&lt;/code&gt; separated by &lt;code&gt;s&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;.join()&lt;/code&gt; is invoked on &lt;code&gt;s&lt;/code&gt;, the separator string.  &lt;code&gt;&amp;lt;iterable&amp;gt;&lt;/code&gt; must be a sequence of string objects as well.&lt;/p&gt;
&lt;p&gt;Some sample code should help clarify.  In the following example, the separator &lt;code&gt;s&lt;/code&gt; is the string &lt;code&gt;&#39;, &#39;&lt;/code&gt;, and &lt;code&gt;&amp;lt;iterable&amp;gt;&lt;/code&gt; is a list of string values:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo, bar, baz, qux&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The result is a single string consisting of the list objects separated by commas.&lt;/p&gt;
&lt;p&gt;In the next example, &lt;code&gt;&amp;lt;iterable&amp;gt;&lt;/code&gt; is specified as a single string value.  When a string value is used as an iterable, it is interpreted as a list of the string&amp;rsquo;s individual characters:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;c&amp;#39;, &amp;#39;o&amp;#39;, &amp;#39;r&amp;#39;, &amp;#39;g&amp;#39;, &amp;#39;e&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;:&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;corge&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;c:o:r:g:e&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Thus, the result of &lt;code&gt;&#39;:&#39;.join(&#39;corge&#39;)&lt;/code&gt; is a string consisting of each character in &lt;code&gt;&#39;corge&#39;&lt;/code&gt; separated by &lt;code&gt;&#39;:&#39;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This example fails because one of the objects in &lt;code&gt;&amp;lt;iterable&amp;gt;&lt;/code&gt; is not a string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;---&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#0&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;s1&quot;&gt;&amp;#39;---&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;sequence item 1: expected str instance, int found&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That can be remedied, though:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;---&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo---23---bar&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you will soon see, many composite objects in Python can be construed as iterables, and &lt;code&gt;.join()&lt;/code&gt; is especially useful for creating strings from them.&lt;/p&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.partition(&amp;lt;sep&amp;gt;)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Divides a string based on a separator.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.partition(&amp;lt;sep&amp;gt;)&lt;/code&gt; splits &lt;code&gt;s&lt;/code&gt; at the first occurrence of string &lt;code&gt;&amp;lt;sep&amp;gt;&lt;/code&gt;.  The return value is a three-part tuple consisting of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The portion of &lt;code&gt;s&lt;/code&gt; preceding &lt;code&gt;&amp;lt;sep&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;sep&amp;gt;&lt;/code&gt; itself&lt;/li&gt;
&lt;li&gt;The portion of &lt;code&gt;s&lt;/code&gt; following &lt;code&gt;&amp;lt;sep&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here are a couple examples of &lt;code&gt;.partition()&lt;/code&gt; in action:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo.bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;partition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;foo&amp;#39;, &amp;#39;.&amp;#39;, &amp;#39;bar&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo@@bar@@baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;partition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;@@&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;foo&amp;#39;, &amp;#39;@@&amp;#39;, &amp;#39;bar@@baz&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;&amp;lt;sep&amp;gt;&lt;/code&gt; is not found in &lt;code&gt;s&lt;/code&gt;, the returned tuple contains &lt;code&gt;s&lt;/code&gt; followed by two empty strings:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo.bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;partition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;@@&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;foo.bar&amp;#39;, &amp;#39;&amp;#39;, &amp;#39;&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Remember:&lt;/strong&gt; Lists and tuples are covered in the next tutorial.&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.rpartition(&amp;lt;sep&amp;gt;)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Divides a string based on a separator.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.rpartition(&amp;lt;sep&amp;gt;)&lt;/code&gt; functions exactly like &lt;code&gt;s.partition(&amp;lt;sep&amp;gt;)&lt;/code&gt;, except that &lt;code&gt;s&lt;/code&gt; is split at the last occurrence of &lt;code&gt;&amp;lt;sep&amp;gt;&lt;/code&gt; instead of the first occurrence:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo@@bar@@baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;partition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;@@&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;foo&amp;#39;, &amp;#39;@@&amp;#39;, &amp;#39;bar@@baz&amp;#39;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo@@bar@@baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rpartition&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;@@&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;foo@@bar&amp;#39;, &amp;#39;@@&amp;#39;, &amp;#39;baz&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.rsplit(sep=None, maxsplit=-1)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Splits a string into a list of substrings.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Without arguments, &lt;code&gt;s.rsplit()&lt;/code&gt; splits &lt;code&gt;s&lt;/code&gt; into substrings delimited by any sequence of whitespace and returns the substrings as a list:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar baz qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rsplit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar   baz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r\f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rsplit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;&amp;lt;sep&amp;gt;&lt;/code&gt; is specified, it is used as the delimiter for splitting:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo.bar.baz.qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rsplit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;(If &lt;code&gt;&amp;lt;sep&amp;gt;&lt;/code&gt; is specified with a value of &lt;code&gt;None&lt;/code&gt;, the string is split delimited by whitespace, just as though &lt;code&gt;&amp;lt;sep&amp;gt;&lt;/code&gt; had not been specified at all.)&lt;/p&gt;
&lt;p&gt;When &lt;code&gt;&amp;lt;sep&amp;gt;&lt;/code&gt; is explicitly given as a delimiter, consecutive delimiters in &lt;code&gt;s&lt;/code&gt; are assumed to delimit empty strings, which will be returned:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo...bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rsplit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;&amp;#39;, &amp;#39;&amp;#39;, &amp;#39;bar&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is not the case when &lt;code&gt;&amp;lt;sep&amp;gt;&lt;/code&gt; is omitted, however.  In that case, consecutive whitespace characters are combined into a single delimiter, and the resulting list will never contain empty strings:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t\t\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rsplit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the optional keyword parameter &lt;code&gt;&amp;lt;maxsplit&amp;gt;&lt;/code&gt; is specified, a maximum of that many splits are performed, starting from the right end of &lt;code&gt;s&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;www.realpython.com&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rsplit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxsplit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;www.realpython&amp;#39;, &amp;#39;com&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The default value for &lt;code&gt;&amp;lt;maxsplit&amp;gt;&lt;/code&gt; is &lt;code&gt;-1&lt;/code&gt;, which means all possible splits should be performed&amp;mdash;the same as if &lt;code&gt;&amp;lt;maxsplit&amp;gt;&lt;/code&gt; is omitted entirely:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;www.realpython.com&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rsplit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxsplit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;www&amp;#39;, &amp;#39;realpython&amp;#39;, &amp;#39;com&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;www.realpython.com&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rsplit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;www&amp;#39;, &amp;#39;realpython&amp;#39;, &amp;#39;com&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.split(sep=None, maxsplit=-1)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Splits a string into a list of substrings.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.split()&lt;/code&gt; behaves exactly like &lt;code&gt;s.rsplit()&lt;/code&gt;, except that if &lt;code&gt;&amp;lt;maxsplit&amp;gt;&lt;/code&gt; is specified, splits are counted from the left end of &lt;code&gt;s&lt;/code&gt; rather than the right end:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;www.realpython.com&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxsplit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;www&amp;#39;, &amp;#39;realpython.com&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;www.realpython.com&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rsplit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxsplit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;www.realpython&amp;#39;, &amp;#39;com&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;&amp;lt;maxsplit&amp;gt;&lt;/code&gt; is not specified, &lt;code&gt;.split()&lt;/code&gt; and &lt;code&gt;.rsplit()&lt;/code&gt; are indistinguishable.&lt;/p&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;s.splitlines([&amp;lt;keepends&amp;gt;])&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Breaks a string at line boundaries.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;s.splitlines()&lt;/code&gt; splits &lt;code&gt;s&lt;/code&gt; up into lines and returns them in a list.  Any of the following characters or character sequences is considered to constitute a line boundary:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Escape Sequence&lt;/th&gt;
&lt;th&gt;Character&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Newline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Carriage Return&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\r\n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Carriage Return + Line Feed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\v&lt;/code&gt; or &lt;code&gt;\x0b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Line Tabulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\f&lt;/code&gt; or &lt;code&gt;\x0c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Form Feed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\x1c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File Separator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\x1d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Group Separator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\x1e&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Record Separator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\x85&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Next Line (C1 Control Code)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\u2028&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unicode Line Separator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\u2029&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unicode Paragraph Separator&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Here is an example using several different line separators:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\r\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;qux&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\u2028&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;quux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;splitlines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;bar&amp;#39;, &amp;#39;baz&amp;#39;, &amp;#39;qux&amp;#39;, &amp;#39;quux&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If consecutive line boundary characters are present in the string, they are assumed to delimit blank lines, which will appear in the result list:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\f\f\f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;splitlines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo&amp;#39;, &amp;#39;&amp;#39;, &amp;#39;&amp;#39;, &amp;#39;bar&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the optional &lt;code&gt;&amp;lt;keepends&amp;gt;&lt;/code&gt; argument is specified and is truthy, then the lines boundaries are retained in the result strings:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;splitlines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo\n&amp;#39;, &amp;#39;bar\n&amp;#39;, &amp;#39;baz\n&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;baz&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;splitlines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;foo\n&amp;#39;, &amp;#39;bar\n&amp;#39;, &amp;#39;baz\n&amp;#39;, &amp;#39;qux&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;bytes-objects&quot;&gt;&lt;code&gt;bytes&lt;/code&gt; Objects&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;bytes&lt;/code&gt; object is one of the core built-in types for manipulating binary data.  A &lt;code&gt;bytes&lt;/code&gt; object is an immutable sequence of single &lt;a href=&quot;https://en.wikipedia.org/wiki/Byte&quot;&gt;byte&lt;/a&gt; values. Each element in a &lt;code&gt;bytes&lt;/code&gt; object is a small integer in the range &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;255&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;defining-a-literal-bytes-object&quot;&gt;Defining a Literal &lt;code&gt;bytes&lt;/code&gt; Object&lt;/h3&gt;
&lt;p&gt;A &lt;code&gt;bytes&lt;/code&gt; literal is defined in the same way as a string literal with the addition of a &lt;code&gt;&#39;b&#39;&lt;/code&gt; prefix:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;foo bar baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;bytes&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As with strings, you can use any of the single, double, or triple quoting mechanisms:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Contains embedded &amp;quot;double&amp;quot; quotes&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;Contains embedded &amp;quot;double&amp;quot; quotes&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Contains embedded &amp;#39;single&amp;#39; quotes&amp;quot;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;quot;Contains embedded &amp;#39;single&amp;#39; quotes&amp;quot;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;#39;&amp;#39;&amp;#39;Contains embedded &amp;quot;double&amp;quot; and &amp;#39;single&amp;#39; quotes&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;Contains embedded &amp;quot;double&amp;quot; and \&amp;#39;single\&amp;#39; quotes&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Contains embedded &amp;quot;double&amp;quot; and &amp;#39;single&amp;#39; quotes&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;Contains embedded &amp;quot;double&amp;quot; and \&amp;#39;single\&amp;#39; quotes&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Only ASCII characters are allowed in a &lt;code&gt;bytes&lt;/code&gt; literal.  Any character value greater than &lt;code&gt;127&lt;/code&gt; must be specified using an appropriate escape sequence:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xdd&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;foo\xddbar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;221&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0xdd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;221&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;&#39;r&#39;&lt;/code&gt; prefix may be used on a &lt;code&gt;bytes&lt;/code&gt; literal to disable processing of escape sequences, as with strings:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;rb&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo\xddbar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;foo\\xddbar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;92&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;chr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;92&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;\\&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;defining-a-bytes-object-with-the-built-in-bytes-function&quot;&gt;Defining a &lt;code&gt;bytes&lt;/code&gt; Object With the Built-in &lt;code&gt;bytes()&lt;/code&gt; Function&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;bytes()&lt;/code&gt; function also creates a &lt;code&gt;bytes&lt;/code&gt; object. What sort of &lt;code&gt;bytes&lt;/code&gt; object gets returned depends on the argument(s) passed to the function.  The possible forms are shown below.&lt;/p&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;bytes(&amp;lt;s&amp;gt;, &amp;lt;encoding&amp;gt;)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Creates a &lt;code&gt;bytes&lt;/code&gt; object from a string.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;bytes(&amp;lt;s&amp;gt;, &amp;lt;encoding&amp;gt;)&lt;/code&gt; converts string &lt;code&gt;&amp;lt;s&amp;gt;&lt;/code&gt; to a &lt;code&gt;bytes&lt;/code&gt; object, using &lt;code&gt;str.encode()&lt;/code&gt; according to the specified &lt;code&gt;&amp;lt;encoding&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo.bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;foo.bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;bytes&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Technical Note:&lt;/strong&gt; In this form of the &lt;code&gt;bytes()&lt;/code&gt; function, the &lt;code&gt;&amp;lt;encoding&amp;gt;&lt;/code&gt; argument is required.  &amp;ldquo;Encoding&amp;rdquo; refers to the manner in which characters are translated to integer values.  A value of &lt;code&gt;&quot;utf8&quot;&lt;/code&gt; indicates Unicode Transformation Format &lt;strong&gt;UTF-8&lt;/strong&gt;, which is an encoding that can handle every possible Unicode character.  UTF-8 can also be indicated by specifying &lt;code&gt;&quot;UTF8&quot;&lt;/code&gt;, &lt;code&gt;&quot;utf-8&quot;&lt;/code&gt;, or &lt;code&gt;&quot;UTF-8&quot;&lt;/code&gt; for &lt;code&gt;&amp;lt;encoding&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&quot;http://www.unicode.org/standard/WhatIsUnicode.html&quot;&gt;Unicode documentation&lt;/a&gt; for more information. As long as you are dealing with common Latin-based characters, UTF-8 will serve you fine.&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;bytes(&amp;lt;size&amp;gt;)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Creates a &lt;code&gt;bytes&lt;/code&gt; object consisting of null (&lt;code&gt;0x00&lt;/code&gt;) bytes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;bytes(&amp;lt;size&amp;gt;)&lt;/code&gt; defines a &lt;code&gt;bytes&lt;/code&gt; object of the specified &lt;code&gt;&amp;lt;size&amp;gt;&lt;/code&gt;, which must be a positive integer.  The resulting &lt;code&gt;bytes&lt;/code&gt; object is initialized to null (&lt;code&gt;0x00&lt;/code&gt;) bytes:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;\x00\x00\x00\x00\x00\x00\x00\x00&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;bytes&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;bytes(&amp;lt;iterable&amp;gt;)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Creates a &lt;code&gt;bytes&lt;/code&gt; object from an iterable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;bytes(&amp;lt;iterable&amp;gt;)&lt;/code&gt; defines a &lt;code&gt;bytes&lt;/code&gt; object from the sequence of integers generated by &lt;code&gt;&amp;lt;iterable&amp;gt;&lt;/code&gt;.  &lt;code&gt;&amp;lt;iterable&amp;gt;&lt;/code&gt; must be an iterable that generates a sequence of integers &lt;code&gt;n&lt;/code&gt; in the range &lt;code&gt;0 ≤ n ≤ 255&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;102&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;104&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;106&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;108&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;dfhjl&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;bytes&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;104&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;operations-on-bytes-objects&quot;&gt;Operations on &lt;code&gt;bytes&lt;/code&gt; Objects&lt;/h3&gt;
&lt;p&gt;Like strings, &lt;code&gt;bytes&lt;/code&gt; objects support the common sequence operations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;in&lt;/code&gt; and &lt;code&gt;not in&lt;/code&gt; operators:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abcde&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;cd&amp;#39;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The concatenation (&lt;code&gt;+&lt;/code&gt;) and replication (&lt;code&gt;*&lt;/code&gt;) operators:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abcde&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;fghi&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;abcdefghi&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;abcdeabcdeabcde&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Indexing and slicing:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abcde&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;99&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;bc&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Built-in functions:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;97&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;101&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Many of the methods defined for string objects are valid for &lt;code&gt;bytes&lt;/code&gt; objects as well:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo,bar,foo,baz,foo,qux&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;12&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[b&amp;#39;foo&amp;#39;, b&amp;#39;bar&amp;#39;, b&amp;#39;foo&amp;#39;, b&amp;#39;baz&amp;#39;, b&amp;#39;foo&amp;#39;, b&amp;#39;qux&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;center&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;---foo,bar,foo,baz,foo,qux----&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice, however, that when these operators and methods are invoked on a &lt;code&gt;bytes&lt;/code&gt; object, the operand and arguments must be &lt;code&gt;bytes&lt;/code&gt; objects as well:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo.bar&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;.baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#72&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;.baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;can&amp;#39;t concat bytes to str&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;foo.bar.baz&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#74&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;a bytes-like object is required, not &amp;#39;str&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sep&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[b&amp;#39;foo&amp;#39;, b&amp;#39;bar&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Although a &lt;code&gt;bytes&lt;/code&gt; object definition and representation is based on ASCII text, it actually behaves like an immutable sequence of small integers in the range &lt;code&gt;0&lt;/code&gt; to &lt;code&gt;255&lt;/code&gt;, inclusive.  That is why a single element from a &lt;code&gt;bytes&lt;/code&gt; object is displayed as an integer:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\xdd&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;221&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;0xdd&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;97&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;221&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A slice is displayed as a &lt;code&gt;bytes&lt;/code&gt; object though, even if it is only one byte long:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;c&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can convert a &lt;code&gt;bytes&lt;/code&gt; object into a list of integers with the built-in &lt;code&gt;list()&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[97, 98, 99, 100, 101]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Hexadecimal numbers are often used to specify binary data because two hexadecimal digits correspond directly to a single byte. The &lt;code&gt;bytes&lt;/code&gt; class supports two additional methods that facilitate conversion to and from a string of hexadecimal digits.&lt;/p&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;bytes.fromhex(&amp;lt;s&amp;gt;)&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Returns a &lt;code&gt;bytes&lt;/code&gt; object constructed from a string of hexadecimal values.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;bytes.fromhex(&amp;lt;s&amp;gt;)&lt;/code&gt; returns the &lt;code&gt;bytes&lt;/code&gt; object that results from converting each pair of hexadecimal digits in &lt;code&gt;&amp;lt;s&amp;gt;&lt;/code&gt; to the corresponding byte value.  The hexadecimal digit pairs in &lt;code&gt;&amp;lt;s&amp;gt;&lt;/code&gt; may optionally be separated by whitespace, which is ignored:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromhex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39; aa 68 4682cc &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;\xaahF\x82\xcc&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[170, 104, 70, 130, 204]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This method is a class method, not an object method.  It is bound to the &lt;code&gt;bytes&lt;/code&gt; class, not a &lt;code&gt;bytes&lt;/code&gt; object.  You will delve much more into the distinction between classes, objects, and their respective methods in the upcoming tutorials on &lt;a href=&quot;https://realpython.com/python3-object-oriented-programming/&quot;&gt;object-oriented programming&lt;/a&gt;.  For now, just observe that this method is invoked on the &lt;code&gt;bytes&lt;/code&gt; class, not on object &lt;code&gt;b&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p class=&quot;h4 mt-5&quot;&gt;&lt;code&gt;b.hex()&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Returns a string of hexadecimal value from a &lt;code&gt;bytes&lt;/code&gt; object.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;code&gt;b.hex()&lt;/code&gt; returns the result of converting &lt;code&gt;bytes&lt;/code&gt; object &lt;code&gt;b&lt;/code&gt; into a string of hexadecimal digit pairs.  That is, it does the reverse of &lt;code&gt;.fromhex()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fromhex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39; aa 68 4682cc &amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&amp;#39;\xaahF\x82\xcc&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;aa684682cc&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;str&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As opposed to &lt;code&gt;.fromhex()&lt;/code&gt;, &lt;code&gt;.hex()&lt;/code&gt; is an object method, not a class method. Thus, it is invoked on an object of the &lt;code&gt;bytes&lt;/code&gt; class, not on the class itself.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;bytearray-objects&quot;&gt;&lt;code&gt;bytearray&lt;/code&gt; Objects&lt;/h3&gt;
&lt;p&gt;Python supports another binary sequence type called the &lt;code&gt;bytearray&lt;/code&gt;.  &lt;code&gt;bytearray&lt;/code&gt; objects are very like &lt;code&gt;bytes&lt;/code&gt; objects, despite some differences:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;There is no dedicated syntax built into Python for defining a &lt;code&gt;bytearray&lt;/code&gt; literal, like the &lt;code&gt;&#39;b&#39;&lt;/code&gt; prefix that may be used to define a &lt;code&gt;bytes&lt;/code&gt; object.  A &lt;code&gt;bytearray&lt;/code&gt; object is always created using the &lt;code&gt;bytearray()&lt;/code&gt; built-in function:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytearray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo.bar.baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;UTF-8&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bytearray(b&amp;#39;foo.bar.baz&amp;#39;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bytearray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bytearray(b&amp;#39;\x00\x00\x00\x00\x00\x00&amp;#39;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bytearray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;102&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;104&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;106&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;108&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bytearray(b&amp;#39;dfhjl&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;bytearray&lt;/code&gt; objects are mutable.  You can modify the contents of a &lt;code&gt;bytearray&lt;/code&gt; object using indexing and slicing:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytearray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo.bar.baz&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;UTF-8&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bytearray(b&amp;#39;foo.bar.baz&amp;#39;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0xee&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bytearray(b&amp;#39;foo.b\xeer.baz&amp;#39;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;qux&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bytearray(b&amp;#39;foo.b\xeer.qux&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A &lt;code&gt;bytearray&lt;/code&gt; object may be constructed directly from a &lt;code&gt;bytes&lt;/code&gt; object as well:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bytearray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ba&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bytearray(b&amp;#39;foo&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This tutorial provided an in-depth look at the many different mechanisms Python provides for &lt;strong&gt;string&lt;/strong&gt; handling, including string operators, built-in functions, indexing, slicing, and built-in methods. You also were introduced to the &lt;code&gt;bytes&lt;/code&gt; and &lt;code&gt;bytearray&lt;/code&gt; types.&lt;/p&gt;
&lt;p&gt;These types are the first types you have examined that are composite&amp;mdash;built from a collection of smaller parts.  Python provides several composite built-in types.  In the next tutorial, you will explore two of the most frequently used:  &lt;strong&gt;lists&lt;/strong&gt; and &lt;strong&gt;tuples&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;container py-3 series-nav mb-3&quot;&gt;
  &lt;div class=&quot;row justify-content-between&quot;&gt;
    &lt;div class=&quot;col-12 col-md-3 text-left text-muted ml-1&quot;&gt;&lt;a href=&quot;https://realpython.com/python-operators-expressions/&quot;&gt; «&amp;nbsp;Operators and Expressions in Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-center text-muted&quot;&gt;&lt;a href=&quot;#&quot;&gt;Strings in Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-right text-muted mr-1&quot;&gt;&lt;a &gt;Lists and Tuples in Python&amp;nbsp;»&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python String Formatting Best Practices</title>
      <id>https://realpython.com/python-string-formatting/</id>
      <link href="https://realpython.com/python-string-formatting/"/>
      <updated>2018-07-04T14:00:00+00:00</updated>
      <summary>Learn the four main approaches to string formatting in Python, as well as their strengths and weaknesses. You&#39;ll also get a simple rule of thumb for how to pick the best general purpose string formatting approach in your own programs.</summary>
      <content type="html">
        &lt;p&gt;Remember the &lt;a href=&quot;https://www.python.org/dev/peps/pep-0020/&quot;&gt;Zen of Python&lt;/a&gt; and how there should be &amp;ldquo;one obvious way to do something in Python&amp;rdquo;? You might scratch your head when you find out that there are &lt;em&gt;four&lt;/em&gt; major ways to do string formatting in Python.&lt;/p&gt;
&lt;p&gt;In this tutorial, you&amp;rsquo;ll learn the four main approaches to string formatting in Python, as well as their strengths and weaknesses. You&amp;rsquo;ll also get a simple rule of thumb for how to pick the best general purpose string formatting approach in your own programs.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s jump right in, as we&amp;rsquo;ve got a lot to cover. In order to have a simple toy example for experimentation, let&amp;rsquo;s assume you&amp;rsquo;ve got the following variables (or constants, really) to work with:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errno&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;50159747054&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Bob&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Based on these variables, you&amp;rsquo;d like to generate an output string containing a simple error message:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;&amp;#39;Hey Bob, there is a 0xbadc0ffee error!&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That error could really spoil a dev&amp;rsquo;s Monday morning&amp;hellip; But we&amp;rsquo;re here to discuss string formatting. So let&amp;rsquo;s get to work.&lt;/p&gt;
&lt;h2 id=&quot;1-old-style-string-formatting-operator&quot;&gt;#1 &amp;ldquo;Old Style&amp;rdquo; String Formatting (% operator)&lt;/h2&gt;
&lt;p&gt;Strings in Python have a unique built-in operation that can be accessed with the &lt;code&gt;%&lt;/code&gt; operator. This lets you do simple positional formatting very easily. If you&amp;rsquo;ve ever worked with a &lt;code&gt;printf&lt;/code&gt;-style function in C, you&amp;rsquo;ll recognize how this works instantly. Here&amp;rsquo;s a simple example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hello, &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;quot;Hello, Bob&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I&amp;rsquo;m using the &lt;code&gt;%s&lt;/code&gt; format specifier here to tell Python where to substitute the value of &lt;code&gt;name&lt;/code&gt;, represented as a string.&lt;/p&gt;
&lt;p&gt;There are other format specifiers available that let you control the output format. For example, it&amp;rsquo;s possible to convert numbers to hexadecimal notation or add whitespace padding to generate nicely formatted tables and reports. (See &lt;a href=&quot;https://docs.python.org/3/library/stdtypes.html#old-string-formatting&quot;&gt;Python Docs: &amp;ldquo;printf-style String Formatting&amp;rdquo;&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;Here, you can use the &lt;code&gt;%x&lt;/code&gt; format specifier to convert an &lt;code&gt;int&lt;/code&gt; value to a string and to represent it as a hexadecimal number:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%x&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errno&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;badc0ffee&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &amp;ldquo;old style&amp;rdquo; string formatting syntax changes slightly if you want to make multiple substitutions in a single string. Because the &lt;code&gt;%&lt;/code&gt; operator takes only one argument, you need to wrap the right-hand side in a tuple, like so:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hey &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, there is a 0x&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%x&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; error!&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errno&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;Hey Bob, there is a 0xbadc0ffee error!&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It&amp;rsquo;s also possible to refer to variable substitutions by name in your format string, if you pass a mapping to the &lt;code&gt;%&lt;/code&gt; operator:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hey &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%(name)s&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;, there is a 0x&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%(errno)x&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; error!&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;s2&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;errno&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errno&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;Hey Bob, there is a 0xbadc0ffee error!&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This makes your format strings easier to maintain and easier to modify in the future. You don&amp;rsquo;t have to worry about making sure the order you&amp;rsquo;re passing in the values matches up with the order in which the values are referenced in the format string. Of course, the downside is that this technique requires a little more typing.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m sure you&amp;rsquo;ve been wondering why this &lt;code&gt;printf&lt;/code&gt;-style formatting is called &amp;ldquo;old style&amp;rdquo; string formatting. It was technically superseded by &amp;ldquo;new style&amp;rdquo; formatting in Python 3, which we&amp;rsquo;re going to talk about next.&lt;/p&gt;
&lt;h2 id=&quot;2-new-style-string-formatting-strformat&quot;&gt;#2 &amp;ldquo;New Style&amp;rdquo; String Formatting (&lt;code&gt;str.format&lt;/code&gt;)&lt;/h2&gt;
&lt;p&gt;Python 3 introduced a new way to do string formatting that was also later back-ported to Python 2.7. This &amp;ldquo;new style&amp;rdquo; string formatting gets rid of the &lt;code&gt;%&lt;/code&gt;-operator special syntax and makes the syntax for string formatting more regular. Formatting is now handled by &lt;a href=&quot;https://docs.python.org/3/library/stdtypes.html#str.format&quot;&gt;calling &lt;code&gt;.format()&lt;/code&gt; on a string object&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can use &lt;code&gt;format()&lt;/code&gt; to do simple positional formatting, just like you could with &amp;ldquo;old style&amp;rdquo; formatting:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hello, {}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;Hello, Bob&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Or, you can refer to your variable substitutions by name and use them in any order you want. This is quite a powerful feature as it allows for re-arranging the order of display without changing the arguments passed to &lt;code&gt;format()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hey {name}, there is a 0x{errno:x} error!&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errno&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errno&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;Hey Bob, there is a 0xbadc0ffee error!&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This also shows that the syntax to format an &lt;code&gt;int&lt;/code&gt; variable as a hexadecimal string has changed. Now you need to pass a format spec by adding a &lt;code&gt;:x&lt;/code&gt; suffix. The format string syntax has become more powerful without complicating the simpler use cases. It pays off to read up on this &lt;a href=&quot;https://docs.python.org/3/library/string.html#string-formatting&quot;&gt;string formatting mini-language in the Python documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In Python 3, this &amp;ldquo;new style&amp;rdquo; string formatting is to be preferred over &lt;code&gt;%&lt;/code&gt;-style formatting. While &lt;a href=&quot;https://docs.python.org/3/library/stdtypes.html?highlight=sprintf#printf-style-string-formatting&quot;&gt;&amp;ldquo;old style&amp;rdquo; formatting has been de-emphasized&lt;/a&gt;, it has not been deprecated. It is still supported in the latest versions of Python. According to &lt;a href=&quot;https://lists.gt.net/python/dev/969817&quot;&gt;this discussion on the Python dev email list&lt;/a&gt; and &lt;a href=&quot;https://bugs.python.org/issue14123&quot;&gt;this issue on the Python dev bug tracker&lt;/a&gt;, &lt;code&gt;%&lt;/code&gt;-formatting is going to stick around for a long time to come.&lt;/p&gt;
&lt;p&gt;Still, the official Python 3 documentation doesn&amp;rsquo;t exactly recommend &amp;ldquo;old style&amp;rdquo; formatting or speak too fondly of it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;The formatting operations described here exhibit a variety of quirks that lead to a number of common errors (such as failing to display tuples and dictionaries correctly). Using the newer formatted string literals or the str.format() interface helps avoid these errors. These alternatives also provide more powerful, flexible and extensible approaches to formatting text.&amp;rdquo; (&lt;a href=&quot;https://docs.python.org/3/library/stdtypes.html?highlight=sprintf#printf-style-string-formatting&quot;&gt;Source&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is why I&amp;rsquo;d personally try to stick with &lt;code&gt;str.format&lt;/code&gt; for new code moving forward. Starting with Python 3.6, there&amp;rsquo;s yet another way to format your strings. I&amp;rsquo;ll tell you all about it in the next section.&lt;/p&gt;
&lt;h2 id=&quot;3-string-interpolation-f-strings-python-36&quot;&gt;#3 String Interpolation / f-Strings (Python 3.6+)&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://dbader.org/blog/cool-new-features-in-python-3-6&quot;&gt;Python 3.6 added a new string formatting approach&lt;/a&gt; called formatted string literals or &lt;a href=&quot;https://realpython.com/python-f-strings/&quot;&gt;&amp;ldquo;f-strings&amp;rdquo;&lt;/a&gt;. This new way of formatting strings lets you use embedded Python expressions inside string constants. Here&amp;rsquo;s a simple example to give you a feel for the feature:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hello, {name}!&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;Hello, Bob!&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, this prefixes the string constant with the letter &amp;ldquo;&lt;code&gt;f&lt;/code&gt;&amp;ldquo;&amp;mdash;hence the name &amp;ldquo;f-strings.&amp;rdquo; This new formatting syntax is powerful. Because you can embed arbitrary Python expressions, you can even do inline arithmetic with it. Check out this example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Five plus ten is {a + b} and not {2 * (a + b)}.&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;Five plus ten is 15 and not 30.&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Formatted string literals are a Python parser feature that converts f-strings into a series of string constants and expressions. They then get joined up to build the final string.&lt;/p&gt;
&lt;p&gt;Imagine you had the following &lt;code&gt;greet()&lt;/code&gt; function that contains an f-string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, {name}! How&amp;#39;s it {question}?&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Bob&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;going&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;quot;Hello, Bob! How&amp;#39;s it going?&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you disassemble the function and inspect what&amp;rsquo;s going on behind the scenes, you&amp;rsquo;ll see that the f-string in the function gets transformed into something similar to the following:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;question&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;   &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;! How&amp;#39;s it &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;question&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;?&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The real implementation is slightly faster than that because it uses the &lt;a href=&quot;https://bugs.python.org/issue27078&quot;&gt;&lt;code&gt;BUILD_STRING&lt;/code&gt; opcode as an optimization&lt;/a&gt;. But functionally they&amp;rsquo;re the same:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;dis&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  2           0 LOAD_CONST               1 (&amp;#39;Hello, &amp;#39;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;              2 LOAD_FAST                0 (name)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;              4 FORMAT_VALUE             0&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;              6 LOAD_CONST               2 (&amp;quot;! How&amp;#39;s it &amp;quot;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;              8 LOAD_FAST                1 (question)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;             10 FORMAT_VALUE             0&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;             12 LOAD_CONST               3 (&amp;#39;?&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;             14 BUILD_STRING             5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;             16 RETURN_VALUE&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;String literals also support the existing format string syntax of the &lt;code&gt;str.format()&lt;/code&gt; method. That allows you to solve the same formatting problems we&amp;rsquo;ve discussed in the previous two sections:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hey {name}, there&amp;#39;s a {errno:#x} error!&amp;quot;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;quot;Hey Bob, there&amp;#39;s a 0xbadc0ffee error!&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Python&amp;rsquo;s new formatted string literals are similar to JavaScript&amp;rsquo;s &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals&quot;&gt;Template Literals added in ES2015&lt;/a&gt;. I think they&amp;rsquo;re quite a nice addition to Python, and I&amp;rsquo;ve already started using them in my day to day (Python 3) work. You can learn more about formatted string literals in our &lt;a href=&quot;https://realpython.com/python-f-strings/&quot;&gt;in-depth Python f-strings tutorial&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;4-template-strings-standard-library&quot;&gt;#4 Template Strings (Standard Library)&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s one more tool for string formatting in Python: template strings. It&amp;rsquo;s a simpler and less powerful mechanism, but in some cases this might be exactly what you&amp;rsquo;re looking for.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at a simple greeting example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Template&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Hey, $name!&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;substitute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;Hey, Bob!&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You see here that we need to import the &lt;code&gt;Template&lt;/code&gt; class from Python&amp;rsquo;s built-in &lt;code&gt;string&lt;/code&gt; module. Template strings are not a core language feature but they&amp;rsquo;re supplied by the &lt;a href=&quot;https://docs.python.org/3/library/string.html&quot;&gt;&lt;code&gt;string&lt;/code&gt; module in the standard library&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Another difference is that template strings don&amp;rsquo;t allow format specifiers. So in order to get the previous error string example to work, you&amp;rsquo;ll need to manually transform the &lt;code&gt;int&lt;/code&gt; error number into a hex-string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;templ_string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Hey $name, there is a $error error!&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;templ_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;substitute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;errno&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;Hey Bob, there is a 0xbadc0ffee error!&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That worked great.&lt;/p&gt;
&lt;p&gt;So when should you use template strings in your Python programs? In my opinion, the best time to use template strings is when you&amp;rsquo;re handling formatted strings generated by users of your program. Due to their reduced complexity, template strings are a safer choice.&lt;/p&gt;
&lt;p&gt;The more complex formatting mini-languages of the other string formatting techniques might introduce security vulnerabilities to your programs. For example, it&amp;rsquo;s &lt;a href=&quot;http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/&quot;&gt;possible for format strings to access arbitrary variables in your program&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;That means, if a malicious user can supply a format string, they can potentially leak secret keys and other sensitive information! Here&amp;rsquo;s a simple proof of concept of how this attack might be used against your code:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# This is our super secret key:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SECRET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;this-is-a-secret&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;     &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fm&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;         &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# A malicious user can craft a format string that&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# can read data from the global namespace:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;{error.__init__.__globals__[SECRET]}&amp;#39;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# This allows them to exfiltrate sensitive information,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# like the secret key:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;this-is-a-secret&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;See how a hypothetical attacker was able to extract our secret string by accessing the &lt;code&gt;__globals__&lt;/code&gt; dictionary from a malicious format string? Scary, huh? Template strings close this attack vector. This makes them a safer choice if you&amp;rsquo;re handling format strings generated from user input:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_input&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;${error.__init__.__globals__[SECRET]}&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;substitute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;ValueError:&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;quot;Invalid placeholder in string: line 1, col 1&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;which-string-formatting-method-should-you-use&quot;&gt;Which String Formatting Method Should You Use?&lt;/h2&gt;
&lt;p&gt;I totally get that having so much choice for how to format your strings in Python can feel very confusing. This is an excellent cue to bust out this handy flowchart infographic I&amp;rsquo;ve put together for you:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/python-string-formatting-flowchart.4ecf0148fd87.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66 rounded&quot; src=&quot;https://files.realpython.com/media/python-string-formatting-flowchart.4ecf0148fd87.png&quot; width=&quot;706&quot; height=&quot;989&quot; alt=&quot;Python String Formatting Flowchart&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Python String Formatting Rule of Thumb (&lt;a href=&quot;https://twitter.com/intent/tweet/?text=Python%20String%20Formatting%20Rule%20of%20Thumb&amp;url=https://realpython.com/python-string-formatting/&quot; target=&quot;_blank&quot;&gt;Click to Tweet&lt;/a&gt;)&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;This flowchart is based on the rule of thumb that I apply when I&amp;rsquo;m writing Python:&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Python String Formatting Rule of Thumb:&lt;/strong&gt; If your format strings are user-supplied, use &lt;a href=&quot;#4-template-strings-standard-library&quot;&gt;Template Strings (#4)&lt;/a&gt; to avoid security issues. Otherwise, use &lt;a href=&quot;#3-string-interpolation-f-strings-python-36&quot;&gt;Literal String Interpolation/f-Strings (#3)&lt;/a&gt; if you&amp;rsquo;re on Python 3.6+, and &lt;a href=&quot;#2-new-style-string-formatting-strformat&quot;&gt;&amp;ldquo;New Style&amp;rdquo; str.format (#2)&lt;/a&gt; if you&amp;rsquo;re not.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;key-takeaways&quot;&gt;Key Takeaways&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Perhaps surprisingly, there&amp;rsquo;s more than one way to handle string formatting in Python.&lt;/li&gt;
&lt;li&gt;Each method has its individual pros and cons. Your use case will influence which method you should use.&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;re having trouble deciding which string formatting method to use, try our &lt;em&gt;Python String Formatting Rule of Thumb&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python Histogram Plotting: NumPy, Matplotlib, Pandas &amp; Seaborn</title>
      <id>https://realpython.com/python-histograms/</id>
      <link href="https://realpython.com/python-histograms/"/>
      <updated>2018-07-02T14:00:00+00:00</updated>
      <summary>In this tutorial, you&#39;ll be equipped to make production-quality, presentation-ready Python histogram plots with a range of choices and features. It&#39;s your one-stop shop for constructing &amp; manipulating histograms with Python&#39;s scientific stack.</summary>
      <content type="html">
        &lt;p&gt;In this tutorial, you&amp;rsquo;ll be equipped to make production-quality, presentation-ready Python histogram plots with a range of choices and features.&lt;/p&gt;
&lt;p&gt;If you have introductory to intermediate knowledge in Python and statistics, you can use this article as a one-stop shop for building and plotting histograms in Python using libraries from its scientific stack, including NumPy, Matplotlib, Pandas, and Seaborn.&lt;/p&gt;
&lt;p&gt;A histogram is a great tool for quickly assessing a &lt;a href=&quot;https://en.wikipedia.org/wiki/Probability_distribution&quot;&gt;probability distribution&lt;/a&gt; that is intuitively understood by almost any audience.  Python offers a handful of different options for building and plotting histograms.  Most people know a histogram by its graphical representation, which is similar to a bar graph:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/commute_times.621e5b1ce062.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-75&quot; src=&quot;https://files.realpython.com/media/commute_times.621e5b1ce062.png&quot; width=&quot;1152&quot; height=&quot;888&quot; alt=&quot;Histogram of commute times for 1000 commuters&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This article will guide you through creating plots like the one above as well as more complex ones.  Here&amp;rsquo;s what you&amp;rsquo;ll cover:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Building histograms in pure Python, without use of third party libraries&lt;/li&gt;
&lt;li&gt;Constructing histograms with NumPy to summarize the underlying data&lt;/li&gt;
&lt;li&gt;Plotting the resulting histogram with Matplotlib, Pandas, and Seaborn&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; Short on time? &lt;a href=&quot;https://realpython.com/optins/view/histograms-cheatsheet/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-histograms-cheatsheet&quot; data-focus=&quot;false&quot;&gt;Click here to get access to a free two-page Python histograms cheat sheet&lt;/a&gt; that summarizes the techniques explained in this tutorial.&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;histograms-in-pure-python&quot;&gt;Histograms in Pure Python&lt;/h2&gt;
&lt;p&gt;When you are preparing to plot a histogram, it is simplest to not think in terms of bins but rather to report how many times each value appears (a frequency table).  A Python &lt;a href=&quot;https://docs.python.org/3/tutorial/datastructures.html#dictionaries&quot;&gt;dictionary&lt;/a&gt; is well-suited for this task:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Need not be sorted, necessarily&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;count_elements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Tally elements from `seq`.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count_elements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counted&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{0: 1, 1: 3, 2: 1, 3: 1, 7: 2, 23: 1}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;count_elements()&lt;/code&gt; returns a dictionary with unique elements from the sequence as keys and their frequencies (counts) as values.  Within the loop over &lt;code&gt;seq&lt;/code&gt;, &lt;code&gt;hist[i] = hist.get(i, 0) + 1&lt;/code&gt; says, &amp;ldquo;for each element of the sequence, increment its corresponding value in &lt;code&gt;hist&lt;/code&gt; by 1.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;In fact, this is precisely what is done by the &lt;code&gt;collections.Counter&lt;/code&gt; class from Python&amp;rsquo;s standard library, which &lt;a href=&quot;https://github.com/python/cpython/blob/7f1bcda9bc3c04100cb047373732db0eba00e581/Lib/collections/__init__.py#L466&quot;&gt;subclasses&lt;/a&gt; a Python dictionary and overrides its &lt;code&gt;.update()&lt;/code&gt; method:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;collections&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recounted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recounted&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Counter({0: 1, 1: 3, 3: 1, 2: 1, 7: 2, 23: 1})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can confirm that your handmade function does virtually the same thing as &lt;code&gt;collections.Counter&lt;/code&gt; by testing for equality between the two:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recounted&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counted&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Technical Detail&lt;/strong&gt;: The mapping from &lt;code&gt;count_elements()&lt;/code&gt; above defaults to a more highly optimized &lt;a href=&quot;https://github.com/python/cpython/blob/a5c42284e69fb309bdd17ee8c1c120d1be383012/Modules/_collectionsmodule.c#L2250&quot;&gt;C function&lt;/a&gt; if it is available.  Within the Python function &lt;code&gt;count_elements()&lt;/code&gt;, one micro-optimization you could make is to declare &lt;code&gt;get = hist.get&lt;/code&gt; before the for-loop.  This would bind a method to a variable for faster calls within the loop.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;It can be helpful to build simplified functions from scratch as a first step to understanding more complex ones. Let&amp;rsquo;s further reinvent the wheel a bit with an ASCII histogram that takes advantage of Python&amp;rsquo;s &lt;a href=&quot;https://docs.python.org/tutorial/inputoutput.html#fancier-output-formatting&quot;&gt;output formatting&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ascii_histogram&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;A horizontal frequency-table/histogram plot.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;counted&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count_elements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;k&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0:5d}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;+&amp;#39;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;counted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This function creates a sorted frequency plot where counts are represented as tallies of plus (&lt;code&gt;+&lt;/code&gt;) symbols.  Calling &lt;code&gt;sorted()&lt;/code&gt; on a dictionary returns a sorted list of its keys, and then you access the corresponding value for each with &lt;code&gt;counted[k]&lt;/code&gt;.  To see this in action, you can create a slightly larger dataset with Python&amp;rsquo;s &lt;code&gt;random&lt;/code&gt; module:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# No NumPy ... yet&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vals&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Each number in `vals` will occur between 5 and 15 times.&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;randint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;freq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ascii_histogram&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    1 +++++++&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    3 ++++++++++++++&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    4 ++++++&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    6 +++++++++&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    8 ++++++&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    9 ++++++++++++&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;   10 ++++++++++++&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, you&amp;rsquo;re simulating plucking from &lt;code&gt;vals&lt;/code&gt; with frequencies given by &lt;code&gt;freq&lt;/code&gt; (a &lt;a href=&quot;https://www.python.org/dev/peps/pep-0289/&quot;&gt;generator expression&lt;/a&gt;).  The resulting sample data repeats each value from &lt;code&gt;vals&lt;/code&gt; a certain number of times between 5 and 15.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;a href=&quot;https://docs.python.org/library/random.html#random.seed&quot;&gt;&lt;code&gt;random.seed()&lt;/code&gt;&lt;/a&gt; is use to seed, or initialize, the underlying pseudorandom number generator (&lt;a href=&quot;https://en.wikipedia.org/wiki/Pseudorandom_number_generator&quot;&gt;PRNG&lt;/a&gt;) used by &lt;code&gt;random&lt;/code&gt;.  It may sound like an oxymoron, but this is a way of making random data reproducible and deterministic.  That is, if you copy the code here as is, you should get exactly the same histogram because the first call to &lt;code&gt;random.randint()&lt;/code&gt; after seeding the generator will produce identical &amp;ldquo;random&amp;rdquo; data using the &lt;a href=&quot;https://en.wikipedia.org/wiki/Mersenne_Twister&quot;&gt;Mersenne Twister&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;building-up-from-the-base-histogram-calculations-in-numpy&quot;&gt;Building Up From the Base: Histogram Calculations in NumPy&lt;/h2&gt;
&lt;p&gt;Thus far, you have been working with what could best be called &amp;ldquo;frequency tables.&amp;rdquo;  But mathematically, a histogram is a mapping of bins (intervals) to frequencies.  More technically, it can be used to approximate the probability density function (&lt;a href=&quot;https://en.wikipedia.org/wiki/Probability_density_function&quot;&gt;PDF&lt;/a&gt;) of the underlying variable.&lt;/p&gt;
&lt;p&gt;Moving on from the &amp;ldquo;frequency table&amp;rdquo; above, a true histogram first &amp;ldquo;bins&amp;rdquo; the range of values and then counts the number of values that fall into each bin.  This is what &lt;a href=&quot;https://realpython.com/numpy-array-programming/&quot;&gt;NumPy&amp;rsquo;s&lt;/a&gt; &lt;code&gt;histogram()&lt;/code&gt; function does, and it is the basis for other functions you&amp;rsquo;ll see here later in Python libraries such as Matplotlib and Pandas.  &lt;/p&gt;
&lt;p&gt;Consider a sample of floats drawn from the &lt;a href=&quot;https://en.wikipedia.org/wiki/Laplace_distribution&quot;&gt;Laplace distribution&lt;/a&gt;.  This distribution has fatter tails than a normal distribution and has two descriptive parameters (location and scale):&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;np&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# `numpy.random` uses its own PRNG.&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;444&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_printoptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;precision&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;laplace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([18.406, 18.087, 16.004, 16.221,  7.358])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this case, you&amp;rsquo;re working with a continuous distribution, and it wouldn&amp;rsquo;t be very helpful to tally each float independently, down to the umpteenth decimal place.  Instead, you can bin or &amp;ldquo;bucket&amp;rdquo; the data and count the observations that fall into each bin.  The histogram is the resulting count of values within each bin:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bin_edges&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;histogram&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([ 1,  0,  3,  4,  4, 10, 13,  9,  2,  4])&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bin_edges&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([ 3.217,  5.199,  7.181,  9.163, 11.145, 13.127, 15.109, 17.091,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       19.073, 21.055, 23.037])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This result may not be immediately intuitive.  &lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html&quot;&gt;&lt;code&gt;np.histogram()&lt;/code&gt;&lt;/a&gt; by default uses 10 equally sized bins and returns a tuple of the frequency counts and corresponding bin edges.  They are edges in the sense that there will be one more bin edge than there are members of the histogram:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bin_edges&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(10, 11)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Technical Detail&lt;/strong&gt;: All but the last (rightmost) bin is half-open.  That is, all bins but the last are [inclusive, exclusive), and the final bin is [inclusive, inclusive].&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;A very condensed breakdown of how the bins are constructed &lt;a href=&quot;https://github.com/numpy/numpy/blob/6a58e25703cbecb6786faa09a04ae2ec8221348b/numpy/lib/function_base.py#L432-L844&quot;&gt;by NumPy&lt;/a&gt; looks like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# The leftmost and rightmost bin edges&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first_edge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;last_edge&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_equal_bins&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# NumPy&amp;#39;s default&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bin_edges&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;linspace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first_edge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;last_edge&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                        &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n_equal_bins&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;endpoint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bin_edges&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([ 0. ,  2.3,  4.6,  6.9,  9.2, 11.5, 13.8, 16.1, 18.4, 20.7, 23. ])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The case above makes a lot of sense: 10 equally spaced bins over a peak-to-peak range of 23 means intervals of width 2.3.&lt;/p&gt;
&lt;p&gt;From there, the function delegates to either &lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.bincount.html&quot;&gt;&lt;code&gt;np.bincount()&lt;/code&gt;&lt;/a&gt; or &lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.searchsorted.html&quot;&gt;&lt;code&gt;np.searchsorted()&lt;/code&gt;&lt;/a&gt;.  &lt;code&gt;bincount()&lt;/code&gt; itself can be used to effectively construct the &amp;ldquo;frequency table&amp;rdquo; that you started off with here, with the distinction that values with zero occurrences are included:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bcounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bincount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;histogram&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array_equal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bcounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Reproducing `collections.Counter`&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bcounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bcounts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nonzero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{0: 1, 1: 3, 2: 1, 3: 1, 7: 2, 23: 1}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;code&gt;hist&lt;/code&gt; here is really using bins of width 1.0 rather than &amp;ldquo;discrete&amp;rdquo; counts.  Hence, this only works for counting integers, not floats such as &lt;code&gt;[3.9, 4.1, 4.15]&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;visualizing-histograms-with-matplotlib-and-pandas&quot;&gt;Visualizing Histograms with Matplotlib and Pandas&lt;/h2&gt;
&lt;p&gt;Now that you&amp;rsquo;ve seen how to build a histogram in Python from the ground up, let&amp;rsquo;s see how other Python packages can do the job for you.  &lt;a href=&quot;https://realpython.com/python-matplotlib-guide/&quot;&gt;Matplotlib&lt;/a&gt; provides the functionality to visualize Python histograms out of the box with a versatile wrapper around NumPy&amp;rsquo;s &lt;code&gt;histogram()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;plt&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# An &amp;quot;interface&amp;quot; to matplotlib.axes.Axes.hist() method&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;patches&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;auto&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;#0504aa&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;alpha&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rwidth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.85&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;y&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alpha&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.75&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xlabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Value&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ylabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Frequency&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;My Very Own Histogram&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;23&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;45&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;$\mu=15, b=3$&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;maxfreq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Set a clean upper y-axis limit.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ylim&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ymax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ceil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;maxfreq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxfreq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxfreq&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/my_very_own_histogram.d411ea1cb95c.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-75&quot; src=&quot;https://files.realpython.com/media/my_very_own_histogram.d411ea1cb95c.png&quot; width=&quot;1280&quot; height=&quot;960&quot; alt=&quot;Histogram&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As defined earlier, a plot of a histogram uses its bin edges on the x-axis and the corresponding frequencies on the y-axis.  In the chart above, passing &lt;code&gt;bins=&#39;auto&#39;&lt;/code&gt; chooses between two algorithms to estimate the &amp;ldquo;ideal&amp;rdquo; number of bins.  At a high level, the goal of the algorithm is to choose a bin width that generates the most faithful representation of the data.  For more on this subject, which can get pretty technical, check out &lt;a href=&quot;http://docs.astropy.org/en/stable/visualization/histogram.html&quot;&gt;Choosing Histogram Bins&lt;/a&gt; from the Astropy docs.&lt;/p&gt;
&lt;p&gt;Staying in Python&amp;rsquo;s scientific stack, Pandas&amp;rsquo; &lt;code&gt;Series.histogram()&lt;/code&gt; &lt;a href=&quot;https://github.com/pandas-dev/pandas/blob/cbec58eacd8e9cd94b7f42351b8de4559c250909/pandas/plotting/_core.py#L1310&quot;&gt;uses &lt;code&gt;matplotlib.pyplot.hist()&lt;/code&gt;&lt;/a&gt; to draw a Matplotlib histogram of the input Series:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pd&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Generate data on commute times.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;commutes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Series&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gamma&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;commutes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rwidth&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                   &lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;#607c8e&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Commute Times for 1,000 Commuters&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;xlabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Counts&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ylabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Commute Time&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;y&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alpha&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.75&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/commute_times.621e5b1ce062.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-75&quot; src=&quot;https://files.realpython.com/media/commute_times.621e5b1ce062.png&quot; width=&quot;1152&quot; height=&quot;888&quot; alt=&quot;Histogram of commute times for 1000 commuters&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;pandas.DataFrame.histogram()&lt;/code&gt; is similar but produces a histogram for each column of data in the DataFrame.&lt;/p&gt;
&lt;h2 id=&quot;plotting-a-kernel-density-estimate-kde&quot;&gt;Plotting a Kernel Density Estimate (KDE)&lt;/h2&gt;
&lt;p&gt;In this tutorial, you&amp;rsquo;ve been working with samples, statistically speaking.  Whether the data is discrete or continuous, it&amp;rsquo;s assumed to be derived from a population that has a true, exact distribution described by just a few parameters.&lt;/p&gt;
&lt;p&gt;A kernel density estimation (KDE) is a way to estimate the probability density function (PDF) of the random variable that &amp;ldquo;underlies&amp;rdquo; our sample.  KDE is a means of data smoothing.&lt;/p&gt;
&lt;p&gt;Sticking with the Pandas library, you can create and overlay density plots using &lt;code&gt;plot.kde()&lt;/code&gt;, which is available for both &lt;code&gt;Series&lt;/code&gt; and &lt;code&gt;DataFrame&lt;/code&gt; objects.  But first, let&amp;rsquo;s generate two distinct data samples for comparison:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Sample from two different normal distributions&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;means&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdevs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataFrame&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;normal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;means&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scale&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stdevs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)),&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dist&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;agg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;min&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;max&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;mean&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;std&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;round&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decimals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;          a      b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;min   -1.57  12.46&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;max   25.32  26.44&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;mean  10.12  19.94&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;std    3.94   1.94&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now, to plot each histogram on the same Matplotlib axes:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subplots&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;dist&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kde&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;legend&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Histogram: A vs. B&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;dist&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hist&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;density&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_ylabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Probability&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;y&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_facecolor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;#d8dcd6&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/a_vs_b.7528322a9e65.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-75&quot; src=&quot;https://files.realpython.com/media/a_vs_b.7528322a9e65.png&quot; width=&quot;1280&quot; height=&quot;960&quot; alt=&quot;Histogram&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;These methods leverage SciPy&amp;rsquo;s &lt;a href=&quot;https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.gaussian_kde.html&quot;&gt;&lt;code&gt;gaussian_kde()&lt;/code&gt;&lt;/a&gt;, which results in a smoother-looking PDF.&lt;/p&gt;
&lt;p&gt;If you take a closer look at this function, you can see how well it approximates the &amp;ldquo;true&amp;rdquo; PDF for a relatively small sample of 1000 data points.  Below, you can first build the &amp;ldquo;analytical&amp;rdquo; distribution with &lt;code&gt;scipy.stats.norm()&lt;/code&gt;.  This is a class instance that encapsulates the statistical standard normal distribution, its moments, and descriptive functions.  Its PDF is &amp;ldquo;exact&amp;rdquo; in the sense that it is defined precisely as &lt;code&gt;norm.pdf(x) = exp(-x**2/2) / sqrt(2*pi)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Building from there, you can take a random sample of 1000 datapoints from this distribution, then attempt to back into an estimation of the PDF with &lt;code&gt;scipy.stats.gaussian_kde()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scipy&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stats&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# An object representing the &amp;quot;frozen&amp;quot; analytical distribution&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Defaults to the standard normal distribution, N~(0, 1)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;dist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;norm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Draw random samples from the population you built above.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# This is just a sample, so the mean and std. deviation should&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# be close to (1, 0).&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;samp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dist&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rvs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# `ppf()`: percent point function (inverse of cdf — percentiles).&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;linspace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;norm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ppf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;stop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;norm&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ppf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.99&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;250&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gkde&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gaussian_kde&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dataset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;samp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# `gkde.evaluate()` estimates the PDF itself.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;fig&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;plt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subplots&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dist&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pdf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;linestyle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;solid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;red&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;alpha&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Analytical (True) PDF&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gkde&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;linestyle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;dashed&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;black&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lw&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;PDF Estimated via KDE&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;legend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;best&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;frameon&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Analytical vs. Estimated PDF&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_ylabel&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Probability&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ax&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;$f(x) = \frac{\exp(-x^2/2)}{\sqrt{2*\pi}}$&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;fontsize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/analytic_v_estimated.44711de28f1d.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-75&quot; src=&quot;https://files.realpython.com/media/analytic_v_estimated.44711de28f1d.png&quot; width=&quot;1280&quot; height=&quot;960&quot; alt=&quot;Chart&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a bigger chunk of code, so let&amp;rsquo;s take a second to touch on a few key lines:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SciPy&amp;rsquo;s &lt;a href=&quot;https://docs.scipy.org/doc/scipy/reference/stats.html&quot;&gt;&lt;code&gt;stats&lt;/code&gt; subpackage&lt;/a&gt; lets you create Python objects that represent analytical distributions that you can sample from to create actual data.  So &lt;code&gt;dist = stats.norm()&lt;/code&gt; represents a normal continuous random variable, and you generate random numbers from it with &lt;code&gt;dist.rvs()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;To evaluate both the analytical PDF and the Gaussian KDE, you need an array &lt;code&gt;x&lt;/code&gt; of quantiles (standard deviations above/below the mean, for a normal distribution).  &lt;code&gt;stats.gaussian_kde()&lt;/code&gt; represents an estimated PDF that you need to evaluate on an array to produce something visually meaningful in this case.&lt;/li&gt;
&lt;li&gt;The last line contains some &lt;a href=&quot;https://matplotlib.org/users/usetex.html&quot;&gt;LaTex&lt;/a&gt;, which integrates nicely with Matplotlib.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;a-fancy-alternative-with-seaborn&quot;&gt;A Fancy Alternative with Seaborn&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s bring one more Python package into the mix. Seaborn has a &lt;code&gt;displot()&lt;/code&gt; function that plots the histogram and KDE for a univariate distribution in one step.  Using the NumPy array &lt;code&gt;d&lt;/code&gt; from ealier:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;seaborn&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sns&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;sns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;darkgrid&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;sns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;distplot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/seaborn_distplot.b10bb7c29d85.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-75&quot; src=&quot;https://files.realpython.com/media/seaborn_distplot.b10bb7c29d85.png&quot; width=&quot;1280&quot; height=&quot;960&quot; alt=&quot;Seaborn&amp;#39;s distplot&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The call above produces a KDE.  There is also optionality to fit a specific distribution to the data.  This is different than a KDE and consists of parameter estimation for generic data and a specified distribution name:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;distplot&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stats&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;laplace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kde&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/seaborn_fitted.106107494ccf.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-75&quot; src=&quot;https://files.realpython.com/media/seaborn_fitted.106107494ccf.png&quot; width=&quot;1280&quot; height=&quot;960&quot; alt=&quot;Histogram with fitted laplace distribution&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Again, note the slight difference.  In the first case, you&amp;rsquo;re estimating some unknown PDF; in the second, you&amp;rsquo;re taking a known distribution and finding what parameters best describe it given the empirical data.&lt;/p&gt;
&lt;h2 id=&quot;other-tools-in-pandas&quot;&gt;Other Tools in Pandas&lt;/h2&gt;
&lt;p&gt;In addition to its plotting tools, Pandas also offers a convenient &lt;code&gt;.value_counts()&lt;/code&gt; method that computes a histogram of non-null values to a Pandas &lt;code&gt;Series&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pandas&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pd&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;                        &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;linspace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Series&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value_counts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;9    1831&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;8    1624&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;7    1423&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6    1323&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5    1089&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4     888&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3     770&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2     535&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1     347&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0     170&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;dtype: int64&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value_counts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;9    0.1831&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;8    0.1624&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;7    0.1423&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6    0.1323&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5    0.1089&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;dtype: float64&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Elsewhere, &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.cut.html&quot;&gt;&lt;code&gt;pandas.cut()&lt;/code&gt;&lt;/a&gt; is a convenient way to bin values into arbitrary intervals.  Let&amp;rsquo;s say you have some data on ages of individuals and want to bucket them sensibly:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ages&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Series&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;51&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;52&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bins&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# The edges&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;child&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;preteen&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;teen&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;military_age&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;adult&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groups&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;labels&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groups&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value_counts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;child           6&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;adult           5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;teen            3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;military_age    2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;preteen         1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;dtype: int64&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;concat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ages&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;groups&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;axis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;columns&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;age&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;group&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;    age         group&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0     1         child&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1     1         child&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2     3         child&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3     5         child&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4     8         child&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5    10         child&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6    12       preteen&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;7    15          teen&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;8    18          teen&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;9    18          teen&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;10   19  military_age&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;11   20  military_age&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;12   25         adult&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;13   30         adult&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;14   40         adult&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;15   51         adult&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;16   52         adult&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What&amp;rsquo;s nice is that both of these operations ultimately &lt;a href=&quot;https://github.com/pandas-dev/pandas/tree/master/pandas/_libs&quot;&gt;utilize Cython code&lt;/a&gt; that makes them competitive on speed while maintaining their flexibility.&lt;/p&gt;
&lt;h2 id=&quot;alright-so-which-should-i-use&quot;&gt;Alright, So Which Should I Use?&lt;/h2&gt;
&lt;p&gt;At this point, you&amp;rsquo;ve seen more than a handful of functions and methods to choose from for plotting a Python histogram.  How do they compare?  In short, there is no &amp;ldquo;one-size-fits-all.&amp;rdquo;  Here&amp;rsquo;s a recap of the functions and methods you&amp;rsquo;ve covered thus far, all of which relate to breaking down and representing distributions in Python:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;You Have/Want To&lt;/th&gt;
&lt;th&gt;Consider Using&lt;/th&gt;
&lt;th&gt;Note(s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Clean-cut integer data housed in a data structure such as a list, tuple, or set, and you want to create a Python histogram without importing any third party libraries.&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://docs.python.org/3.6/library/collections.html#collections.Counter&quot;&gt;&lt;code&gt;collections.counter()&lt;/code&gt;&lt;/a&gt; from the Python standard library offers a fast and straightforward way to get frequency counts from a container of data.&lt;/td&gt;
&lt;td&gt;This is a frequency table, so it doesn&amp;rsquo;t use the concept of binning as a &amp;ldquo;true&amp;rdquo; histogram does.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large array of data, and you want to compute the &amp;ldquo;mathematical&amp;rdquo; histogram that represents bins and the corresponding frequencies.&lt;/td&gt;
&lt;td&gt;NumPy&amp;rsquo;s  &lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html&quot;&gt;&lt;code&gt;np.histogram()&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.bincount.html&quot;&gt;&lt;code&gt;np.bincount()&lt;/code&gt;&lt;/a&gt; are useful for computing the histogram values numerically and the corresponding bin edges.&lt;/td&gt;
&lt;td&gt;For more, check out &lt;a href=&quot;https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html&quot;&gt;&lt;code&gt;np.digitize()&lt;/code&gt;&lt;/a&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tabular data in Pandas&amp;rsquo; &lt;code&gt;Series&lt;/code&gt; or &lt;code&gt;DataFrame&lt;/code&gt; object.&lt;/td&gt;
&lt;td&gt;Pandas methods such as &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.plot.hist.html&quot;&gt;&lt;code&gt;Series.plot.hist()&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.plot.hist.html&quot;&gt;&lt;code&gt;DataFrame.plot.hist()&lt;/code&gt;&lt;/a&gt;, &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.value_counts.html&quot;&gt;&lt;code&gt;Series.value_counts()&lt;/code&gt;&lt;/a&gt;, and &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.cut.html&quot;&gt;&lt;code&gt;cut()&lt;/code&gt;&lt;/a&gt;, as well as &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.plot.kde.html&quot;&gt;&lt;code&gt;Series.plot.kde()&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.plot.kde.html&quot;&gt;&lt;code&gt;DataFrame.plot.kde()&lt;/code&gt;&lt;/a&gt;.&lt;/td&gt;
&lt;td&gt;Check out the Pandas &lt;a href=&quot;https://pandas.pydata.org/pandas-docs/stable/visualization.html&quot;&gt;visualization docs&lt;/a&gt; for inspiration.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create a highly customizable, fine-tuned plot from any data structure.&lt;/td&gt;
&lt;td&gt;&lt;a href=&quot;https://matplotlib.org/api/_as_gen/matplotlib.pyplot.hist.html&quot;&gt;&lt;code&gt;pyplot.hist()&lt;/code&gt;&lt;/a&gt; is a widely used histogram plotting function that uses &lt;code&gt;np.histogram()&lt;/code&gt; and is the basis for Pandas&amp;rsquo; plotting functions.&lt;/td&gt;
&lt;td&gt;Matplotlib, and especially its &lt;a href=&quot;https://realpython.com/python-matplotlib-guide/&quot;&gt;object-oriented framework&lt;/a&gt;, is great for fine-tuning the details of a histogram.  This interface can take a bit of time to master, but ultimately allows you to be very precise in how any visualization is laid out.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pre-canned design and integration.&lt;/td&gt;
&lt;td&gt;Seaborn&amp;rsquo;s &lt;a href=&quot;https://seaborn.pydata.org/generated/seaborn.distplot.html&quot;&gt;&lt;code&gt;distplot()&lt;/code&gt;&lt;/a&gt;, for combining a histogram and KDE plot or plotting distribution-fitting.&lt;/td&gt;
&lt;td&gt;Essentially a &amp;ldquo;wrapper around a wrapper&amp;rdquo; that leverages a Matplotlib histogram internally, which in turn utilizes NumPy.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; Short on time? &lt;a href=&quot;https://realpython.com/optins/view/histograms-cheatsheet/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-histograms-cheatsheet&quot; data-focus=&quot;false&quot;&gt;Click here to get access to a free two-page Python histograms cheat sheet&lt;/a&gt; that summarizes the techniques explained in this tutorial.&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;You can also find the code snippets from this article together in one &lt;a href=&quot;https://github.com/realpython/materials/tree/master/histograms&quot;&gt;script&lt;/a&gt; at the Real Python materials page.&lt;/p&gt;
&lt;p&gt;With that, good luck creating histograms in the wild.  Hopefully one of the tools above will suit your needs.  Whatever you do, just &lt;a href=&quot;http://www.businessinsider.com/pie-charts-are-the-worst-2013-6&quot;&gt;don&amp;rsquo;t use a pie chart&lt;/a&gt;.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Cool New Features in Python 3.7</title>
      <id>https://realpython.com/python37-new-features/</id>
      <link href="https://realpython.com/python37-new-features/"/>
      <updated>2018-06-27T14:00:00+00:00</updated>
      <summary>Python 3.7 is officially released. In this article you&#39;ll do a deep dive into some of the biggest pieces of news and new features in the latest and greatest CPython release.</summary>
      <content type="html">
        &lt;p&gt;Python 3.7 is &lt;a href=&quot;https://www.python.org/downloads/release/python-370/&quot;&gt;officially released&lt;/a&gt;! This new Python version has been in development since &lt;a href=&quot;https://www.python.org/dev/peps/pep-0537/&quot;&gt;September 2016&lt;/a&gt;, and now we all get to enjoy the results of the core developers&amp;rsquo; hard work.&lt;/p&gt;
&lt;p&gt;What does the new Python version bring? While the &lt;a href=&quot;https://docs.python.org/3.7/whatsnew/3.7.html&quot;&gt;documentation&lt;/a&gt; gives a good overview of the new features, this article will take a deep dive into some of the biggest pieces of news. These include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Easier access to debuggers through a new &lt;code&gt;breakpoint()&lt;/code&gt; built-in&lt;/li&gt;
&lt;li&gt;Simple class creation using data classes&lt;/li&gt;
&lt;li&gt;Customized access to module attributes&lt;/li&gt;
&lt;li&gt;Improved support for type hinting&lt;/li&gt;
&lt;li&gt;Higher precision timing functions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;More importantly, Python 3.7 is fast.&lt;/p&gt;
&lt;p&gt;In the final sections of this article, you&amp;rsquo;ll read more about this speed, as well as some of the other cool features of Python 3.7. You will also get some advice on upgrading to the new version.&lt;/p&gt;
&lt;h2 id=&quot;the-breakpoint-built-in&quot;&gt;The &lt;code&gt;breakpoint()&lt;/code&gt; Built-In&lt;/h2&gt;
&lt;p&gt;While we might strive to write perfect code, the simple truth is that we never do. Debugging is an important part of programming. Python 3.7 introduces the new built-in function &lt;code&gt;breakpoint()&lt;/code&gt;. This does not really add any new functionality to Python, but it makes using debuggers more flexible and intuitive.&lt;/p&gt;
&lt;p&gt;Assume that you have the following buggy code in the file &lt;code&gt;bugs.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;divide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;divide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Running the code causes a &lt;code&gt;ZeroDivisionError&lt;/code&gt; inside the &lt;code&gt;divide()&lt;/code&gt; function. Let&amp;rsquo;s say that you want to interrupt your code and drop into a &lt;a href=&quot;https://realpython.com/python-debugging-pdb/&quot;&gt;debugger&lt;/a&gt; right at the top of &lt;code&gt;divide()&lt;/code&gt;. You can do so by setting a so called &amp;ldquo;breakpoint&amp;rdquo; in your code:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;divide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Insert breakpoint here&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A breakpoint is a signal inside your code that execution should temporarily stop, so that you can look around at the current state of the program. How do you place the breakpoint? In Python 3.6 and below, you use this somewhat cryptic line:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;divide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pdb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pdb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_trace&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, &lt;a href=&quot;https://docs.python.org/library/pdb.html&quot;&gt;&lt;code&gt;pdb&lt;/code&gt;&lt;/a&gt; is the Python Debugger from the standard library. In Python 3.7, you can use the new &lt;code&gt;breakpoint()&lt;/code&gt; function call as a shortcut instead:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;divide&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;breakpoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the background, &lt;code&gt;breakpoint()&lt;/code&gt; is first importing &lt;code&gt;pdb&lt;/code&gt; and then calling &lt;code&gt;pdb.set_trace()&lt;/code&gt; for you. The obvious benefits are that &lt;code&gt;breakpoint()&lt;/code&gt; is easier to remember and that you only need to type 12 characters instead of 27. However, the real bonus of using &lt;code&gt;breakpoint()&lt;/code&gt; is its customizability.&lt;/p&gt;
&lt;p&gt;Run your &lt;code&gt;bugs.py&lt;/code&gt; script with &lt;code&gt;breakpoint()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3.7 bugs.py 
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&lt;/span&gt; /home/gahjelle/bugs.py&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;divide&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; return f / e&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(Pdb)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The script will break when it reaches &lt;code&gt;breakpoint()&lt;/code&gt; and drop you into a PDB debugging session. You can type &lt;code&gt;c&lt;/code&gt; and hit &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt; to continue the script. Refer to &lt;a href=&quot;https://realpython.com/python-debugging-pdb/&quot;&gt;Nathan Jennings&amp;rsquo; PDB guide&lt;/a&gt; if you want to learn more about PDB and debugging.&lt;/p&gt;
&lt;p&gt;Now, say that you think you&amp;rsquo;ve fixed the bug. You would like to run the script again but without stopping in the debugger. You could, of course, comment out the &lt;code&gt;breakpoint()&lt;/code&gt; line, but another option is to use the &lt;code&gt;PYTHONBREAKPOINT&lt;/code&gt; environment variable. This variable controls the behavior of &lt;code&gt;breakpoint()&lt;/code&gt;, and setting &lt;code&gt;PYTHONBREAKPOINT=0&lt;/code&gt; means that any call to &lt;code&gt;breakpoint()&lt;/code&gt; is ignored:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;PYTHONBREAKPOINT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; python3.7 bugs.py
&lt;span class=&quot;go&quot;&gt;ZeroDivisionError: division by zero&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Oops, it seems as if you haven&amp;rsquo;t fixed the bug after all&amp;hellip;&lt;/p&gt;
&lt;p&gt;Another option is to use &lt;code&gt;PYTHONBREAKPOINT&lt;/code&gt; to specify a debugger other than PDB. For instance, to use &lt;a href=&quot;https://pypi.org/project/pudb/&quot;&gt;PuDB&lt;/a&gt; (a visual debugger in the console) you can do:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;PYTHONBREAKPOINT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;pudb.set_trace python3.7 bugs.py
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For this to work, you need to have &lt;code&gt;pudb&lt;/code&gt; installed (&lt;code&gt;pip install pudb&lt;/code&gt;). Python will take care of importing &lt;code&gt;pudb&lt;/code&gt; for you though. This way you can also set your default debugger. Simply set the &lt;code&gt;PYTHONBREAKPOINT&lt;/code&gt; environment variable to your preferred debugger. See &lt;a href=&quot;https://www.schrodinger.com/kb/1842&quot;&gt;this guide&lt;/a&gt; for instructions on how to set an environment variable on your system.&lt;/p&gt;
&lt;p&gt;The new &lt;code&gt;breakpoint()&lt;/code&gt; function does not only work with debuggers. One convenient option could be to simply start an interactive shell inside your code. For instance, to start an IPython session, you can use the following:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;PYTHONBREAKPOINT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;IPython.embed python3.7 bugs.py 
&lt;span class=&quot;go&quot;&gt;IPython 6.3.1 -- An enhanced Interactive Python. Type &amp;#39;?&amp;#39; for help.&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;In [1]: print(e / f)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can also create your own function and have &lt;code&gt;breakpoint()&lt;/code&gt; call that. The following code prints all variables in the local scope. Add it to a file called &lt;code&gt;bp_utils.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pprint&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pprint&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;print_locals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;caller&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_getframe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Caller is 1 frame up.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;pprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;caller&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f_locals&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To use this function, set &lt;code&gt;PYTHONBREAKPOINT&lt;/code&gt; as before, with the &lt;code&gt;&amp;lt;module&amp;gt;.&amp;lt;function&amp;gt;&lt;/code&gt; notation:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;PYTHONBREAKPOINT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;bp_utils.print_locals python3.7 bugs.py 
&lt;span class=&quot;go&quot;&gt;{&amp;#39;e&amp;#39;: 0, &amp;#39;f&amp;#39;: 1}&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;ZeroDivisionError: division by zero&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Normally, &lt;code&gt;breakpoint()&lt;/code&gt; will be used to call functions and methods that do not need arguments. However, it is possible to pass arguments as well. Change the line &lt;code&gt;breakpoint()&lt;/code&gt; in &lt;code&gt;bugs.py&lt;/code&gt; to:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;breakpoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;lt;-END&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The default PDB debugger will raise a &lt;code&gt;TypeError&lt;/code&gt; at this line because &lt;code&gt;pdb.set_trace()&lt;/code&gt; does not take any positional arguments.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Run this code with &lt;code&gt;breakpoint()&lt;/code&gt; masquerading as the &lt;code&gt;print()&lt;/code&gt; function to see a simple example of the arguments being passed through:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;PYTHONBREAKPOINT&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;print python3.7 bugs.py 
&lt;span class=&quot;go&quot;&gt;0 1&amp;lt;-END&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;ZeroDivisionError: division by zero&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;See &lt;a href=&quot;https://www.python.org/dev/peps/pep-0553/&quot;&gt;PEP 553&lt;/a&gt; as well as the documentation for &lt;a href=&quot;https://docs.python.org/3.7/library/functions.html#breakpoint&quot;&gt;&lt;code&gt;breakpoint()&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://docs.python.org/3.7/library/sys.html#sys.breakpointhook&quot;&gt;&lt;code&gt;sys.breakpointhook()&lt;/code&gt;&lt;/a&gt; for more information.&lt;/p&gt;
&lt;h2 id=&quot;data-classes&quot;&gt;Data Classes&lt;/h2&gt;
&lt;p&gt;The new &lt;a href=&quot;https://realpython.com/python-data-classes/&quot;&gt;&lt;code&gt;dataclasses&lt;/code&gt;&lt;/a&gt; module makes it more convenient to write your own classes, as special methods like &lt;code&gt;.__init__()&lt;/code&gt;, &lt;code&gt;.__repr__()&lt;/code&gt;, and &lt;code&gt;.__eq__()&lt;/code&gt; are added automatically. Using the &lt;code&gt;@dataclass&lt;/code&gt; decorator, you can write something like:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;dataclasses&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dataclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@dataclass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Country&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;int&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;repr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;compare&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;beach_per_person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Meters of coastline per person&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;These nine lines of code stand in for quite a bit of boilerplate code and best practices. Think about what it would take to implement &lt;code&gt;Country&lt;/code&gt; as a regular class: the &lt;code&gt;.__init__()&lt;/code&gt; method, a &lt;code&gt;repr&lt;/code&gt;, six different comparison methods as well as the &lt;code&gt;.beach_per_person()&lt;/code&gt; method. You can expand the box below to see an implementation of &lt;code&gt;Country&lt;/code&gt; that is roughly equivalent to the data class:&lt;/p&gt;
&lt;div class=&quot;card mb-3&quot; id=&quot;collapse_cardf0149d&quot;&gt;
&lt;div class=&quot;card-header border-0&quot;&gt;&lt;p class=&quot;m-0&quot;&gt;&lt;button class=&quot;btn&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapsef0149d&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapsef0149d&quot;&gt;Alternate implementation of the &amp;quot;Country&amp;quot; class&lt;/button&gt; &lt;button class=&quot;btn btn-link float-right&quot; data-toggle=&quot;collapse&quot; data-target=&quot;#collapsef0149d&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapsef0149d&quot;&gt;Show/Hide&lt;/button&gt;&lt;/p&gt;&lt;/div&gt;
&lt;div id=&quot;collapsef0149d&quot; class=&quot;collapse&quot; data-parent=&quot;#collapse_cardf0149d&quot;&gt;&lt;div class=&quot;card-body&quot; markdown=&quot;1&quot;&gt;

&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Country&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;area&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__repr__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Country(name=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{self.name!r}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, population=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{self.population!r}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;,&amp;quot;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot; coastline=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{self.coastline!r}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__eq__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__class__&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__class__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;NotImplemented&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__ne__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__class__&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__class__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;NotImplemented&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__lt__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__class__&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__class__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;NotImplemented&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__le__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__class__&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__class__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;NotImplemented&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__gt__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__class__&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__class__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;NotImplemented&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__ge__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__class__&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__class__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;NotImplemented&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;beach_per_person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Meters of coastline per person&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;coastline&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;population&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/div&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;p&gt;After creation, a data class is a normal class. You can, for instance, inherit from a data class in the normal way. The main purpose of data classes is to make it quick and easy to write robust classes, in particular small classes that mainly store data.&lt;/p&gt;
&lt;p&gt;You can use the &lt;code&gt;Country&lt;/code&gt; data class like any other class:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;norway&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Country&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Norway&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5320045&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;323802&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;58133&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;norway&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Country(name=&amp;#39;Norway&amp;#39;, population=5320045, coastline=58133)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;norway&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;area&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;323802&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;usa&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Country&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;United States&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;326625791&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9833517&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;19924&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nepal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Country&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Nepal&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;29384297&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;147181&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nepal&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Country(name=&amp;#39;Nepal&amp;#39;, population=29384297, coastline=0)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;usa&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;beach_per_person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.06099946957342386&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;norway&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;beach_per_person&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;10.927163210085629&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that all the fields &lt;code&gt;.name&lt;/code&gt;, &lt;code&gt;.population&lt;/code&gt;, &lt;code&gt;.area&lt;/code&gt;, and &lt;code&gt;.coastline&lt;/code&gt; are used when initializing the class (although &lt;code&gt;.coastline&lt;/code&gt; is optional, as is shown in the example of landlocked Nepal). The &lt;code&gt;Country&lt;/code&gt; class has a reasonable &lt;a href=&quot;https://dbader.org/blog/python-repr-vs-str&quot;&gt;&lt;code&gt;repr&lt;/code&gt;&lt;/a&gt;, while defining methods works the same as for regular classes.&lt;/p&gt;
&lt;p&gt;By default, data classes can be compared for equality. Since we specified &lt;code&gt;order=True&lt;/code&gt; in the &lt;code&gt;@dataclass&lt;/code&gt; decorator, the &lt;code&gt;Country&lt;/code&gt; class can also be sorted:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;norway&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;norway&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nepal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;usa&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;norway&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;usa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nepal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[Country(name=&amp;#39;Nepal&amp;#39;, population=29384297, coastline=0),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; Country(name=&amp;#39;Norway&amp;#39;, population=5320045, coastline=58133),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; Country(name=&amp;#39;United States&amp;#39;, population=326625791, coastline=19924)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The sorting happens on the field values, first &lt;code&gt;.name&lt;/code&gt; then &lt;code&gt;.population&lt;/code&gt;, and so on. However, if you use &lt;code&gt;field()&lt;/code&gt;, you can &lt;a href=&quot;https://realpython.com/python-data-classes/#advanced-default-values&quot;&gt;customize&lt;/a&gt; which fields will be used in the comparison. In the example, the &lt;code&gt;.area&lt;/code&gt; field was left out of the &lt;code&gt;repr&lt;/code&gt; and the comparisons.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The country data are from the &lt;a href=&quot;https://www.cia.gov/library/publications/the-world-factbook/&quot;&gt;CIA World Factbook&lt;/a&gt; with population numbers estimated for July 2017. &lt;/p&gt;
&lt;p&gt;Before you all go book your next beach holidays in Norway, here is what the Factbook says about the &lt;a href=&quot;https://www.cia.gov/library/publications/the-world-factbook/geos/no.html&quot;&gt;Norwegian climate&lt;/a&gt;: &amp;ldquo;temperate along coast, modified by North Atlantic Current; colder interior with increased precipitation and colder summers; rainy year-round on west coast.&amp;rdquo; &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Data classes do some of the same things as &lt;a href=&quot;https://dbader.org/blog/writing-clean-python-with-namedtuples&quot;&gt;&lt;code&gt;namedtuple&lt;/code&gt;&lt;/a&gt;. Yet, they draw their biggest inspiration from the &lt;a href=&quot;http://www.attrs.org/&quot;&gt;&lt;code&gt;attrs&lt;/code&gt; project&lt;/a&gt;. See our &lt;a href=&quot;https://realpython.com/python-data-classes/&quot;&gt;full guide to data classes&lt;/a&gt; for more examples and further information, as well as &lt;a href=&quot;https://www.python.org/dev/peps/pep-0557/&quot;&gt;PEP 557&lt;/a&gt; for the official description.&lt;/p&gt;
&lt;h2 id=&quot;customization-of-module-attributes&quot;&gt;Customization of Module Attributes&lt;/h2&gt;
&lt;p&gt;Attributes are everywhere in Python! While class attributes are probably the most famous, attributes can actually be put on essentially anything&amp;mdash;including functions and modules. Several of Python&amp;rsquo;s basic features are implemented as attributes: most of the introspection functionality, doc-strings, and name spaces. Functions inside a module are made available as module attributes.&lt;/p&gt;
&lt;p&gt;Attributes are most often retrieved using the dot notation: &lt;code&gt;thing.attribute&lt;/code&gt;. However, you can also get attributes that are named at runtime using &lt;code&gt;getattr()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;random_attr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;gammavariate&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;lognormvariate&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;normalvariate&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;random_func&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;getattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;random_attr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;A &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{random_attr}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; random value: {random_func(1, 1)}&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Running this code will produce something like:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;A gammavariate random value: 2.8017715125270618&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For classes, calling &lt;code&gt;thing.attr&lt;/code&gt; will first look for &lt;code&gt;attr&lt;/code&gt; defined on &lt;code&gt;thing&lt;/code&gt;. If it is not found, then the special method &lt;code&gt;thing.__getattr__(&quot;attr&quot;)&lt;/code&gt; is called. (This is a simplification. See &lt;a href=&quot;http://blog.lerner.co.il/python-attributes/&quot;&gt;this article&lt;/a&gt; for more details.) The &lt;code&gt;.__getattr__()&lt;/code&gt; method can be used to customize access to attributes on objects.&lt;/p&gt;
&lt;p&gt;Until Python 3.7, the same customization was not easily available for module attributes. However, &lt;a href=&quot;https://www.python.org/dev/peps/pep-0562/&quot;&gt;PEP 562&lt;/a&gt; introduces &lt;code&gt;__getattr__()&lt;/code&gt;  on modules, together with a corresponding &lt;code&gt;__dir__()&lt;/code&gt; function. The &lt;code&gt;__dir__()&lt;/code&gt; special function allows customization of the result of calling &lt;a href=&quot;https://realpython.com/python-modules-packages/#the-dir-function&quot;&gt;&lt;code&gt;dir()&lt;/code&gt; on a module&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The PEP itself gives a few examples of how these functions can be used, including adding deprecation warnings to functions and lazy loading of heavy submodules. Below, we will build a simple plugin system that allows functions to be added to a module dynamically. This example takes advantage of Python packages. See &lt;a href=&quot;https://realpython.com/python-modules-packages/&quot;&gt;this article&lt;/a&gt; if you need a refresher on packages.&lt;/p&gt;
&lt;p&gt;Create a new directory, &lt;code&gt;plugins&lt;/code&gt;, and add the following code to a file, &lt;code&gt;plugins/__init__.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;importlib&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;import_module&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;importlib&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;dict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;register_plugin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Decorator to register plug-ins&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__getattr__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Return a named plugin&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;KeyError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_import_plugins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;AttributeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;module &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{__name__!r}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; has no attribute &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{name!r}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;None&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__dir__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;List available plug-ins&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_import_plugins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_import_plugins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Import all resources to register plug-ins&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;.py&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;import_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{__name__}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{name[:-3]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Before we look at what this code does, add two more files inside the &lt;code&gt;plugins&lt;/code&gt; directory. First, let&amp;rsquo;s see &lt;code&gt;plugins/plugin_1.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;register_plugin&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@register_plugin&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hello_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello from Plugin 1&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, add similar code in the file &lt;code&gt;plugins/plugin_2.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;register_plugin&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@register_plugin&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hello_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello from Plugin 2&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nd&quot;&gt;@register_plugin&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;goodbye&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Plugin 2 says goodbye&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;These plugins can now be used as follows:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;plugins&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hello_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Hello from Plugin 1&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;goodbye&amp;#39;, &amp;#39;hello_1&amp;#39;, &amp;#39;hello_2&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;goodbye&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Plugin 2 says goodbye&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This may not all seem that revolutionary (and it probably isn&amp;rsquo;t), but let&amp;rsquo;s look at what actually happened here. Normally, to be able to call &lt;code&gt;plugins.hello_1()&lt;/code&gt;, the &lt;code&gt;hello_1()&lt;/code&gt; function must be defined in a &lt;code&gt;plugins&lt;/code&gt; module or explicitly imported inside &lt;code&gt;__init__.py&lt;/code&gt; in a &lt;code&gt;plugins&lt;/code&gt; package. Here, it is neither!&lt;/p&gt;
&lt;p&gt;Instead, &lt;code&gt;hello_1()&lt;/code&gt; is defined in an arbitrary file inside the &lt;code&gt;plugins&lt;/code&gt; package, and &lt;code&gt;hello_1()&lt;/code&gt; becomes a part of the &lt;code&gt;plugins&lt;/code&gt; package by registering itself using the &lt;code&gt;@register_plugin&lt;/code&gt; &lt;a href=&quot;https://realpython.com/primer-on-python-decorators/&quot;&gt;decorator&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The difference is subtle. Instead of the package dictating which functions are available, the individual functions register themselves as part of the package. This gives you a simple structure where you can add functions independently of the rest of the code without having to keep a centralized list of which functions are available.&lt;/p&gt;
&lt;p&gt;Let us do a quick review of what &lt;code&gt;__getattr__()&lt;/code&gt; does inside the &lt;code&gt;plugins/__init__.py&lt;/code&gt; code. When you asked for &lt;code&gt;plugins.hello_1()&lt;/code&gt;, Python first looks for a &lt;code&gt;hello_1()&lt;/code&gt; function inside the &lt;code&gt;plugins/__init__.py&lt;/code&gt; file. As no such function exists, Python calls &lt;code&gt;__getattr__(&quot;hello_1&quot;)&lt;/code&gt; instead. Remember the source code of the &lt;code&gt;__getattr__()&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__getattr__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Return a named plugin&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# 1) Try to return plugin&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;KeyError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;_import_plugins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;           &lt;span class=&quot;c1&quot;&gt;# 2) Import all plugins&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# 3) Try to return plugin again&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;AttributeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# 4) Raise error&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;module &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{__name__!r}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; has no attribute &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{name!r}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;None&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;__getattr__()&lt;/code&gt; contains the following steps. The numbers in the following list correspond to the numbered comments in the code:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First, the function optimistically tries to return the named plugin from the &lt;code&gt;PLUGINS&lt;/code&gt; dictionary. This will succeed if a plugin named &lt;code&gt;name&lt;/code&gt; exists and has already been imported.&lt;/li&gt;
&lt;li&gt;If the named plugin is not found in the &lt;code&gt;PLUGINS&lt;/code&gt; dictionary, we make sure all plugins are imported.&lt;/li&gt;
&lt;li&gt;Return the named plugin if it has become available after the import.&lt;/li&gt;
&lt;li&gt;If the plugin is not in the &lt;code&gt;PLUGINS&lt;/code&gt; dictionary after importing all plugins, we raise an &lt;code&gt;AttributeError&lt;/code&gt; saying that &lt;code&gt;name&lt;/code&gt; is not an attribute (plugin) on the current module.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;How is the &lt;code&gt;PLUGINS&lt;/code&gt; dictionary populated though? The &lt;code&gt;_import_plugins()&lt;/code&gt; function imports all Python files inside the &lt;code&gt;plugins&lt;/code&gt; package, but does not seem to touch &lt;code&gt;PLUGINS&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_import_plugins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Import all resources to register plug-ins&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;.py&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;import_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{__name__}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{name[:-3]}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Don&amp;rsquo;t forget that each plugin function is decorated by the &lt;code&gt;@register_plugin&lt;/code&gt; decorator. This decorator is called when the plugins are imported and is the one actually populating the &lt;code&gt;PLUGINS&lt;/code&gt; dictionary. You can see this if you manually import one of the plugin files:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;plugins&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{}&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;plugins.plugin_1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;#39;hello_1&amp;#39;: &amp;lt;function hello_1 at 0x7f29d4341598&amp;gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Continuing the example, note that calling &lt;code&gt;dir()&lt;/code&gt; on the module also imports the remaining plugins:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;goodbye&amp;#39;, &amp;#39;hello_1&amp;#39;, &amp;#39;hello_2&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;#39;hello_1&amp;#39;: &amp;lt;function hello_1 at 0x7f29d4341598&amp;gt;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;hello_2&amp;#39;: &amp;lt;function hello_2 at 0x7f29d4341620&amp;gt;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;goodbye&amp;#39;: &amp;lt;function goodbye at 0x7f29d43416a8&amp;gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;dir()&lt;/code&gt; usually lists all available attributes on an object. Normally, using &lt;code&gt;dir()&lt;/code&gt; on a module results in something like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;plugins&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;PLUGINS&amp;#39;, &amp;#39;__builtins__&amp;#39;, &amp;#39;__cached__&amp;#39;, &amp;#39;__doc__&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;__file__&amp;#39;, &amp;#39;__getattr__&amp;#39;, &amp;#39;__loader__&amp;#39;, &amp;#39;__name__&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;__package__&amp;#39;, &amp;#39;__path__&amp;#39;, &amp;#39;__spec__&amp;#39;, &amp;#39;_import_plugins&amp;#39;,&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; &amp;#39;import_module&amp;#39;, &amp;#39;register_plugin&amp;#39;, &amp;#39;resources&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;While this might be useful information, we are more interested in exposing the available plugins. In Python 3.7, you can customize the result of calling &lt;code&gt;dir()&lt;/code&gt; on a module by adding a &lt;code&gt;__dir__()&lt;/code&gt; special function. For &lt;code&gt;plugins/__init__.py&lt;/code&gt;, this function first makes sure all plugins have been imported and then lists their names:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__dir__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;List available plug-ins&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;_import_plugins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PLUGINS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Before leaving this example, please note that we also used another cool new feature of Python 3.7. To import all modules inside the &lt;code&gt;plugins&lt;/code&gt; directory, we used the new &lt;a href=&quot;https://docs.python.org/3.7/library/importlib.html#module-importlib.resources&quot;&gt;&lt;code&gt;importlib.resources&lt;/code&gt;&lt;/a&gt; module. This module gives access to files and resources inside modules and packages without the need for &lt;code&gt;__file__&lt;/code&gt; hacks (which do not always work) or &lt;code&gt;pkg_resources&lt;/code&gt; (which is slow). Other features of &lt;code&gt;importlib.resources&lt;/code&gt; will be &lt;a href=&quot;#other-pretty-cool-features&quot;&gt;highlighted later&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;typing-enhancements&quot;&gt;Typing Enhancements&lt;/h2&gt;
&lt;p&gt;Type hinting and annotations have been in constant development throughout the Python 3 series of releases. Python&amp;rsquo;s &lt;a href=&quot;https://www.youtube.com/watch?v=2xWhaALHTvU&quot;&gt;typing system&lt;/a&gt; is now quite stable. Still, Python 3.7 brings some enhancements to the table: better performance, core support, and forward references.&lt;/p&gt;
&lt;p&gt;Python does not do any type checking at runtime (unless you are explicitly using packages like &lt;a href=&quot;https://pypi.org/project/enforce/&quot;&gt;&lt;code&gt;enforce&lt;/code&gt;&lt;/a&gt;). Therefore, adding type hints to your code should not affect its performance.&lt;/p&gt;
&lt;p&gt;Unfortunately, this is not completely true as most type hints need the &lt;code&gt;typing&lt;/code&gt; module. The &lt;code&gt;typing&lt;/code&gt; module is one of the &lt;a href=&quot;https://www.python.org/dev/peps/pep-0560/#performance&quot;&gt;slowest modules&lt;/a&gt; in the standard library. &lt;a href=&quot;https://www.python.org/dev/peps/pep-0560&quot;&gt;PEP 560&lt;/a&gt; adds some core support for typing in Python 3.7, which significantly speeds up the &lt;code&gt;typing&lt;/code&gt; module. The details of this are in general not necessary to know about. Simply lean back and enjoy the increased performance.&lt;/p&gt;
&lt;p&gt;While Python&amp;rsquo;s type system is reasonably expressive, one issue that causes some pain is forward references. Type hints&amp;mdash;or more generally annotations&amp;mdash;are evaluated while the module is imported. Therefore, all names must already be defined before they are used. The following is not possible:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Running the code raises a &lt;code&gt;NameError&lt;/code&gt; because the class &lt;code&gt;Tree&lt;/code&gt; is not yet (completely) defined in the definition of the &lt;code&gt;.__init__()&lt;/code&gt; method:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;tree.py&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;tree.py&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;Tree&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;NameError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;name &amp;#39;Tree&amp;#39; is not defined&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To overcome this, you would have needed to write &lt;code&gt;&quot;Tree&quot;&lt;/code&gt; as a string literal instead:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Tree&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Tree&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;See &lt;a href=&quot;https://www.python.org/dev/peps/pep-0484/#forward-references&quot;&gt;PEP 484&lt;/a&gt; for the original discussion.&lt;/p&gt;
&lt;p&gt;In a future &lt;a href=&quot;http://www.curiousefficiency.org/posts/2014/08/python-4000.html&quot;&gt;Python 4.0&lt;/a&gt;, such so called forward references will be allowed. This will be handled by not evaluating annotations until that is explicitly asked for. &lt;a href=&quot;https://www.python.org/dev/peps/pep-0563/&quot;&gt;PEP 563&lt;/a&gt; describes the details of this proposal. In Python 3.7, forward references are already available as a &lt;a href=&quot;https://docs.python.org/library/__future__.html&quot;&gt;&lt;code&gt;__future__&lt;/code&gt; import&lt;/a&gt;. You can now write the following:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;__future__&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;annotations&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Tree&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;left&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;left&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that in addition to avoiding the somewhat clumsy &lt;code&gt;&quot;Tree&quot;&lt;/code&gt; syntax, the postponed evaluation of annotations will also speed up your code, since type hints are not executed. Forward references are already supported by &lt;a href=&quot;http://mypy-lang.org/&quot;&gt;&lt;code&gt;mypy&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By far, the most common use of annotations is type hinting. Still, you have full access to the annotations at runtime and can use them as you see fit. If you are handling annotations directly, you need to deal with the possible forward references explicitly.&lt;/p&gt;
&lt;p&gt;Let us create some admittedly silly examples that show when annotations are evaluated. First we do it old-style, so annotations are evaluated at import time. Let &lt;code&gt;anno.py&lt;/code&gt; contain the following code:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Now!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{name}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that the annotation of &lt;code&gt;name&lt;/code&gt; is &lt;code&gt;print()&lt;/code&gt;. This is only to see exactly when the annotation is evaluated. Import the new module:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;anno&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Now!&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anno&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__annotations__&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;#39;name&amp;#39;: None}&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anno&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Alice&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Hello Alice&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, the annotation was evaluated at import time. Note that &lt;code&gt;name&lt;/code&gt; ends up annotated with &lt;code&gt;None&lt;/code&gt; because that is the return value of &lt;code&gt;print()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Add the &lt;code&gt;__future__&lt;/code&gt; import to enable postponed evaluation of annotations:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;__future__&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;annotations&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Now!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{name}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Importing this updated code will not evaluate the annotation:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;anno&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anno&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__annotations__&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;#39;name&amp;#39;: &amp;quot;print(&amp;#39;Now!&amp;#39;)&amp;quot;}&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anno&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Marty&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Hello Marty&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that &lt;code&gt;Now!&lt;/code&gt; is never printed and the annotation is kept as a string literal in the &lt;code&gt;__annotations__&lt;/code&gt; dictionary. In order to evaluate the annotation, use &lt;code&gt;typing.get_type_hints()&lt;/code&gt; or &lt;code&gt;eval()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;typing&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;typing&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_type_hints&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anno&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Now!&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;#39;name&amp;#39;: &amp;lt;class &amp;#39;NoneType&amp;#39;&amp;gt;}&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;eval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anno&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__annotations__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Now!&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;anno&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__annotations__&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;#39;name&amp;#39;: &amp;quot;print(&amp;#39;Now!&amp;#39;)&amp;quot;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Observe that the &lt;code&gt;__annotations__&lt;/code&gt; dictionary is never updated, so you need to evaluate the annotation every time you use it.&lt;/p&gt;
&lt;h2 id=&quot;timing-precision&quot;&gt;Timing Precision&lt;/h2&gt;
&lt;p&gt;In Python 3.7, the &lt;a href=&quot;https://docs.python.org/library/time.html&quot;&gt;&lt;code&gt;time&lt;/code&gt;&lt;/a&gt; module gains some new functions as described in &lt;a href=&quot;https://www.python.org/dev/peps/pep-0564/&quot;&gt;PEP 564&lt;/a&gt;. In particular, the following six functions are added:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;clock_gettime_ns()&lt;/code&gt;:&lt;/strong&gt; Returns the time of a specified clock&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;clock_settime_ns()&lt;/code&gt;:&lt;/strong&gt; Sets the time of a specified clock&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;monotonic_ns()&lt;/code&gt;:&lt;/strong&gt; Returns the time of a relative clock that cannot go backwards (for instance due to daylight savings)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;perf_counter_ns()&lt;/code&gt;&lt;/strong&gt;: Returns the value of a performance counter&amp;mdash;a clock specifically designed to measure short intervals&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;process_time_ns()&lt;/code&gt;:&lt;/strong&gt; Returns the sum of the system and user CPU time of the current process (not including sleep time)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;time_ns()&lt;/code&gt;&lt;/strong&gt;: Returns the number of nanoseconds since January 1st 1970&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In a sense, there is no new functionality added. Each function is similar to an already existing function without the &lt;code&gt;_ns&lt;/code&gt; suffix. The difference being that the new functions return a number of nanoseconds as an &lt;code&gt;int&lt;/code&gt; instead of a number of seconds as a &lt;code&gt;float&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For most applications, the difference between these new nanosecond functions and their old counterpart will not be appreciable. However, the new functions are easier to reason about because they rely on &lt;code&gt;int&lt;/code&gt; instead of &lt;code&gt;float&lt;/code&gt;. Floating point numbers are &lt;a href=&quot;https://docs.python.org/tutorial/floatingpoint.html&quot;&gt;by nature inaccurate&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.30000000000000004&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is not an issue with Python but rather a consequence of computers needing to represent infinite decimal numbers using a finite number of bits.&lt;/p&gt;
&lt;p&gt;A Python &lt;code&gt;float&lt;/code&gt; follows the &lt;a href=&quot;https://en.wikipedia.org/wiki/IEEE_754&quot;&gt;IEEE 754 standard&lt;/a&gt; and uses 53 significant bits. The result is that any time greater than about 104 days (2⁵³ or approximately &lt;a href=&quot;https://en.wikipedia.org/wiki/Names_of_large_numbers&quot;&gt;9 quadrillion nanoseconds&lt;/a&gt;) cannot be expressed as a float with nanosecond precision. In contrast, a Python &lt;a href=&quot;https://stackoverflow.com/a/9860611&quot;&gt;&lt;code&gt;int&lt;/code&gt; is unlimited&lt;/a&gt;, so an integer number of nanoseconds will always have nanosecond precision independent of the time value.&lt;/p&gt;
&lt;p&gt;As an example, &lt;code&gt;time.time()&lt;/code&gt; returns the number of seconds since January 1st 1970. This number is already quite big, so the precision of this number is at the microsecond level. This function is the one showing the biggest improvement in its &lt;code&gt;_ns&lt;/code&gt; version. The resolution of &lt;code&gt;time.time_ns()&lt;/code&gt; is about &lt;a href=&quot;https://www.python.org/dev/peps/pep-0564/#analysis&quot;&gt;3 times better&lt;/a&gt; than for &lt;code&gt;time.time()&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;What is a nanosecond by the way? Technically, it is one billionth of a second, or &lt;code&gt;1e-9&lt;/code&gt; second if you prefer scientific notation. These are just numbers though and do not really provide any intuition. For a better visual aid, see &lt;a href=&quot;https://en.wikipedia.org/wiki/Grace_Hopper#Anecdotes&quot;&gt;Grace Hopper&amp;rsquo;s&lt;/a&gt; wonderful &lt;a href=&quot;https://www.youtube.com/watch?v=JEpsKnWZrJ8&quot;&gt;demonstration of the nanosecond&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;As an aside, if you need to work with datetimes with nanosecond precision, the &lt;code&gt;datetime&lt;/code&gt; standard library will not cut it. It explicitly only handles microseconds:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timedelta&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2018&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timedelta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1e-6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;datetime.datetime(2018, 6, 27, 0, 0, 0, 1)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2018&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;27&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timedelta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1e-9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;datetime.datetime(2018, 6, 27, 0, 0)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Instead, you can use the &lt;a href=&quot;http://www.astropy.org/&quot;&gt;&lt;code&gt;astropy&lt;/code&gt; project&lt;/a&gt;. Its &lt;a href=&quot;http://docs.astropy.org/en/stable/time/&quot;&gt;&lt;code&gt;astropy.time&lt;/code&gt;&lt;/a&gt; package represents datetimes using two &lt;code&gt;float&lt;/code&gt; objects which guarantees &amp;ldquo;sub-nanosecond precision over times spanning the age of the universe.&amp;rdquo;&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;astropy.time&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TimeDelta&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;2018-06-27&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;Time object: scale=&amp;#39;utc&amp;#39; format=&amp;#39;iso&amp;#39; value=2018-06-27 00:00:00.000&amp;gt;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;2018-06-27&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TimeDelta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1e-9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;sec&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;2018-06-27&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sec&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;9.976020010071807e-10&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The latest version of &lt;code&gt;astropy&lt;/code&gt; is available in Python 3.5 and later.&lt;/p&gt;
&lt;h2 id=&quot;other-pretty-cool-features&quot;&gt;Other Pretty Cool Features&lt;/h2&gt;
&lt;p&gt;So far, you have seen the headline news regarding what&amp;rsquo;s new in Python 3.7. However, there are many other changes that are also pretty cool. In this section, we will look briefly at some of them.&lt;/p&gt;
&lt;h3 id=&quot;the-order-of-dictionaries-is-guaranteed&quot;&gt;The Order of Dictionaries Is Guaranteed&lt;/h3&gt;
&lt;p&gt;The CPython implementation of Python 3.6 has ordered dictionaries. (&lt;a href=&quot;http://pypy.org/&quot;&gt;PyPy&lt;/a&gt; also has this.) This means that items in dictionaries are iterated over in the same order they were inserted. The first example is using Python 3.5, and the second is using Python 3.6:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;one&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;two&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;three&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Python &amp;lt;= 3.5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;#39;three&amp;#39;: 3, &amp;#39;one&amp;#39;: 1, &amp;#39;two&amp;#39;: 2}&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;one&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;two&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;three&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Python &amp;gt;= 3.6&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{&amp;#39;one&amp;#39;: 1, &amp;#39;two&amp;#39;: 2, &amp;#39;three&amp;#39;: 3}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In Python 3.6, this ordering was just a nice consequence of that implementation of &lt;code&gt;dict&lt;/code&gt;. In Python 3.7, however, dictionaries preserving their insert order is part of the &lt;a href=&quot;https://mail.python.org/pipermail/python-dev/2017-December/151283.html&quot;&gt;language specification&lt;/a&gt;. As such, it may now be relied on in projects that support only Python &amp;gt;= 3.7 (or CPython &amp;gt;= 3.6).&lt;/p&gt;
&lt;h3 id=&quot;async-and-await-are-keywords&quot;&gt;&amp;ldquo;&lt;code&gt;async&lt;/code&gt;&amp;rdquo; and &amp;ldquo;&lt;code&gt;await&lt;/code&gt;&amp;rdquo; Are Keywords&lt;/h3&gt;
&lt;p&gt;Python 3.5 introduced &lt;a href=&quot;https://www.python.org/dev/peps/pep-0492/&quot;&gt;coroutines with &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; syntax&lt;/a&gt;. To avoid issues of backwards compatibility, &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; were not added to the list of reserved keywords. In other words, it was still possible to define variables or functions named &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;In Python 3.7, this is no longer possible:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;invalid syntax&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;await&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;await&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;invalid syntax&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;asyncio-face-lift&quot;&gt;&amp;ldquo;&lt;code&gt;asyncio&lt;/code&gt;&amp;rdquo; Face Lift&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;asyncio&lt;/code&gt; standard library was originally introduced in Python 3.4 to handle concurrency in a modern way using event loops, coroutines and futures. Here is a &lt;a href=&quot;https://hackernoon.com/asyncio-for-the-working-python-developer-5c468e6e2e8e&quot;&gt;gentle introduction&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In Python 3.7, the &lt;code&gt;asyncio&lt;/code&gt; module is getting a &lt;a href=&quot;https://docs.python.org/3.7/whatsnew/3.7.html#asyncio&quot;&gt;major face lift&lt;/a&gt;, including many new functions, support for the context variables (see &lt;a href=&quot;#context-variables&quot;&gt;below&lt;/a&gt;), and performance improvements. Of particular note is &lt;code&gt;asyncio.run()&lt;/code&gt;, which simplifies calling coroutines from synchronous code. Using &lt;a href=&quot;https://docs.python.org/3.7/library/asyncio-task.html#asyncio.run&quot;&gt;&lt;code&gt;asyncio.run()&lt;/code&gt;&lt;/a&gt;, you do not need to explicitly create the event loop. An asynchronous Hello World program can now be written:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;asyncio&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;hello_world&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;asyncio&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hello_world&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;context-variables&quot;&gt;Context Variables&lt;/h3&gt;
&lt;p&gt;Context variables are variables that can have different values depending on their context. They are similar to Thread-Local Storage in which each execution thread may have a different value for a variable. However, with context variables, there may be several contexts in one execution thread. The main use case for context variables is keeping track of variables in concurrent asynchronous tasks.&lt;/p&gt;
&lt;p&gt;The following example constructs three contexts, each with their own value for the value &lt;code&gt;name&lt;/code&gt;. The &lt;code&gt;greet()&lt;/code&gt; function is later able to use the value of &lt;code&gt;name&lt;/code&gt; inside each context:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;contextvars&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contextvars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ContextVar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;contexts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello {name.get()}&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Construct contexts and set the context variable name&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Steve&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Dina&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Harry&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contextvars&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;copy_context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;contexts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Run greet function inside each context&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;reversed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contexts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ctx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Running this script greets Steve, Dina, and Harry in reverse order:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3.7 context_demo.py
&lt;span class=&quot;go&quot;&gt;Hello Harry&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Hello Dina&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Hello Steve&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;importing-data-files-with-importlibresources&quot;&gt;Importing Data Files With &amp;ldquo;&lt;code&gt;importlib.resources&lt;/code&gt;&amp;ldquo;&lt;/h3&gt;
&lt;p&gt;One challenge when packaging a Python project is deciding what to do with project resources like data files needed by the project. A few options have commonly been used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hard-code a path to the data file.&lt;/li&gt;
&lt;li&gt;Put the data file inside the package and locate it using &lt;code&gt;__file__&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;https://setuptools.readthedocs.io/en/latest/pkg_resources.html&quot;&gt;&lt;code&gt;setuptools.pkg_resources&lt;/code&gt;&lt;/a&gt; to access the data file resource.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of these have their shortcomings. The first option is not portable. Using &lt;code&gt;__file__&lt;/code&gt; is more portable, but if the Python project is installed it might end up inside a zip and not have a &lt;code&gt;__file__&lt;/code&gt; attribute. The third option solves this problem, but is unfortunately very slow.&lt;/p&gt;
&lt;p&gt;A better solution is the new &lt;a href=&quot;https://docs.python.org/3.7/library/importlib.html#module-importlib.resources&quot;&gt;&lt;code&gt;importlib.resources&lt;/code&gt;&lt;/a&gt; module in the standard library. It uses Python&amp;rsquo;s existing import functionality to also import data files. Assume you have a resource inside a Python package like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;data/
│
├── alice_in_wonderland.txt
└── __init__.py
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that &lt;code&gt;data&lt;/code&gt; needs to be a &lt;a href=&quot;https://realpython.com/python-modules-packages/&quot;&gt;Python package&lt;/a&gt;. That is, the directory needs to contain an &lt;code&gt;__init__.py&lt;/code&gt; file (which may be empty). You can then read the &lt;code&gt;alice_in_wonderland.txt&lt;/code&gt; file as follows:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;importlib&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resources&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;data&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;alice_in_wonderland.txt&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;alice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readlines&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;CHAPTER I. Down the Rabbit-Hole&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;Alice was beginning to get very tired of sitting by her sister on the&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bank, and of having nothing to do: once or twice she had peeped into the&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;book her sister was reading, but it had no pictures or conversations in&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;it, ‘and what is the use of a book,’ thought Alice ‘without pictures or&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;conversations?’&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A similar &lt;a href=&quot;https://docs.python.org/3.7/library/importlib.html#importlib.resources.open_binary&quot;&gt;&lt;code&gt;resources.open_binary()&lt;/code&gt;&lt;/a&gt; function is available for opening files in binary mode. In the earlier &lt;a href=&quot;#customization-of-module-attributes&quot;&gt;&amp;ldquo;plugins as module attributes&amp;rdquo; example&lt;/a&gt;, we used &lt;code&gt;importlib.resources&lt;/code&gt; to discover the available plugins using &lt;code&gt;resources.contents()&lt;/code&gt;. See &lt;a href=&quot;https://www.youtube.com/watch?v=ZsGFU2qh73E&quot;&gt;Barry Warsaw&amp;rsquo;s PyCon 2018 talk&lt;/a&gt; for more information.&lt;/p&gt;
&lt;p&gt;It is possible to use &lt;code&gt;importlib.resources&lt;/code&gt; in Python 2.7 and Python 3.4+ through a &lt;a href=&quot;https://pypi.org/project/importlib_resources/&quot;&gt;backport&lt;/a&gt;. A &lt;a href=&quot;http://importlib-resources.readthedocs.io/en/latest/migration.html&quot;&gt;guide on migrating from &lt;code&gt;pkg_resources&lt;/code&gt; to &lt;code&gt;importlib.resources&lt;/code&gt;&lt;/a&gt; is available.&lt;/p&gt;
&lt;h3 id=&quot;developer-tricks&quot;&gt;Developer Tricks&lt;/h3&gt;
&lt;p&gt;Python 3.7 has added several features aimed at you as a developer. You have &lt;a href=&quot;#the-breakpoint-built-in&quot;&gt;already seen the new &lt;code&gt;breakpoint()&lt;/code&gt; built-in&lt;/a&gt;. In addition, a few new &lt;a href=&quot;https://docs.python.org/3.7/using/cmdline.html#id5&quot;&gt;&lt;code&gt;-X&lt;/code&gt; command line options&lt;/a&gt; have been added to the Python interpreter.&lt;/p&gt;
&lt;p&gt;You can easily get an idea of how much time the imports in your script takes, using &lt;code&gt;-X importtime&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3.7 -X importtime my_script.py
&lt;span class=&quot;go&quot;&gt;import time: self [us] | cumulative | imported package&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;import time:      2607 |       2607 | _frozen_importlib_external&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;import time:       844 |      28866 |   importlib.resources&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;import time:       404 |      30434 | plugins&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;cumulative&lt;/code&gt; column shows the cumulative time of import (in microseconds). In this example, importing &lt;code&gt;plugins&lt;/code&gt; took about 0.03 seconds, most of which was spent importing &lt;code&gt;importlib.resources&lt;/code&gt;. The &lt;code&gt;self&lt;/code&gt; column shows the import time excluding nested imports.&lt;/p&gt;
&lt;p&gt;You can now use &lt;code&gt;-X dev&lt;/code&gt; to activate &amp;ldquo;development mode.&amp;rdquo; The development mode will add certain debug features and runtime checks that are considered too slow to be enabled by default. These include enabling &lt;a href=&quot;https://docs.python.org/library/faulthandler.html#module-faulthandler&quot;&gt;&lt;code&gt;faulthandler&lt;/code&gt;&lt;/a&gt; to show a traceback on serious crashes, as well as more warnings and debug hooks.&lt;/p&gt;
&lt;p&gt;Finally, &lt;code&gt;-X utf8&lt;/code&gt; enables &lt;a href=&quot;https://docs.python.org/3.7/using/cmdline.html#envvar-PYTHONUTF8&quot;&gt;UTF-8 mode&lt;/a&gt;. (See &lt;a href=&quot;https://www.python.org/dev/peps/pep-0540/&quot;&gt;PEP 540&lt;/a&gt;.) In this mode, &lt;code&gt;UTF-8&lt;/code&gt; will be used for text encoding regardless of the current locale.&lt;/p&gt;
&lt;h3 id=&quot;optimizations&quot;&gt;Optimizations&lt;/h3&gt;
&lt;p&gt;Each new release of Python comes with a set of optimizations. In Python 3.7, there are some significant speed-ups, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There is less overhead in calling many methods in the standard library.&lt;/li&gt;
&lt;li&gt;Method calls are up to 20% faster in general.&lt;/li&gt;
&lt;li&gt;The startup time of Python itself is reduced by 10-30%.&lt;/li&gt;
&lt;li&gt;Importing &lt;code&gt;typing&lt;/code&gt; is 7 times faster.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, many more specialized optimizations are included. See &lt;a href=&quot;https://docs.python.org/3.7/whatsnew/3.7.html#optimizations&quot;&gt;this list&lt;/a&gt; for a detailed overview.&lt;/p&gt;
&lt;p&gt;The upshot of all these optimizations is that &lt;a href=&quot;https://speed.python.org/&quot;&gt;Python 3.7 is fast&lt;/a&gt;. It is simply the &lt;a href=&quot;https://hackernoon.com/which-is-the-fastest-version-of-python-2ae7c61a6b2b&quot;&gt;fastest version of CPython&lt;/a&gt; released so far.&lt;/p&gt;
&lt;h2 id=&quot;so-should-i-upgrade&quot;&gt;So, Should I Upgrade?&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s start with the simple answer. If you want to try out any of the new features you have seen here, then you do need to be able to use Python 3.7. Using tools such as &lt;a href=&quot;https://github.com/pyenv/pyenv&quot;&gt;&lt;code&gt;pyenv&lt;/code&gt;&lt;/a&gt; or &lt;a href=&quot;https://www.anaconda.com/download/&quot;&gt;Anaconda&lt;/a&gt; makes it easy to have several versions of Python installed side by side. There is no downside to installing Python 3.7 and trying it out.&lt;/p&gt;
&lt;p&gt;Now, for the more complicated questions. Should you upgrade your production environment to Python 3.7? Should you make your own project dependent on Python 3.7 to take advantage of the new features?&lt;/p&gt;
&lt;p&gt;With the obvious caveat that you should always do thorough testing before upgrading your production environment, there are very few things in Python 3.7 that will break earlier code (&lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; becoming keywords is one example though). If you are already using a modern Python, upgrading to 3.7 should be quite smooth. If you want to be a little conservative, you might want to wait for the release of the first maintenance release&amp;mdash;Python 3.7.1&amp;mdash;&lt;a href=&quot;https://www.python.org/dev/peps/pep-0537/#maintenance-releases&quot;&gt;tentatively expected some time in July 2018&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Arguing that you should make your project 3.7 only is harder. Many of the new features in Python 3.7 are either available as backports to Python 3.6 (data classes, &lt;code&gt;importlib.resources&lt;/code&gt;) or conveniences (faster startup and method calls, easier debugging, and &lt;code&gt;-X&lt;/code&gt; options). The latter, you can take advantage of by running Python 3.7 yourself while keeping your code compatible with Python 3.6 (or lower).&lt;/p&gt;
&lt;p&gt;The big features that will lock your code to Python 3.7 are &lt;a href=&quot;#customization-of-module-attributes&quot;&gt;&lt;code&gt;__getattr__()&lt;/code&gt; on modules&lt;/a&gt;, &lt;a href=&quot;#typing-enhancements&quot;&gt;forward references in type hints&lt;/a&gt;, and the &lt;a href=&quot;#timing-precision&quot;&gt;nanosecond &lt;code&gt;time&lt;/code&gt; functions&lt;/a&gt;. If you really need any of these, you should go ahead and bump your requirements. Otherwise, your project will probably be more useful to others if it can be run on Python 3.6 for a while longer.&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&quot;https://docs.python.org/3.7/whatsnew/3.7.html#porting-to-python-37&quot;&gt;Porting to Python 3.7 guide&lt;/a&gt; for details to be aware of when upgrading.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>What Can I Do With Python?</title>
      <id>https://realpython.com/what-can-i-do-with-python/</id>
      <link href="https://realpython.com/what-can-i-do-with-python/"/>
      <updated>2018-06-25T14:00:00+00:00</updated>
      <summary>In this article, we offer several different projects, resources, and tutorials that you can use to start building things with Python.</summary>
      <content type="html">
        &lt;p&gt;You&amp;rsquo;ve done it: you&amp;rsquo;ve finished a course or finally made it to the end of a book that teaches you the basics of programming with Python. You&amp;rsquo;ve mastered lists, dictionaries, classes, and maybe even some &lt;a href=&quot;https://realpython.com/python3-object-oriented-programming/&quot;&gt;object oriented concepts&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So&amp;hellip; what next?&lt;/p&gt;
&lt;p&gt;Python is a very versatile programming language, with a plethora of uses in a variety of different fields. If you&amp;rsquo;ve grasped the basics of Python and are itching to build something with the language, then it&amp;rsquo;s time to figure out what your next step should be.&lt;/p&gt;
&lt;p&gt;In this article, we offer several different projects, resources, and tutorials that you can use to start building things with Python.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free PDF Download:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/optins/view/python-cheat-sheet-short/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-cheat-sheet-short&quot; data-focus=&quot;false&quot;&gt;Python 3 Cheat Sheet&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;what-others-do-with-python&quot;&gt;What Others Do With Python&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;re probably wondering what people are building with Python in the real world. So first, let&amp;rsquo;s take a quick look at how some of the big tech companies are using the language.&lt;/p&gt;
&lt;p&gt;Google is a company that has used Python from the start, and it&amp;rsquo;s gained a place as one of the tech giant&amp;rsquo;s main server-side languages. Guido van Rossum, Python&amp;rsquo;s Benevolent Dictator for Life, even worked there for several years, overseeing the language&amp;rsquo;s development.&lt;/p&gt;
&lt;p&gt;Instagram likes Python for its simplicity. The service is known for running &lt;a href=&quot;https://instagram-engineering.com/web-service-efficiency-at-instagram-with-python-4976d078e366&quot;&gt;&amp;ldquo;the world&amp;rsquo;s largest deployment of the Django web framework, which is written entirely in Python.&amp;rdquo;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Spotify puts the language to use in its data analysis and back-end services. According to their team, Python&amp;rsquo;s ease of use leads to a lightning-fast development pipeline. Spotify performs a ton of analyses to give recommendations to their users, so they need something that&amp;rsquo;s simple but also works well. Python to the rescue!&lt;/p&gt;
&lt;p&gt;You can check out &lt;a href=&quot;https://realpython.com/world-class-companies-using-python/&quot;&gt;this article&lt;/a&gt; to see what other companies are doing with Python.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re already convinced, then let&amp;rsquo;s get you started!&lt;/p&gt;
&lt;h2 id=&quot;what-you-can-do-with-python&quot;&gt;What You Can Do With Python&lt;/h2&gt;
&lt;p&gt;From &lt;a href=&quot;https://realpython.com/tutorials/web-dev/&quot;&gt;web development&lt;/a&gt; to &lt;a href=&quot;https://realpython.com/tutorials/data-science/&quot;&gt;data science&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/tutorials/machine-learning/&quot;&gt;machine learning&lt;/a&gt;, and more, Python&amp;rsquo;s real-world applications are limitless. Here are some projects that will assist you in finally putting your Python skills to good use.&lt;/p&gt;
&lt;h3 id=&quot;1-automate-the-boring-stuff&quot;&gt;#1: Automate the Boring Stuff&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/automate-boring-stuff.740c78ae44f0.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid ml-3 w-33 float-right&quot; src=&quot;https://files.realpython.com/media/automate-boring-stuff.740c78ae44f0.jpg&quot; width=&quot;378&quot; height=&quot;499&quot; alt=&quot;Automate the Boring Stuff With Python + Al Sweigart&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is a resource on &amp;ldquo;practical programming for total beginners.&amp;rdquo; Like the title says, this book will teach you how to automate tedious tasks such as updating spreadsheets or renaming files on your computer. It&amp;rsquo;s the perfect starting point for anyone who&amp;rsquo;s mastered the basics of Python.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll get a chance to practice what you&amp;rsquo;ve learned so far by creating dictionaries, scraping the web, working with files, and creating objects and classes. The hands-on applications that you come across in this book will provide you with real-world results that you can see immediately.&lt;/p&gt;
&lt;p&gt;This resource is available in different formats to give you the best learning experience possible. &lt;a href=&quot;https://realpython.com/asins/1593275994/&quot;&gt;Buy the book on Amazon&lt;/a&gt; or &lt;a href=&quot;https://automatetheboringstuff.com/&quot;&gt;read it online for free&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;2-stay-on-top-of-bitcoin-prices&quot;&gt;#2: Stay on Top of Bitcoin Prices&lt;/h3&gt;
&lt;p&gt;Everyone seems to be talking about Bitcoin these days. Ever since topping out at a price of almost $20,000 in December 2017, the cryptocurrency has been on the minds of millions. Its price continues to fluctuate, but many would consider it a worthwhile investment.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re looking to cash in on the virtual gold rush and just need to know when to make your move, then you&amp;rsquo;ll need to stay on top of Bitcoin&amp;rsquo;s prices. This &lt;a href=&quot;https://realpython.com/python-bitcoin-ifttt/&quot;&gt;tutorial&lt;/a&gt; can teach you how to use your Python skills to build a Bitcoin price notification service.&lt;/p&gt;
&lt;p&gt;The foundation of this project is the creation of IFTTT (&amp;ldquo;if this, then that&amp;rdquo;) applets. You&amp;rsquo;ll learn how to use the &lt;a href=&quot;http://docs.python-requests.org/en/master/&quot;&gt;&lt;code&gt;requests&lt;/code&gt;&lt;/a&gt; library to send HTTP requests and how to use a webhook to connect your app to external services.&lt;/p&gt;
&lt;p&gt;This is the perfect starter project for a beginner Pythonista with an interest in crypto. The service you build with this tutorial can be extended to other currencies as well, so don&amp;rsquo;t worry&amp;mdash;Ethereum is fair game, too.&lt;/p&gt;
&lt;h3 id=&quot;3-create-a-calculator&quot;&gt;#3: Create a Calculator&lt;/h3&gt;
&lt;p&gt;This simple project is a solid gateway into GUI programming. Building back-end services is one important part of deployment, but there may be a front-end that needs to be taken into account. Creating applications that users can easily interact with is paramount.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re interested in UX and UI design, then take a look at this &lt;a href=&quot;https://python-textbok.readthedocs.io/en/1.0/Introduction_to_GUI_Programming.html&quot;&gt;tutorial&lt;/a&gt;. You&amp;rsquo;ll be working with the &lt;code&gt;tkinter&lt;/code&gt; module, the standard graphical user interface package that comes traditionally bundled with Python.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;tkinter&lt;/code&gt; module is a wrapper around Tcl/Tk, a combination of the Tcl scripting language and a GUI framework extension, Tk. If you have Python installed, then you should already have the &lt;code&gt;tkinter&lt;/code&gt; framework ready to go as well. A simple call will get you started:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;tkinter&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Once you&amp;rsquo;ve got that set up, you can get to work on &lt;a href=&quot;https://python-textbok.readthedocs.io/en/1.0/Introduction_to_GUI_Programming.html&quot;&gt;building your first GUI calculator in Python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Practice using the &lt;code&gt;tkinter&lt;/code&gt; module and watch your vision materialize on the screen. Then, once you&amp;rsquo;ve got your feet wet, you can branch out and start working with Python&amp;rsquo;s other GUI toolkits. Check out the official documentation on &lt;a href=&quot;https://wiki.python.org/moin/GuiProgramming&quot;&gt;GUI Programming in Python&lt;/a&gt; for more information.&lt;/p&gt;
&lt;h3 id=&quot;4-mine-twitter-data&quot;&gt;#4: Mine Twitter Data&lt;/h3&gt;
&lt;p&gt;Thanks to the Internet&amp;mdash;and, increasingly, the Internet of Things&amp;mdash;we now have access to hordes of data that weren&amp;rsquo;t available even a decade ago. Analytics is a huge part of any field that works with data. What are people talking about? What patterns can we see in their behavior?&lt;/p&gt;
&lt;p&gt;Twitter is a great place to get answers to some of these questions. If you&amp;rsquo;re interested in data analysis, then a Twitter data mining project is a great way to use your Python skills to answer questions about the world around you.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://realpython.com/twitter-sentiment-python-docker-elasticsearch-kibana/&quot;&gt;Our Twitter sentiment analysis tutorial&lt;/a&gt; will teach you how to mine Twitter data and analyze user sentiment with a &lt;code&gt;docker&lt;/code&gt; environment. You&amp;rsquo;ll learn how to register an application with Twitter, which you&amp;rsquo;ll need to do in order to access their streaming API.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll see how to use &lt;a href=&quot;http://tweepy.readthedocs.io/en/v3.6.0/&quot;&gt;Tweepy&lt;/a&gt; to filter which tweets you want to pull, &lt;a href=&quot;http://textblob.readthedocs.io/en/dev/&quot;&gt;TextBlob&lt;/a&gt; to calculate the sentiment of those tweets, &lt;a href=&quot;https://www.elastic.co/products/elasticsearch&quot;&gt;Elasticsearch&lt;/a&gt; to analyze their content, and &lt;a href=&quot;https://www.elastic.co/products/kibana&quot;&gt;Kibana&lt;/a&gt; to visualize the results. After you finish this tutorial, you should be ready to dive into other projects that use Python for &lt;a href=&quot;https://realpython.com/flask-by-example-part-3-text-processing-with-requests-beautifulsoup-nltk/&quot;&gt;text processing&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/python-speech-recognition/&quot;&gt;speech recognition&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;5-build-a-microblog-with-flask&quot;&gt;#5: Build a Microblog With Flask&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/mega-tutorial-small.5c22a7be3695.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid ml-3 w-33 float-right&quot; src=&quot;https://files.realpython.com/media/mega-tutorial-small.5c22a7be3695.png&quot; width=&quot;280&quot; height=&quot;362&quot; alt=&quot;Flask Mega Tutorial book cover Miguel Grinberg&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It seems like everyone has a blog these days, but it&amp;rsquo;s not a bad idea to have a central hub for yourself online. With the advent of Twitter and Instagram, microblogging in particular has become exceedingly popular. In &lt;a href=&quot;https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world&quot;&gt;this project by Miguel Grinberg&lt;/a&gt;, you&amp;rsquo;ll learn how to build your own microblog.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s called &lt;a href=&quot;https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world&quot;&gt;&amp;ldquo;The Flask Mega-Tutorial,&amp;rdquo;&lt;/a&gt; and it truly lives up to its name. With 23 chapters to work through, you&amp;rsquo;ll develop a deep understanding of the Flask micro web-framework. At the end of this project, you should have a fully functional web application.&lt;/p&gt;
&lt;p&gt;You don&amp;rsquo;t need to know anything about &lt;a href=&quot;https://realpython.com/tutorials/flask/&quot;&gt;Flask&lt;/a&gt; to get started, so it&amp;rsquo;s perfect for those of you who are itching to get your hands dirty with web development.&lt;/p&gt;
&lt;p&gt;The tutorial was recently updated to include content that will help you become a better web developer in general. You can &lt;a href=&quot;https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world&quot;&gt;read it for free online&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/asins/B079KPG4HT/&quot;&gt;purchase a copy on Amazon&lt;/a&gt;, or have the author walk you step by step through his &lt;a href=&quot;https://courses.miguelgrinberg.com/p/flask-mega-tutorial&quot;&gt;online course&lt;/a&gt;. Once you&amp;rsquo;re done, you&amp;rsquo;ll be able to move on to &lt;a href=&quot;https://www.djangoproject.com/&quot;&gt;Django&lt;/a&gt; and creating even larger-scale web applications.&lt;/p&gt;
&lt;h3 id=&quot;6-build-a-blockchain&quot;&gt;#6: Build a Blockchain&lt;/h3&gt;
&lt;p&gt;While the blockchain was initially developed as a financial technology, it&amp;rsquo;s spreading to a variety of other industries. Blockchains can be used for almost any kind of transaction: from real estate dealings to medical record transfers.&lt;/p&gt;
&lt;p&gt;You can get a better understanding of how they work by building one yourself. &lt;a href=&quot;https://hackernoon.com/learn-blockchains-by-building-one-117428612f46&quot;&gt;Hackernoon&amp;rsquo;s tutorial&lt;/a&gt; will assist you in implementing a blockchain from scratch. At the end of this project, you&amp;rsquo;ll have gained an in-depth understanding of how this transactional technology works.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll be working with HTTP clients and the &lt;a href=&quot;http://docs.python-requests.org/en/master/&quot;&gt;&lt;code&gt;requests&lt;/code&gt;&lt;/a&gt; library. Once you install the &lt;a href=&quot;https://realpython.com/tutorials/flask/&quot;&gt;&lt;code&gt;Flask&lt;/code&gt;&lt;/a&gt; web framework, you&amp;rsquo;ll be able to use HTTP requests to communicate with your blockchain over the Internet.&lt;/p&gt;
&lt;p&gt;Remember, blockchain isn&amp;rsquo;t just for crypto enthusiasts. Once you&amp;rsquo;ve built one for yourself, see if you can&amp;rsquo;t find a creative way to implement the technology in your field of interest.&lt;/p&gt;
&lt;h3 id=&quot;7-bottle-up-a-twitter-feed&quot;&gt;#7: Bottle Up a Twitter Feed&lt;/h3&gt;
&lt;p&gt;Interested in building web applications but unsure about starting a mega-project? No worries&amp;mdash;we&amp;rsquo;ve got something for you. &lt;a href=&quot;https://realpython.com/building-a-simple-web-app-with-bottle-sqlalchemy-twitter-api/&quot;&gt;Follow along with us&lt;/a&gt; to learn how to create a simple web app in just a few hours.&lt;/p&gt;
&lt;p&gt;Bob Belderbos shares how he implemented the &lt;a href=&quot;https://pybit.es/codechallenge40.html&quot;&gt;40th PyBites Code Challenge&lt;/a&gt;, where participants were instructed to create a simple web app to better navigate the &lt;a href=&quot;https://twitter.com/python_tip&quot;&gt;Daily Python Tip&lt;/a&gt; feed on Twitter. You can walk through his implementation of the challenge and code alongside him.&lt;/p&gt;
&lt;p&gt;Instead of Flask, you&amp;rsquo;ll be using the &lt;a href=&quot;http://bottlepy.org/docs/stable/&quot;&gt;Bottle micro web-framework&lt;/a&gt;. Bottle is known as a low-dependency solution for deploying apps quickly. Since it is designed to be lightweight and simple to use, you&amp;rsquo;ll have your application developed in no time.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll also use the &lt;a href=&quot;http://tweepy.readthedocs.io/en/v3.6.0/&quot;&gt;Tweepy&lt;/a&gt; module to load data from the Twitter API. You&amp;rsquo;ll store the data in an &lt;a href=&quot;https://www.sqlalchemy.org/&quot;&gt;SQLAlchemy&lt;/a&gt; database, so you&amp;rsquo;ll get some practice writing SQL queries as well. Fork &lt;a href=&quot;https://github.com/pybites/pytip&quot;&gt;the repo&lt;/a&gt; to get started!&lt;/p&gt;
&lt;h3 id=&quot;8-play-pygames&quot;&gt;#8: Play PyGames&lt;/h3&gt;
&lt;p&gt;This one is for those of you who like to have fun! Python can be used to code a variety of arcade games, adventure games, and puzzle games that you can deploy within a few days. Classics like hangman, tic-tac-toe, ping-pong, and more are all doable with your newly acquired programming skills.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://www.pygame.org/docs/&quot;&gt;Pygame&lt;/a&gt; library makes it even easier to build your own games. It contains almost anything you could need when starting to develop a game.&lt;/p&gt;
&lt;p&gt;Pygame is free and open source. It includes computer graphics and sound libraries that you can use to add interactive functionality to your application.&lt;/p&gt;
&lt;p&gt;There are &lt;a href=&quot;https://inventwithpython.com/blog/2012/02/20/i-need-practice-programming-49-ideas-for-game-clones-to-code/&quot;&gt;scores of games&lt;/a&gt; you can create with the library. Whatever you choose to invent, feel free to share your stuff with &lt;a href=&quot;https://www.pygame.org/wiki/about&quot;&gt;the Pygame community&lt;/a&gt;!&lt;/p&gt;
&lt;h3 id=&quot;9-choose-your-own-adventure&quot;&gt;#9: Choose Your Own Adventure&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;re more into storytelling, then you can still build something cool with Python.&lt;/p&gt;
&lt;p&gt;The language is extremely easy to write in, which makes it the perfect environment for developing interactive fiction. &lt;a href=&quot;https://letstalkdata.com/2014/08/how-to-write-a-text-adventure-in-python/&quot;&gt;This free resource&lt;/a&gt; will guide you through the process of writing a text-based adventure game in Python.&lt;/p&gt;
&lt;p&gt;The tutorial assumes basic knowledge of programming in Python, but it helps you bridge the gap between what you know and how to use that knowledge to build an application.&lt;/p&gt;
&lt;p&gt;If you want to take your story to the next level, you can use a software engine like &lt;a href=&quot;https://www.renpy.org/&quot;&gt;Ren&amp;rsquo;Py&lt;/a&gt; to add sounds and images to your game, creating a full-fledged visual novel. (Then, you can put it up on Steam and see how it does! The best way to get feedback on your work is to release your creation out into the world.)&lt;/p&gt;
&lt;h3 id=&quot;10-say-hello-world-to-machine-learning&quot;&gt;#10: Say &amp;ldquo;Hello World!&amp;rdquo; to Machine Learning&lt;/h3&gt;
&lt;p&gt;Machine Learning can be a critical field of understanding for anyone interested in Artificial Intelligence. However, it can be intimidating to get started, because the space is fast and ever-changing.&lt;/p&gt;
&lt;p&gt;Luckily, there are resources online that can help you get your feet wet before you dive into the world of data science. &lt;a href=&quot;https://machinelearningmastery.com/machine-learning-in-python-step-by-step/&quot;&gt;This tutorial by Jason Brownlee&lt;/a&gt; is a wonderful introduction to using Python for machine learning.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll walk through some of the most common machine learning algorithms as well as the Python libraries that will assist you in making predictions.&lt;/p&gt;
&lt;p&gt;The tutorial is extremely simple and very easy to follow. You can complete it in as little as a few hours. By the time you&amp;rsquo;re done, you&amp;rsquo;ll have gained a quick understanding of how to use Python to perform data science.&lt;/p&gt;
&lt;p&gt;When you&amp;rsquo;re sure you&amp;rsquo;re ready to dive in, check out &lt;a href=&quot;https://realpython.com/tutorials/data-science/&quot;&gt;our stock of data science tutorials&lt;/a&gt;, where you&amp;rsquo;ll learn how to analyze fingerprints, create visualizations, and recognize speech and faces, all in Python.&lt;/p&gt;
&lt;h3 id=&quot;11-get-challenged&quot;&gt;#11: Get Challenged&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/python-tricks-book-cover.5b0f5df06d94.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid ml-3 w-33 float-right&quot; src=&quot;https://files.realpython.com/media/python-tricks-book-cover.5b0f5df06d94.jpg&quot; width=&quot;333&quot; height=&quot;500&quot; alt=&quot;&amp;quot;Python Tricks&amp;quot; Book Cover&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re not sure about taking the plunge with some of the larger projects listed above, but the smaller ones don&amp;rsquo;t interest you either, then you might be wondering what else there is. How on earth can you find something that excites you?&lt;/p&gt;
&lt;p&gt;Coding challenges can help you practice your Python skills and gain a surface-level understanding of all the different things you can do with Python.&lt;/p&gt;
&lt;p&gt;To put it simply: you&amp;rsquo;re presented with a problem, and you have to find a solution that uses Python.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll get a chance to develop implementations that make sense to you, but you&amp;rsquo;ll also have the opportunity to dive deep into the Python language by way of hints. These give you an idea of which modules you should be importing to help you solve the challenge.&lt;/p&gt;
&lt;p&gt;Coding challenges are a great way to learn breadth-first about as many libraries, methods, and frameworks as possible. You&amp;rsquo;re guaranteed to find something that you&amp;rsquo;ll want to explore more on your own time. You might even come back to this list and find that something you used in one of your challenges has sparked a new interest for you!&lt;/p&gt;
&lt;p&gt;To get started, try one of these on for size:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;http://pythonchallenge.com&quot;&gt;The Python Challenge&lt;/a&gt; has over 20 levels for you to work through.  Create small Python scripts to find a solution to the level. There are hints scattered about the Internet, but try to see the clues and figure it out for yourself!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://pybit.es/pages/challenges.html&quot;&gt;PyBites Code Challenges&lt;/a&gt; has 50 challenges and counting! These challenges encourage you to master Python by building applications that accomplish tasks.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you&amp;rsquo;d rather push yourself by coding through these challenges on your own instead of working through a step-by-step tutorial, then it&amp;rsquo;s always a good idea to have a resource you can turn to for help. &lt;a href=&quot;https://realpython.com/products/python-tricks-book/&quot;&gt;&lt;em&gt;Python Tricks: The Book&lt;/em&gt;&lt;/a&gt; is an amazing source of information to have on hand when you are working through these challenges. It will take you through some of the lesser-known parts of Python that you&amp;rsquo;ll need to solve them.&lt;/p&gt;
&lt;h2 id=&quot;what-you-probably-shouldnt-do-with-python&quot;&gt;What You Probably Shouldn&amp;rsquo;t Do With Python&lt;/h2&gt;
&lt;p&gt;Clearly, Python is an extremely versatile language, and there&amp;rsquo;s a lot you can do with it. But you can&amp;rsquo;t do everything with it. In fact, there are some things that Python is not very well suited for at all.&lt;/p&gt;
&lt;p&gt;As an interpreted language, Python has trouble interacting with low-level devices, like device drivers. For instance, you&amp;rsquo;d have a problem if you wanted to write an operating system with Python only. You&amp;rsquo;re better off sticking with C or C++ for low-level applications.&lt;/p&gt;
&lt;p&gt;However, even that might not be true for long. As a testament to Python&amp;rsquo;s flexibility, there are those out there who are working on projects that extend Python&amp;rsquo;s usability to low-level interactions. &lt;a href=&quot;https://micropython.org/&quot;&gt;MicroPython&lt;/a&gt; is just one of these projects, designing low-level capability for Python.&lt;/p&gt;
&lt;h2 id=&quot;what-if-my-idea-isnt-on-this-list&quot;&gt;What if My Idea Isn&amp;rsquo;t on This List?&lt;/h2&gt;
&lt;p&gt;That&amp;rsquo;s okay! This list isn&amp;rsquo;t exhaustive&amp;mdash;there are countless other tools and applications you can build with Python that we haven&amp;rsquo;t covered here. Don&amp;rsquo;t think you&amp;rsquo;re limited to what&amp;rsquo;s on this list. It is simply a resource to give you a place to start.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=7BiLUehbOb8&quot;&gt;This video&lt;/a&gt; will give you some ideas on other projects that Python is well-suited for. You can also check out &lt;a href=&quot;https://dbader.org/blog/python-projects-inspiration&quot;&gt;this blog post&lt;/a&gt; to learn where to find inspiration for more Python projects.&lt;/p&gt;
&lt;p&gt;In the end, it&amp;rsquo;s up to you to do the research and find projects that pique your interest. If you&amp;rsquo;re not sure where to begin, then &lt;a href=&quot;https://twitter.com/realpython&quot;&gt;follow us on Twitter&lt;/a&gt;. We regularly share cool and interesting Python projects from our reader community. You might find something that you can&amp;rsquo;t wait to contribute to!&lt;/p&gt;
&lt;h2 id=&quot;what-to-do-next&quot;&gt;What to Do Next&lt;/h2&gt;
&lt;p&gt;So there you have it! Eleven ways to start working your way from Python beginner to savvy Pythonista.&lt;/p&gt;
&lt;p&gt;No matter where you choose to begin, you&amp;rsquo;re sure to open up countless avenues for developing your programming skills. Pick something&amp;mdash;anything&amp;mdash;and get started! Do you have an idea for a project that didn&amp;rsquo;t make this list? Leave a comment down below! You could suggest the perfect project for a fellow programmer.&lt;/p&gt;
&lt;p&gt;If you get stuck and need a nudge in the right direction, check out &lt;a href=&quot;https://realpython.com/python-beginner-tips/&quot;&gt;our tips for developing positive learning strategies&lt;/a&gt; to help get yourself back on track.&lt;/p&gt;
&lt;p&gt;Another great way to get unstuck is to talk it out. Coding doesn&amp;rsquo;t have to be a solitary activity. If you need a way to ask questions and get answers quickly from knowledgeable professionals, then consider joining the &lt;a href=&quot;https://www.pythonistacafe.com/&quot;&gt;PythonistaCafe&lt;/a&gt;. This private community allows you to network with those who will help push you through any walls you may hit on your journey to Python mastery. &lt;a href=&quot;https://www.pythonistacafe.com/learn-more&quot;&gt;Click here&lt;/a&gt; to learn more, or go ahead an &lt;a href=&quot;https://www.pythonistacafe.com/apply&quot;&gt;apply&lt;/a&gt;!&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Operators and Expressions in Python</title>
      <id>https://realpython.com/python-operators-expressions/</id>
      <link href="https://realpython.com/python-operators-expressions/"/>
      <updated>2018-06-20T14:00:00+00:00</updated>
      <summary>You&#39;ll see how calculations can be performed on objects in Python. By the end of this tutorial, you will be able to create complex expressions by combining Python objects and operators.</summary>
      <content type="html">
        &lt;p&gt;After finishing our previous tutorial on &lt;a href=&quot;https://realpython.com/python-variables&quot;&gt;Python variables&lt;/a&gt; in this series, you should now have a good grasp of creating and naming Python objects of different types.  Let&amp;rsquo;s do some work with them!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Here&amp;rsquo;s what you&amp;rsquo;ll learn in this tutorial:&lt;/strong&gt; You&amp;rsquo;ll see how calculations can be performed on objects in Python. By the end of this tutorial, you will be able to create complex &lt;strong&gt;expressions&lt;/strong&gt; by combining objects and &lt;strong&gt;operators&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Get Notified:&lt;/strong&gt; Don&#39;t miss the follow up to this tutorial—&lt;a href=&quot;https://realpython.com/optins/view/newsletter-dont-miss-updates/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-newsletter-dont-miss-updates&quot; data-focus=&quot;false&quot;&gt;Click here to join the Real Python Newsletter&lt;/a&gt; and you&#39;ll know when the next installment comes out.&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;In Python, operators are special symbols that designate that some sort of computation should be performed.  The values that an operator acts on are called &lt;strong&gt;operands&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Here is an example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;30&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this case, the &lt;code&gt;+&lt;/code&gt; operator adds the operands &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; together.  An operand can be either a literal value or a variable that references an object:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;25&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A sequence of operands and operators, like &lt;code&gt;a + b - 5&lt;/code&gt;, is called an expression.  Python supports many operators for combining data objects into expressions.  These are explored below.&lt;/p&gt;
&lt;h2 id=&quot;arithmetic-operators&quot;&gt;Arithmetic Operators&lt;/h2&gt;
&lt;p&gt;The following table lists the arithmetic operators supported by Python:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operator&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+&lt;/code&gt;&amp;nbsp;(unary)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;+a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Unary Positive&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a&lt;/code&gt;&lt;br&gt;In other words, it doesn&amp;rsquo;t really do anything.  It mostly exists for the sake of completeness, to complement &lt;strong&gt;Unary Negation&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+&lt;/code&gt;&amp;nbsp;(binary)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a + b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Addition&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sum of &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&amp;nbsp;(unary)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Unary Negation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Value equal to &lt;code&gt;a&lt;/code&gt; but opposite in sign&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-&lt;/code&gt;&amp;nbsp;(binary)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a - b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Subtraction&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;b&lt;/code&gt; subtracted from &lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a * b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Multiplication&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Product of &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a / b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Division&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Quotient when &lt;code&gt;a&lt;/code&gt; is divided by &lt;code&gt;b&lt;/code&gt;.&lt;br&gt; The result always has type &lt;code&gt;float&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a % b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Modulus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Remainder when &lt;code&gt;a&lt;/code&gt; is divided by &lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;//&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a // b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Floor Division&lt;/strong&gt; (also called &lt;strong&gt;Integer Division&lt;/strong&gt;)&lt;/td&gt;
&lt;td&gt;Quotient when &lt;code&gt;a&lt;/code&gt; is divided by &lt;code&gt;b&lt;/code&gt;, rounded to the next smallest whole number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;**&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a ** b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Exponentiation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a&lt;/code&gt; raised to the power of &lt;code&gt;b&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Here are some examples of these operators in use:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;12&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1.3333333333333333&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;64&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The result of standard division (&lt;code&gt;/&lt;/code&gt;) is always a &lt;code&gt;float&lt;/code&gt;, even if the dividend is evenly divisible by the divisor:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2.0&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;float&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When the result of floor division (&lt;code&gt;//&lt;/code&gt;) is positive, it is as though the fractional portion is truncated off, leaving only the integer portion.   When the result is negative, the result is rounded down to the next smallest (greater negative) integer:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2.5&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note, by the way, that in a REPL session, you can display the value of an expression by just typing it in at the &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; prompt without &lt;code&gt;print()&lt;/code&gt;, the same as you can with a literal value or variable:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;25&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;106&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;comparison-operators&quot;&gt;Comparison Operators&lt;/h2&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operator&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;==&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a == b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Equal to&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt; if the value of &lt;code&gt;a&lt;/code&gt; is equal to the value of &lt;code&gt;b&lt;/code&gt;&lt;br&gt;&lt;code&gt;False&lt;/code&gt; otherwise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;!=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a != b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Not equal to&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt; if &lt;code&gt;a&lt;/code&gt; is not equal to &lt;code&gt;b&lt;/code&gt;&lt;br&gt;&lt;code&gt;False&lt;/code&gt; otherwise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a &amp;lt; b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Less than&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt; if &lt;code&gt;a&lt;/code&gt; is less than &lt;code&gt;b&lt;/code&gt;&lt;br&gt;&lt;code&gt;False&lt;/code&gt; otherwise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a &amp;lt;= b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Less than or equal to&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt; if &lt;code&gt;a&lt;/code&gt; is less than or equal to &lt;code&gt;b&lt;/code&gt;&lt;br&gt;&lt;code&gt;False&lt;/code&gt; otherwise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a &amp;gt; b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Greater than&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt; if &lt;code&gt;a&lt;/code&gt; is greater than &lt;code&gt;b&lt;/code&gt;&lt;br&gt;&lt;code&gt;False&lt;/code&gt; otherwise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;gt;=&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a &amp;gt;= b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Greater than or equal to&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt; if &lt;code&gt;a&lt;/code&gt; is greater than or equal to &lt;code&gt;b&lt;/code&gt;&lt;br&gt;&lt;code&gt;False&lt;/code&gt; otherwise&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Here are examples of the comparison operators in use:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Comparison operators are typically used in Boolean contexts like conditional and loop statements to direct program flow, as you will see later.&lt;/p&gt;
&lt;h3 id=&quot;equality-comparison-on-floating-point-values&quot;&gt;Equality Comparison on Floating-Point Values&lt;/h3&gt;
&lt;p&gt;Recall from the earlier discussion of &lt;a href=&quot;https://realpython.com/python-data-types/#floating-point-numbers&quot;&gt;floating-point numbers&lt;/a&gt; that the value stored internally for a &lt;code&gt;float&lt;/code&gt; object may not be precisely what you&amp;rsquo;d think it would be. For that reason, it is poor practice to compare floating-point values for exact equality.  Consider this example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Yikes! The internal representations of the addition operands are not exactly equal to &lt;code&gt;1.1&lt;/code&gt; and &lt;code&gt;2.2&lt;/code&gt;, so you cannot rely on &lt;code&gt;x&lt;/code&gt; to compare exactly to &lt;code&gt;3.3&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The preferred way to determine whether two floating-point values are &amp;ldquo;equal&amp;rdquo; is to compute whether they are close to one another, given some tolerance.  Take a look at this example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tolerance&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.00001&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;3.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tolerance&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;abs()&lt;/code&gt; returns absolute value.  If the absolute value of the difference between the two numbers is less than the specified tolerance, they are close enough to one another to be considered equal.&lt;/p&gt;
&lt;h2 id=&quot;logical-operators&quot;&gt;Logical Operators&lt;/h2&gt;
&lt;p&gt;The logical operators &lt;code&gt;not&lt;/code&gt;, &lt;code&gt;or&lt;/code&gt;, and &lt;code&gt;and&lt;/code&gt; modify and join together expressions evaluated in Boolean context to create more complex conditions.&lt;/p&gt;
&lt;h3 id=&quot;logical-expressions-involving-boolean-operands&quot;&gt;Logical Expressions Involving Boolean Operands&lt;/h3&gt;
&lt;p&gt;As you have seen, some objects and expressions in Python actually are of Boolean type.  That is, they are equal to one of the Python objects &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;.  Consider these examples:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;bool&amp;#39;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;bool&amp;#39;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;bool&amp;#39;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;bool&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the examples above, &lt;code&gt;x &amp;lt; 10&lt;/code&gt;, &lt;code&gt;callable(x)&lt;/code&gt;, and &lt;code&gt;t&lt;/code&gt; are all Boolean objects or expressions.&lt;/p&gt;
&lt;p&gt;Interpretation of logical expressions involving &lt;code&gt;not&lt;/code&gt;, &lt;code&gt;or&lt;/code&gt;, and &lt;code&gt;and&lt;/code&gt; is straightforward when the operands are Boolean:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operator&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;not&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;not x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt; if &lt;code&gt;x&lt;/code&gt; is &lt;code&gt;False&lt;/code&gt;&lt;br&gt;&lt;code&gt;False&lt;/code&gt; if &lt;code&gt;x&lt;/code&gt; is &lt;code&gt;True&lt;/code&gt;&lt;br&gt;(Logically reverses the sense of &lt;code&gt;x&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;or&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;x or y&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt; if either &lt;code&gt;x&lt;/code&gt; or &lt;code&gt;y&lt;/code&gt; is &lt;code&gt;True&lt;/code&gt;&lt;br&gt;&lt;code&gt;False&lt;/code&gt; otherwise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;and&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;x and y&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt; if both &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; are &lt;code&gt;True&lt;/code&gt;&lt;br&gt;&lt;code&gt;False&lt;/code&gt; otherwise&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Take a look at how they work in practice below.&lt;/p&gt;
&lt;h4 id=&quot;not-and-boolean-operands&quot;&gt;&amp;ldquo;&lt;code&gt;not&lt;/code&gt;&amp;rdquo; and Boolean Operands&lt;/h4&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operand&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Logical Expression&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;x &amp;lt; 10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;not x &amp;lt; 10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;callable(x)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;not callable(x)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h4 id=&quot;or-and-boolean-operands&quot;&gt;&amp;ldquo;&lt;code&gt;or&lt;/code&gt;&amp;rdquo; and Boolean Operands&lt;/h4&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operand&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Operand&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Logical Expression&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;x &amp;lt; 10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;callable(x)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;x &amp;lt; 10 or callable(x)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;x &amp;lt; 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;callable(x)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;x &amp;lt; 0 or callable(x)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h4 id=&quot;and-and-boolean-operands&quot;&gt;&amp;ldquo;&lt;code&gt;and&lt;/code&gt;&amp;rdquo; and Boolean Operands&lt;/h4&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;callable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operand&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Operand&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Logical Expression&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;x &amp;lt; 10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;callable(x)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;x &amp;lt; 10 and callable(x)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;x &amp;lt; 10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;callable(len)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;x &amp;lt; 10 or callable(len)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h3 id=&quot;evaluation-of-non-boolean-values-in-boolean-context&quot;&gt;Evaluation of Non-Boolean Values in Boolean Context&lt;/h3&gt;
&lt;p&gt;Many objects and expressions are not equal to &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;.  Nonetheless, they may still be evaluated in Boolean context and determined to be &amp;ldquo;truthy&amp;rdquo; or &amp;ldquo;falsy.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;So what is true and what isn&amp;rsquo;t?  As a philosophical question, that is outside the scope of this tutorial!&lt;/p&gt;
&lt;p&gt;But in Python, it is well-defined.  All the following are considered false when evaluated in Boolean context:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Boolean value &lt;code&gt;False&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Any value that is numerically zero (&lt;code&gt;0&lt;/code&gt;, &lt;code&gt;0.0&lt;/code&gt;, &lt;code&gt;0.0+0.0j&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;An empty string&lt;/li&gt;
&lt;li&gt;An object of a built-in composite data type which is empty (see below)&lt;/li&gt;
&lt;li&gt;The special value denoted by the Python keyword &lt;code&gt;None&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Virtually any other object built into Python is regarded as true.&lt;/p&gt;
&lt;p&gt;You can determine the &amp;ldquo;truthiness&amp;rdquo; of an object or expression with the built-in &lt;code&gt;bool()&lt;/code&gt; function.  &lt;code&gt;bool()&lt;/code&gt; returns &lt;code&gt;True&lt;/code&gt; if its argument is truthy and &lt;code&gt;False&lt;/code&gt; if it is falsy.&lt;/p&gt;
&lt;h4 id=&quot;numeric-value&quot;&gt;Numeric Value&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;A zero value is false.&lt;br&gt;
A non-zero value is true.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False False False&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;3.14159&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True True True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;string&quot;&gt;String&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;An empty string is false.&lt;br&gt;
A non-empty string is true.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False False False&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&amp;#39; &amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True True True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;built-in-composite-data-object&quot;&gt;Built-In Composite Data Object&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Python provides built-in composite data types called &lt;code&gt;list&lt;/code&gt;, &lt;code&gt;tuple&lt;/code&gt;, &lt;code&gt;dict&lt;/code&gt;, and &lt;code&gt;set&lt;/code&gt;.  These are &amp;ldquo;container&amp;rdquo; types that contain other objects.  An object of one of these types is considered false if it is empty and true if it is non-empty.&lt;/p&gt;
&lt;p&gt;The examples below demonstrate this for the &lt;code&gt;list&lt;/code&gt; type. (Lists are defined in Python with square brackets.)&lt;/p&gt;
&lt;p&gt;For more information on the &lt;code&gt;list&lt;/code&gt;, &lt;code&gt;tuple&lt;/code&gt;, &lt;code&gt;dict&lt;/code&gt;, and &lt;code&gt;set&lt;/code&gt; types, see the upcoming tutorials.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;list&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;list&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;the-none-keyword&quot;&gt;The &amp;ldquo;&lt;code&gt;None&lt;/code&gt;&amp;rdquo; Keyword&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;None&lt;/code&gt; is always false:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;logical-expressions-involving-non-boolean-operands&quot;&gt;Logical Expressions Involving Non-Boolean Operands&lt;/h3&gt;
&lt;p&gt;Non-Boolean values can also be modified and joined by &lt;code&gt;not&lt;/code&gt;, &lt;code&gt;or&lt;/code&gt; and, &lt;code&gt;and&lt;/code&gt;.  The result depends on the &amp;ldquo;truthiness&amp;rdquo; of the operands.&lt;/p&gt;
&lt;h4 id=&quot;not-and-non-boolean-operands&quot;&gt;&amp;ldquo;&lt;code&gt;not&lt;/code&gt;&amp;rdquo; and Non-Boolean Operands&lt;/h4&gt;
&lt;p&gt;Here is what happens for a non-Boolean value &lt;code&gt;x&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If &lt;code&gt;x&lt;/code&gt; is&lt;/th&gt;
&lt;th&gt;&lt;code&gt;not x&lt;/code&gt; is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;ldquo;truthy&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;ldquo;falsy&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Here are some concrete examples:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;or-and-non-boolean-operands&quot;&gt;&amp;ldquo;&lt;code&gt;or&lt;/code&gt;&amp;rdquo; and Non-Boolean Operands&lt;/h4&gt;
&lt;p&gt;This is what happens for two non-Boolean values &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If &lt;code&gt;x&lt;/code&gt; is&lt;/th&gt;
&lt;th&gt;&lt;code&gt;x or y&lt;/code&gt; is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;truthy&lt;/td&gt;
&lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;falsy&lt;/td&gt;
&lt;td&gt;&lt;code&gt;y&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Note that in this case, the expression &lt;code&gt;x or y&lt;/code&gt; does not evaluate to either &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;, but instead to one of either &lt;code&gt;x&lt;/code&gt; or &lt;code&gt;y&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;4.4&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4.4&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Even so, it is still the case that the expression &lt;code&gt;x or y&lt;/code&gt; will be truthy if either &lt;code&gt;x&lt;/code&gt; or &lt;code&gt;y&lt;/code&gt; is truthy, and falsy if both &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; are falsy.&lt;/p&gt;
&lt;h4 id=&quot;and-and-non-boolean-operands&quot;&gt;&amp;ldquo;&lt;code&gt;and&lt;/code&gt;&amp;rdquo; and Non-Boolean Operands&lt;/h4&gt;
&lt;p&gt;Here&amp;rsquo;s what you&amp;rsquo;ll get for two non-Boolean values &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If &lt;code&gt;x&lt;/code&gt; is&lt;/th&gt;
&lt;th&gt;&lt;code&gt;x and y&lt;/code&gt; is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;ldquo;truthy&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;y&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;ldquo;falsy&amp;rdquo;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;x&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;4.4&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As with &lt;code&gt;or&lt;/code&gt;, the expression &lt;code&gt;x and y&lt;/code&gt; does not evaluate to either &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;, but instead to one of either &lt;code&gt;x&lt;/code&gt; or &lt;code&gt;y&lt;/code&gt;.  &lt;code&gt;x and y&lt;/code&gt; will be truthy if both &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; are truthy, and falsy otherwise.&lt;/p&gt;
&lt;h3 id=&quot;compound-logical-expressions-and-short-circuit-evaluation&quot;&gt;Compound Logical Expressions and Short-Circuit Evaluation&lt;/h3&gt;
&lt;p&gt;So far, you have seen expressions with only a single &lt;code&gt;or&lt;/code&gt; or &lt;code&gt;and&lt;/code&gt; operator and two operands:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Multiple logical operators and operands can be strung together to form compound logical expressions.&lt;/p&gt;
&lt;h4 id=&quot;compound-or-expressions&quot;&gt;Compound &amp;ldquo;&lt;code&gt;or&lt;/code&gt;&amp;rdquo; Expressions&lt;/h4&gt;
&lt;p&gt;Consider the following expression:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;x&lt;sub&gt;1&lt;/sub&gt;&lt;/strong&gt; &lt;code&gt;or&lt;/code&gt; &lt;strong&gt;x&lt;sub&gt;2&lt;/sub&gt;&lt;/strong&gt; &lt;code&gt;or&lt;/code&gt; &lt;strong&gt;x&lt;sub&gt;3&lt;/sub&gt;&lt;/strong&gt; &lt;code&gt;or&lt;/code&gt; &amp;hellip; &lt;strong&gt;x&lt;sub&gt;n&lt;/sub&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This expression is true if any of the &lt;strong&gt;x&lt;sub&gt;i&lt;/sub&gt;&lt;/strong&gt; are true.&lt;/p&gt;
&lt;p&gt;In an expression like this, Python uses a methodology called &lt;a href=&quot;https://en.wikipedia.org/wiki/Short-circuit_evaluation&quot;&gt;short-circuit evaluation&lt;/a&gt;, also called McCarthy evaluation in honor of computer scientist John McCarthy.  The &lt;strong&gt;x&lt;sub&gt;i&lt;/sub&gt;&lt;/strong&gt; operands are evaluated in order from left to right.  As soon as one is found to be true, the entire expression is known to be true.  At that point, Python stops and no more terms are evaluated.  The value of the entire expression is that of the &lt;strong&gt;x&lt;sub&gt;i&lt;/sub&gt;&lt;/strong&gt; that terminated evaluation.&lt;/p&gt;
&lt;p&gt;To help demonstrate short-circuit evaluation, suppose that you have a simple &amp;ldquo;identity&amp;rdquo; function &lt;code&gt;f()&lt;/code&gt; that behaves as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;f()&lt;/code&gt; takes a single argument.&lt;/li&gt;
&lt;li&gt;It displays the argument to the console.&lt;/li&gt;
&lt;li&gt;It returns the argument passed to it as its return value.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(You will see how to define such a function in the upcoming tutorial on Functions.)&lt;/p&gt;
&lt;p&gt;Several example calls to &lt;code&gt;f()&lt;/code&gt; are shown below:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(0) = 0&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(False) = False&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(1.5) = 1.5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1.5&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Because &lt;code&gt;f()&lt;/code&gt; simply returns the argument passed to it, we can make the expression &lt;code&gt;f(arg)&lt;/code&gt; be truthy or falsy as needed by specifying a value for &lt;code&gt;arg&lt;/code&gt; that is appropriately truthy or falsy.  Additionally, &lt;code&gt;f()&lt;/code&gt; displays its argument to the console, which visually confirms whether or not it was called.&lt;/p&gt;
&lt;p&gt;Now, consider the following compound logical expression:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(0) = 0&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(False) = False&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(1) = 1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The interpreter first evaluates &lt;code&gt;f(0)&lt;/code&gt;, which is &lt;code&gt;0&lt;/code&gt;.  A numeric value of &lt;code&gt;0&lt;/code&gt; is false.  The expression is not true yet, so evaluation proceeds left to right.  The next operand, &lt;code&gt;f(False)&lt;/code&gt;, returns &lt;code&gt;False&lt;/code&gt;.  That is also false, so evaluation continues.&lt;/p&gt;
&lt;p&gt;Next up is &lt;code&gt;f(1)&lt;/code&gt;.  That evaluates to &lt;code&gt;1&lt;/code&gt;, which is true.  At that point, the interpreter stops because it now knows the entire expression to be true.  &lt;code&gt;1&lt;/code&gt; is returned as the value of the expression, and the remaining operands, &lt;code&gt;f(2)&lt;/code&gt; and &lt;code&gt;f(3)&lt;/code&gt;, are never evaluated.  You can see from the display that the &lt;code&gt;f(2)&lt;/code&gt; and &lt;code&gt;f(3)&lt;/code&gt; calls do not occur.&lt;/p&gt;
&lt;h4 id=&quot;compound-and-expressions&quot;&gt;Compound &amp;ldquo;&lt;code&gt;and&lt;/code&gt;&amp;rdquo; Expressions&lt;/h4&gt;
&lt;p&gt;A similar situation exists in an expression with multiple &lt;code&gt;and&lt;/code&gt; operators:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;x&lt;sub&gt;1&lt;/sub&gt;&lt;/strong&gt; &lt;code&gt;and&lt;/code&gt; &lt;strong&gt;x&lt;sub&gt;2&lt;/sub&gt;&lt;/strong&gt; &lt;code&gt;and&lt;/code&gt; &lt;strong&gt;x&lt;sub&gt;3&lt;/sub&gt;&lt;/strong&gt; &lt;code&gt;and&lt;/code&gt; &amp;hellip; &lt;strong&gt;x&lt;sub&gt;n&lt;/sub&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This expression is true if all the &lt;strong&gt;x&lt;sub&gt;i&lt;/sub&gt;&lt;/strong&gt; are true.&lt;/p&gt;
&lt;p&gt;In this case, short-circuit evaluation dictates that the interpreter stop evaluating as soon as any operand is found to be false, because at that point the entire expression is known to be false.  Once that is the case, no more operands are evaluated, and the falsy operand that terminated evaluation is returned as the value of the expression:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(1) = 1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(False) = False&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(1) = 1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(0.0) = 0.0&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In both examples above, evaluation stops at the first term that is false&amp;mdash;&lt;code&gt;f(False)&lt;/code&gt; in the first case, &lt;code&gt;f(0.0)&lt;/code&gt; in the second case&amp;mdash;and neither the &lt;code&gt;f(2)&lt;/code&gt; nor &lt;code&gt;f(3)&lt;/code&gt; call occurs.  &lt;code&gt;False&lt;/code&gt; and &lt;code&gt;0.0&lt;/code&gt;, respectively, are returned as the value of the expression.&lt;/p&gt;
&lt;p&gt;If all the operands are truthy, they all get evaluated and the last (rightmost) one is returned as the value of the expression:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;2.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(1) = 1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(2.2) = 2.2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;-&amp;gt; f(bar) = bar&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;idioms-that-exploit-short-circuit-evaluation&quot;&gt;Idioms That Exploit Short-Circuit Evaluation&lt;/h3&gt;
&lt;p&gt;There are some common idiomatic patterns that exploit short-circuit evaluation for conciseness of expression.&lt;/p&gt;
&lt;h4 id=&quot;avoiding-an-exception&quot;&gt;Avoiding an Exception&lt;/h4&gt;
&lt;p&gt;Suppose you have defined two variables &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt;, and you want to know whether &lt;code&gt;(b / a) &amp;gt; 0&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But you need to account for the possibility that &lt;code&gt;a&lt;/code&gt; might be &lt;code&gt;0&lt;/code&gt;, in which case the interpreter will &lt;a href=&quot;https://realpython.com/python-exceptions/&quot;&gt;raise an exception&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#2&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;ZeroDivisionError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;division by zero&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can avoid an error with an expression like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When &lt;code&gt;a&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;a != 0&lt;/code&gt; is false.  Short-circuit evaluation ensures that evaluation stops at that point.  &lt;code&gt;(b / a)&lt;/code&gt; is not evaluated, and no error is raised.&lt;/p&gt;
&lt;p&gt;If fact, you can be even more concise than that.  When &lt;code&gt;a&lt;/code&gt; is &lt;code&gt;0&lt;/code&gt;, the expression &lt;code&gt;a&lt;/code&gt; by itself is falsy.  There is no need for the explicit comparison &lt;code&gt;a != 0&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;selecting-a-default-value&quot;&gt;Selecting a Default Value&lt;/h4&gt;
&lt;p&gt;Another idiom involves selecting a default value when a specified value is zero or empty.  For example, suppose you want to assign a variable &lt;code&gt;s&lt;/code&gt; to the value contained in another variable called &lt;code&gt;string&lt;/code&gt;.  But if &lt;code&gt;string&lt;/code&gt; is empty, you want to supply a default value.&lt;/p&gt;
&lt;p&gt;Here is a concise way of expressing this using short-circuit evaluation:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;lt;default_value&amp;gt;&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;string&lt;/code&gt; is non-empty, it is truthy, and the expression &lt;code&gt;string or &#39;&amp;lt;default_value&amp;gt;&#39;&lt;/code&gt; will be true at that point.  Evaluation stops, and the value of &lt;code&gt;string&lt;/code&gt; is returned and assigned to &lt;code&gt;s&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;lt;default_value&amp;gt;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;foo bar&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On the other hand, if &lt;code&gt;string&lt;/code&gt; is an empty string, it is falsy.  Evaluation of &lt;code&gt;string or &#39;&amp;lt;default_value&amp;gt;&#39;&lt;/code&gt; continues to the next operand, &lt;code&gt;&#39;&amp;lt;default_value&amp;gt;&#39;&lt;/code&gt;, which is returned and assigned to &lt;code&gt;s&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;lt;default_value&amp;gt;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;&amp;lt;default_value&amp;gt;&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;chained-comparisons&quot;&gt;Chained Comparisons&lt;/h3&gt;
&lt;p&gt;Comparison operators can be chained together to arbitrary length.  For example, the following expressions are nearly equivalent:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;They will both evaluate to the same Boolean value.  The subtle difference between the two is that in the chained comparison &lt;code&gt;x &amp;lt; y &amp;lt;= z&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt; is evaluated only once.  The longer expression &lt;code&gt;x &amp;lt; y and y &amp;lt;= z&lt;/code&gt; will cause &lt;code&gt;y&lt;/code&gt; to be evaluated twice.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In cases where &lt;code&gt;y&lt;/code&gt; is a static value, this will not be a significant distinction.  But consider these expressions:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If &lt;code&gt;f()&lt;/code&gt; is a function that causes program data to be modified, the difference between its being called once in the first case and twice in the second case may be important.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;More generally, if &lt;strong&gt;&lt;em&gt;op&lt;sub&gt;1&lt;/sub&gt;&lt;/em&gt;, &lt;em&gt;op&lt;sub&gt;2&lt;/sub&gt;&lt;/em&gt;,&lt;/strong&gt; &amp;hellip;, &lt;strong&gt;&lt;em&gt;op&lt;sub&gt;n&lt;/sub&gt;&lt;/em&gt;&lt;/strong&gt; are comparison operators, then the following have the same Boolean value:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;x&lt;sub&gt;1&lt;/sub&gt; &lt;strong&gt;&lt;em&gt;op&lt;sub&gt;1&lt;/sub&gt;&lt;/em&gt;&lt;/strong&gt; x&lt;sub&gt;2&lt;/sub&gt; &lt;strong&gt;&lt;em&gt;op&lt;sub&gt;2&lt;/sub&gt;&lt;/em&gt;&lt;/strong&gt; x&lt;sub&gt;3&lt;/sub&gt; &amp;hellip; x&lt;sub&gt;n-1&lt;/sub&gt; &lt;strong&gt;&lt;em&gt;op&lt;sub&gt;n&lt;/sub&gt;&lt;/em&gt;&lt;/strong&gt; x&lt;sub&gt;n&lt;/sub&gt;&lt;/p&gt;
&lt;p&gt;x&lt;sub&gt;1&lt;/sub&gt; &lt;strong&gt;&lt;em&gt;op&lt;sub&gt;1&lt;/sub&gt;&lt;/em&gt;&lt;/strong&gt; x&lt;sub&gt;2&lt;/sub&gt; &lt;code&gt;and&lt;/code&gt; x&lt;sub&gt;2&lt;/sub&gt; &lt;strong&gt;&lt;em&gt;op&lt;sub&gt;2&lt;/sub&gt;&lt;/em&gt;&lt;/strong&gt; x&lt;sub&gt;3&lt;/sub&gt; &lt;code&gt;and&lt;/code&gt; &amp;hellip; x&lt;sub&gt;n-1&lt;/sub&gt; &lt;strong&gt;&lt;em&gt;op&lt;sub&gt;n&lt;/sub&gt;&lt;/em&gt;&lt;/strong&gt; x&lt;sub&gt;n&lt;/sub&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the former case, each x&lt;sub&gt;i&lt;/sub&gt; is only evaluated once. In the latter case, each will be evaluated twice except the first and last, unless short-circuit evaluation causes premature termination.&lt;/p&gt;
&lt;h2 id=&quot;bitwise-operators&quot;&gt;Bitwise Operators&lt;/h2&gt;
&lt;p&gt;Bitwise operators treat operands as sequences of binary digits and operate on them bit by bit.  The following operators are supported:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operator&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a &amp;amp; b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bitwise &lt;strong&gt;AND&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Each bit position in the result is the logical &lt;strong&gt;AND&lt;/strong&gt; of the bits in the corresponding position of the operands. (&lt;code&gt;1&lt;/code&gt; if both are &lt;code&gt;1&lt;/code&gt;, otherwise &lt;code&gt;0&lt;/code&gt;.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;#124;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a &amp;#124; b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bitwise &lt;strong&gt;OR&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Each bit position in the result is the logical &lt;strong&gt;OR&lt;/strong&gt; of the bits in the corresponding position of the operands. (&lt;code&gt;1&lt;/code&gt; if either is &lt;code&gt;1&lt;/code&gt;, otherwise &lt;code&gt;0&lt;/code&gt;.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;~&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;~a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bitwise &lt;strong&gt;negation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Each bit position in the result is the logical negation of the bit in the corresponding position of the operand. (&lt;code&gt;1&lt;/code&gt; if &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt; if &lt;code&gt;1&lt;/code&gt;.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;^&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a ^ b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bitwise &lt;strong&gt;XOR (exclusive OR)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Each bit position in the result is the logical &lt;strong&gt;XOR&lt;/strong&gt; of the bits in the corresponding position of the operands. (&lt;code&gt;1&lt;/code&gt; if the bits in the operands are different, &lt;code&gt;0&lt;/code&gt; if they are the same.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a &amp;gt;&amp;gt; n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Shift right&lt;/strong&gt; &lt;code&gt;n&lt;/code&gt; &lt;strong&gt;places&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Each bit is shifted right &lt;code&gt;n&lt;/code&gt; places.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a &amp;lt;&amp;lt; n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Shift left&lt;/strong&gt; &lt;code&gt;n&lt;/code&gt; &lt;strong&gt;places&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Each bit is shifted left &lt;code&gt;n&lt;/code&gt; places.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Here are some examples:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;0b{:04b}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mb&quot;&gt;0b1100&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;mb&quot;&gt;0b1010&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;0b1000&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;0b{:04b}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mb&quot;&gt;0b1100&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;mb&quot;&gt;0b1010&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;0b1110&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;0b{:04b}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mb&quot;&gt;0b1100&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt; &lt;span class=&quot;mb&quot;&gt;0b1010&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;0b0110&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;0b{:04b}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mb&quot;&gt;0b1100&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;0b0011&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;0b{:04b}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mb&quot;&gt;0b0011&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;0b1100&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The purpose of the &lt;code&gt;&#39;0b{:04b}&#39;.format()&lt;/code&gt; is to format the numeric output of the bitwise operations, to make them easier to read.  You will see the &lt;code&gt;format()&lt;/code&gt; method in much more detail later.  For now, just pay attention to the operands of the bitwise operations, and the results.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;identity-operators&quot;&gt;Identity Operators&lt;/h2&gt;
&lt;p&gt;Python provides two operators, &lt;code&gt;is&lt;/code&gt; and &lt;code&gt;is not&lt;/code&gt;, that determine whether the given operands have the same identity&amp;mdash;that is, refer to the same object.  This is not the same thing as equality, which means the two operands refer to objects that contain the same data but are not necessarily the same object.&lt;/p&gt;
&lt;p&gt;Here is an example of two object that are equal but not identical:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1001&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1001 1001&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; both refer to objects whose value is &lt;code&gt;1001&lt;/code&gt;.  They are equal.  But they do not reference the same object, as you can verify:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;60307920&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;60307936&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; do not have the same identity, and  &lt;code&gt;x is y&lt;/code&gt; returns &lt;code&gt;False&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You saw previously that when you make an assignment like &lt;code&gt;x = y&lt;/code&gt;, Python merely creates a second reference to the same object, and that you could confirm that fact with the &lt;code&gt;id()&lt;/code&gt; function.  You can also confirm it using the &lt;code&gt;is&lt;/code&gt; operator:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;I am a string&amp;#39;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;55993992&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;55993992&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this case, since &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; reference the same object, it stands to reason that &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;b&lt;/code&gt; would be equal as well.&lt;/p&gt;
&lt;p&gt;Unsurprisingly, the opposite of &lt;code&gt;is&lt;/code&gt; is &lt;code&gt;is not&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;operator-precedence&quot;&gt;Operator Precedence&lt;/h2&gt;
&lt;p&gt;Consider this expression:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;60&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There is ambiguity here.  Should Python perform the addition &lt;code&gt;20 + 4&lt;/code&gt; first and then multiply the sum by &lt;code&gt;10&lt;/code&gt;?  Or should the multiplication &lt;code&gt;4 * 10&lt;/code&gt; be performed first, and the addition of &lt;code&gt;20&lt;/code&gt; second?&lt;/p&gt;
&lt;p&gt;Clearly, since the result is &lt;code&gt;60&lt;/code&gt;, Python has chosen the latter; if it had chosen the former, the result would be &lt;code&gt;240&lt;/code&gt;.  This is standard algebraic procedure, found universally in virtually all programming languages.&lt;/p&gt;
&lt;p&gt;All operators that the language supports are assigned a precedence.  In an expression, all operators of highest precedence are performed first.  Once those results are obtained, operators of the next highest precedence are performed.  So it continues, until the expression is fully evaluated.  Any operators of equal precedence are performed in left-to-right order.&lt;/p&gt;
&lt;p&gt;Here is the order of precedence of the Python operators you have seen so far, from lowest to highest:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&amp;nbsp;&lt;/th&gt;
&lt;th&gt;Operator&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;em&gt;lowest precedence&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;or&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Boolean OR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;and&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Boolean AND&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;not&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Boolean NOT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;==&lt;/code&gt;, &lt;code&gt;!=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;gt;=&lt;/code&gt;, &lt;code&gt;is&lt;/code&gt;, &lt;code&gt;is not&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;comparisons, identity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;#124;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bitwise OR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;^&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bitwise XOR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bitwise AND&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;bit shifts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;addition, subtraction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;//&lt;/code&gt;, &lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;multiplication, division, floor division, modulo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;+x&lt;/code&gt;, &lt;code&gt;-x&lt;/code&gt;, &lt;code&gt;~x&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;unary positive, unary negation, bitwise negation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;em&gt;highest precedence&lt;/em&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;**&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;exponentiation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Operators at the top of the table have the lowest precedence, and those at the bottom of the table have the highest.  Any operators in the same row of the table have equal precedence.&lt;/p&gt;
&lt;p&gt;It is clear why multiplication is performed first in the example above: multiplication has a higher precedence than addition.  &lt;/p&gt;
&lt;p&gt;Similarly, in the example below, &lt;code&gt;3&lt;/code&gt; is raised to the power of &lt;code&gt;4&lt;/code&gt; first, which equals &lt;code&gt;81&lt;/code&gt;, and then the multiplications are carried out in order from left to right (&lt;code&gt;2 * 81 * 5 = 810&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;810&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Operator precedence can be overridden using parentheses.  Expressions in parentheses are always performed first, before expressions that are not parenthesized.  Thus, the following happens:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;60&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;240&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;810&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;6973568802&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the first example, &lt;code&gt;20 + 4&lt;/code&gt; is computed first, then the result is multiplied by &lt;code&gt;10&lt;/code&gt;.  In the second example, &lt;code&gt;4 * 5&lt;/code&gt; is calculated first, then &lt;code&gt;3&lt;/code&gt; is raised to that power, then the result is multiplied by &lt;code&gt;2&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;There is nothing wrong with making liberal use of parentheses, even when they aren&amp;rsquo;t necessary to change the order of evaluation.  In fact, it is considered good practice, because it can make the code more readable, and it relieves the reader of having to recall operator precedence from memory.  Consider the following:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here the parentheses are fully unnecessary, as the comparison operators have higher precedence than &lt;code&gt;and&lt;/code&gt; does and would have been performed first anyhow.  But some might consider the intent of the parenthesized version more immediately obvious than this version without parentheses:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;On the other hand, there are probably those who would prefer the latter; it&amp;rsquo;s a matter of personal preference.  The point is, you can always use parentheses if you feel it makes the code more readable, even if they aren&amp;rsquo;t necessary to change the order of evaluation.&lt;/p&gt;
&lt;h2 id=&quot;augmented-assignment-operators&quot;&gt;Augmented Assignment Operators&lt;/h2&gt;
&lt;p&gt;You have seen that a single equal sign (&lt;code&gt;=&lt;/code&gt;) is used to assign a value to a variable.  It is, of course, perfectly viable for the value to the right of the assignment to be an expression containing other variables:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;70&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In fact, the expression to the right of the assignment can include references to the variable that is being assigned to:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;15&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;60&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The first example is interpreted as &amp;ldquo;&lt;code&gt;a&lt;/code&gt; is assigned the current value of &lt;code&gt;a&lt;/code&gt; plus &lt;code&gt;5&lt;/code&gt;,&amp;rdquo; effectively increasing the value of &lt;code&gt;a&lt;/code&gt; by &lt;code&gt;5&lt;/code&gt;.  The second reads &amp;ldquo;&lt;code&gt;b&lt;/code&gt; is assigned the current value of &lt;code&gt;b&lt;/code&gt; times &lt;code&gt;3&lt;/code&gt;,&amp;rdquo; effectively increasing the value of &lt;code&gt;b&lt;/code&gt; threefold.&lt;/p&gt;
&lt;p&gt;Of course, this sort of assignment only makes sense if the variable in question has already previously been assigned a value:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;pyshell#11&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;z&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;NameError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;name &amp;#39;z&amp;#39; is not defined&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Python supports a shorthand augmented assignment notation for these arithmetic and bitwise operators:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Arithmetic&lt;/th&gt;
&lt;th&gt;Bitwise&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;+&lt;/code&gt;&lt;br&gt;&lt;code&gt;-&lt;/code&gt;&lt;br&gt;&lt;code&gt;*&lt;/code&gt;&lt;br&gt;&lt;code&gt;/&lt;/code&gt;&lt;br&gt;&lt;code&gt;%&lt;/code&gt;&lt;br&gt;&lt;code&gt;//&lt;/code&gt;&lt;br&gt;&lt;code&gt;**&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;amp;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;#124;&lt;/code&gt;&lt;br&gt;&lt;code&gt;^&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt;&lt;br&gt;&lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;For these operators, the following are equivalent:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;op&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;op&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Take a look at these examples:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Augmented&lt;br&gt;Assignment&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Standard&lt;br&gt;Assignment&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a += 5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;is equivalent to&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a = a + 5&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a /= 10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;is equivalent to&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a = a / 10&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a ^= b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;is equivalent to&lt;/td&gt;
&lt;td&gt;&lt;code&gt;a = a ^ b&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this tutorial, you learned about the diverse &lt;strong&gt;operators&lt;/strong&gt; Python supports to combine objects into &lt;strong&gt;expressions&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Most of the examples you have seen so far have involved only simple atomic data, but you saw a brief introduction to the &lt;strong&gt;string&lt;/strong&gt; data type.  The next tutorial will explore &lt;strong&gt;string&lt;/strong&gt; objects in much more detail.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Get Notified:&lt;/strong&gt; Don&#39;t miss the follow up to this tutorial—&lt;a href=&quot;https://realpython.com/optins/view/newsletter-dont-miss-updates/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-newsletter-dont-miss-updates&quot; data-focus=&quot;false&quot;&gt;Click here to join the Real Python Newsletter&lt;/a&gt; and you&#39;ll know when the next installment comes out.&lt;/p&gt;&lt;/div&gt;

&lt;div class=&quot;container py-3 series-nav mb-3&quot;&gt;
  &lt;div class=&quot;row justify-content-between&quot;&gt;
    &lt;div class=&quot;col-12 col-md-3 text-left text-muted ml-1&quot;&gt;&lt;a href=&quot;https://realpython.com/python-variables/&quot;&gt; «&amp;nbsp;Variables in Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-center text-muted&quot;&gt;&lt;a href=&quot;#&quot;&gt;Operators and Expressions in Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-right text-muted mr-1&quot;&gt;&lt;a &gt;Strings in Python&amp;nbsp;»&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Ultimate List of Python YouTube Channels</title>
      <id>https://realpython.com/python-youtube-channels/</id>
      <link href="https://realpython.com/python-youtube-channels/"/>
      <updated>2018-06-18T14:00:00+00:00</updated>
      <summary>We couldn&#39;t find a good and updated list of Python developer or Python programming YouTube channels online. So we created our own list with the best and most Pythonic YouTubers.</summary>
      <content type="html">
        &lt;p&gt;We couldn&amp;rsquo;t find a good, up-to-date list of Python developer or Python programming YouTube channels online.&lt;/p&gt;
&lt;p&gt;Learning Python on YouTube is a viable option these days, and we&amp;rsquo;re excited about what this new medium can do for programming education.&lt;/p&gt;
&lt;p&gt;There are some really good YouTube channels that focus on Python development out there, but we just couldn&amp;rsquo;t find a list that was both comprehensive and up-to-date. So we created our own with the best and most Pythonic YouTubers.&lt;/p&gt;
&lt;p&gt;We initially wrote this list based on information we gathered by reading forum posts and searching YouTube for Python channels directly. We&amp;rsquo;ll continue to add to the list with your feedback. We plan to keep this list updated, so feel free to leave a comment at the end of the page or &lt;a href=&quot;https://twitter.com/realpython&quot;&gt;tweet at us&lt;/a&gt; if you think anything is missing or if you&amp;rsquo;d like to see your own YouTube Python tutorials added.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;In order for a channel to be included in our list, it must:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Focus on Python tutorials&lt;/li&gt;
&lt;li&gt;Not be brand-new (&amp;gt; 2,000 subscribers)&lt;/li&gt;
&lt;li&gt;Be active (new videos are coming out) &lt;em&gt;OR&lt;/em&gt; have an interesting archive with old content worth watching&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p&gt;Enjoy the Python goodness! 📹🐍&lt;/p&gt;
&lt;h2 id=&quot;al-sweigart&quot;&gt;&lt;a href=&quot;https://www.youtube.com/user/Albert10110/&quot;&gt;Al Sweigart&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Tons of sweet computer related tutorials and some other awesome videos too!&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;https://automatetheboringstuff.com/&quot;&gt;automatetheboringstuff.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/AlSweigart&quot;&gt;@AlSweigart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/user/Albert10110/&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;anaconda-inc&quot;&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCND4vKhJssAtK8p1Blfj14Q&quot;&gt;Anaconda Inc.&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;With over 4.5 million users, Anaconda is the world’s most popular Python data science platform. Anaconda, Inc. continues to lead open source projects like Anaconda, NumPy and SciPy that form the foundation of modern data science.  Anaconda’s flagship product, Anaconda Enterprise, allows organizations to secure, govern, scale and extend Anaconda to deliver actionable insights that drive businesses and industries forward.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In addition to their company developed videos, including a fun &lt;a href=&quot;https://www.youtube.com/watch?v=60ukQ_8TsPY&quot;&gt;lego-mation&lt;/a&gt; and &lt;a href=&quot;https://www.youtube.com/watch?v=60ukQ_8TsPY&quot;&gt;Pyception&lt;/a&gt; short, Anaconda’s YouTube channel contains all the videos from AnacondaCon, a gathering of the passionate community of data scientists, IT professionals, analysts, developers, and business leaders all using the Anaconda distribution.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;https://www.anaconda.com/&quot;&gt;anaconda.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/anacondainc&quot;&gt;@anacondainc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/channel/UCND4vKhJssAtK8p1Blfj14Q&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;christian-thompson&quot;&gt;&lt;a href=&quot;https://www.youtube.com/c/ChristianThompson_Python&quot;&gt;Christian Thompson&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;A little bit about me and a lot about Python programming for beginners. I am a middle and high school teacher who uses Python as my teaching language. I firmly believe anyone can (and should) learn to program a computer and that Python is the perfect language for doing so.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;http://christianthompson.com/&quot;&gt;christianthompson.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/tokyoedtech&quot;&gt;@tokyoedtech&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/c/ChristianThompson_Python&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;clever-programmer&quot;&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCqrILQNl5Ed9Dz6CGMyvMTQ&quot;&gt;Clever Programmer&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;You can find awesome programming lessons here! Also, expect programming tips and tricks that will take your coding skills to the next level.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;https://www.cleverprogrammer.com/&quot;&gt;cleverprogrammer.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/cleverqazi&quot;&gt;@cleverqazi&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/channel/UCqrILQNl5Ed9Dz6CGMyvMTQ&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;codingentrepreneurs&quot;&gt;&lt;a href=&quot;https://www.youtube.com/user/CodingEntrepreneurs/&quot;&gt;CodingEntrepreneurs&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Coding for Entrepreneurs is a Programming Series for Non-Technical Founders. Learn Django, Python, APIs, Accepting Payments, Stripe, jQuery, Twitter Bootstrap, and much more.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;https://www.codingforentrepreneurs.com/&quot;&gt;www.codingforentrepreneurs.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/joincfe&quot;&gt;@joincfe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/user/CodingEntrepreneurs/&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;corey-schafer&quot;&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g&quot;&gt;Corey Schafer&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;This channel is focused on creating tutorials and walkthroughs for software developers, programmers, and engineers. We cover topics for all different skill levels, so whether you are a beginner or have many years of experience, this channel will have something for you.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;http://coreyms.com/&quot;&gt;coreyms.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/CoreyMSchafer&quot;&gt;@CoreyMSchafer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/channel/UCCezIgC97PvUuR4_gbFUs5g&quot;&gt;YouTube&lt;/a&gt; ⋅ &lt;a href=&quot;https://www.patreon.com/coreyms&quot;&gt;Patreon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;chris-hawkes&quot;&gt;&lt;a href=&quot;https://www.youtube.com/user/noobtoprofessional/&quot;&gt;Chris Hawkes&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;We&amp;rsquo;re going to learn about programming, web design, responsive web design, Reactjs, Django, Python, web scraping, games, forms applications and more!&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/realchrishawkes&quot;&gt;@realchrishawkes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/user/noobtoprofessional/&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;cs-dojo&quot;&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCxX9wt5FWQUAAz4UrysqK9A&quot;&gt;CS Dojo&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Hey everyone! My name is YK, and I make videos mostly about programming and computer science here.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;https://www.csdojo.io/&quot;&gt;csdojo.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/ykdojo&quot;&gt;@ykdojo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/channel/UCxX9wt5FWQUAAz4UrysqK9A&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;data-school-kevin-markham&quot;&gt;&lt;a href=&quot;https://www.youtube.com/user/dataschool&quot;&gt;Data School (Kevin Markham)&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;You&amp;rsquo;re trying to launch your career in data science, and I want to help you reach that goal! My in-depth tutorials will help you to master crucial data science topics using open source tools like Python and R.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;http://www.dataschool.io/&quot;&gt;www.dataschool.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/justmarkham&quot;&gt;@justmarkham&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/user/dataschool&quot;&gt;YouTube&lt;/a&gt; ⋅ &lt;a href=&quot;https://www.patreon.com/dataschool&quot;&gt;Patreon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;david-beazley&quot;&gt;&lt;a href=&quot;https://www.youtube.com/user/dabeazllc/&quot;&gt;David Beazley&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;An archive of David Beazley&amp;rsquo;s conference, user group, and training talks.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;http://www.dabeaz.com/&quot;&gt;www.dabeaz.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/dabeaz&quot;&gt;@dabeaz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/user/dabeazllc/&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;enthought&quot;&gt;&lt;a href=&quot;https://www.youtube.com/user/EnthoughtMedia&quot;&gt;Enthought&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;For more than 15 years, Enthought has built AI solutions with science and engineering at the core. We accelerate digital transformation by enabling companies and their people to leverage the benefits of Artificial Intelligence and Machine Learning.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Additionally, Enthought is best known for the early development, maintenance, and continued support of &lt;a href=&quot;https://www.scipy.org/&quot;&gt;SciPy&lt;/a&gt;, as well as the primary sponsor for the SciPy US and EuroSciPy Conferences.  In addition to the company developed content, this channel provides all the video recordings from the SciPy US and EuroScipy (before 2016) Conferences, talks and tutorials specifically focused on the advancement of scientific computing through open source Python software for mathematics, science, and engineering.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;https://www.enthought.com/&quot;&gt;enthought.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/enthought&quot;&gt;@enthought&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/user/EnthoughtMedia&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;michael-kennedy-talk-python&quot;&gt;&lt;a href=&quot;https://www.youtube.com/user/mkennedy66996694&quot;&gt;Michael Kennedy (Talk Python)&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Videos, demos, and lectures about programming - especially Python and web topics.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;https://talkpython.fm/&quot;&gt;talkpython.fm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/mkennedy&quot;&gt;@mkennedy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/user/mkennedy66996694&quot;&gt;YouTube&lt;/a&gt; ⋅ &lt;a href=&quot;https://talkpython.fm/&quot;&gt;Podcast&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;practical-python&quot;&gt;&lt;a href=&quot;https://www.youtube.com/channel/UC0MjyrJVnDLc8a2JTbeH6Mg/&quot;&gt;Practical Python&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Expect unexpected.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/channel/UC0MjyrJVnDLc8a2JTbeH6Mg&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;prettyprinted&quot;&gt;&lt;a href=&quot;https://www.youtube.com/channel/UC-QDfvrRIDB6F0bIO4I4HkQ/&quot;&gt;PrettyPrinted&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;I&amp;rsquo;m Anthony. I make programming videos.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;https://prettyprinted.com/&quot;&gt;prettyprinted.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/pretty_printed&quot;&gt;@pretty_printed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/channel/UC-QDfvrRIDB6F0bIO4I4HkQ/&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;pycon-session-recordings&quot;&gt;&lt;a href=&quot;https://www.youtube.com/results?search_query=PyCon&amp;amp;sp=EgIQAg%253D%253D&quot;&gt;PyCon Session Recordings&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;These are all PyCon talk and session recordings made available on YouTube. There&amp;rsquo;s no single channel that combines these. Instead, you&amp;rsquo;ll access each year&amp;rsquo;s videos on a separate &amp;ldquo;PyCon 20&amp;hellip;&amp;rdquo; channel. Alternatively, you can use &lt;a href=&quot;http://pyvideo.org/&quot;&gt;PyVideo.org&lt;/a&gt; to watch the session recordings.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;http://www.pycon.org/&quot;&gt;www.pycon.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/pycon&quot;&gt;@PyCon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/results?search_query=PyCon&amp;amp;sp=EgIQAg%253D%253D&quot;&gt;YouTube&lt;/a&gt; ⋅ &lt;a href=&quot;http://pyvideo.org/&quot;&gt;PyVideo.org&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;pydata&quot;&gt;&lt;a href=&quot;https://www.youtube.com/user/PyDataTV/&quot;&gt;PyData&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;PyData provides a forum for the international community of users and developers of data analysis tools to share ideas and learn from each other. The global PyData network promotes discussion of best practices, new approaches, and emerging technologies for data management, processing, analytics, and visualization. PyData communities approach data science using many languages, including (but not limited to) Python, Julia, and R.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;https://pydata.org/&quot;&gt;pydata.org&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/PyData&quot;&gt;@PyData&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/user/PyDataTV/&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;python-training-by-dan-bader&quot;&gt;&lt;a href=&quot;https://www.youtube.com/c/realpython&quot;&gt;Python Training by Dan Bader&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Python tutorials and training videos for Pythonistas that go beyond the basics. On this channel you’ll get new Python videos and screencasts every week. They’re bite-sized and to the point so you can fit them in with your day and pick up new Python skills on the side.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;https://dbader.org/&quot;&gt;dbader.org&lt;/a&gt; ⋅ &lt;a href=&quot;https://realpython.com&quot;&gt;realpython.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/dbader_org&quot;&gt;@dbader_org&lt;/a&gt; ⋅ &lt;a href=&quot;https://twitter.com/realpython&quot;&gt;@realpython&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/c/realpython&quot;&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;sentdex-harrison-kinsley&quot;&gt;&lt;a href=&quot;https://www.youtube.com/user/sentdex&quot;&gt;Sentdex (Harrison Kinsley)&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Python Programming tutorials, going further than just the basics. Learn about machine learning, finance, data analysis, robotics, web development, game development and more.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;http://pythonprogramming.net/&quot;&gt;pythonprogramming.net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/sentdex&quot;&gt;@sentdex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/user/sentdex&quot;&gt;YouTube&lt;/a&gt; ⋅ &lt;a href=&quot;https://www.patreon.com/sentdex&quot;&gt;Patreon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;siraj-raval&quot;&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCWN3xxRkmTPmbKwht9FuE5A/&quot;&gt;Siraj Raval&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;I&amp;rsquo;m Siraj. I&amp;rsquo;m on a warpath to inspire and educate developers to build Artificial Intelligence. Games, music, chatbots, art, i&amp;rsquo;ll teach you how to make it all yourself.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;http://www.twitter.com/sirajraval&quot;&gt;@sirajraval&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/channel/UCWN3xxRkmTPmbKwht9FuE5A/&quot;&gt;YouTube&lt;/a&gt; ⋅ &lt;a href=&quot;https://www.patreon.com/sirajraval&quot;&gt;Patreon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;socratica&quot;&gt;&lt;a href=&quot;https://www.youtube.com/user/SocraticaStudios/&quot;&gt;Socratica&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Socratica makes high-quality educational videos on math and science. New videos every week! We&amp;rsquo;re a couple of Caltech grads who believe you deserve better videos. You&amp;rsquo;ll learn more with us!&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;http://www.socratica.com/&quot;&gt;www.socratica.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/socratica&quot;&gt;@socratica&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/user/SocraticaStudios/&quot;&gt;YouTube&lt;/a&gt; ⋅ &lt;a href=&quot;https://www.patreon.com/socratica&quot;&gt;Patreon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;thenewboston-bucky-roberts&quot;&gt;&lt;a href=&quot;https://www.youtube.com/user/thenewboston/&quot;&gt;TheNewBoston (Bucky Roberts)&lt;/a&gt;&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Tons of sweet computer related tutorials and some other awesome videos too!&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Website: &lt;a href=&quot;http://thenewboston.com/&quot;&gt;thenewboston.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href=&quot;https://twitter.com/bucky_roberts&quot;&gt;@bucky_roberts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Subscribe: &lt;a href=&quot;https://www.youtube.com/user/thenewboston/&quot;&gt;YouTube&lt;/a&gt; ⋅ &lt;a href=&quot;https://www.patreon.com/thenewboston&quot;&gt;Patreon&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;smaller-python-conferences&quot;&gt;Smaller Python Conferences&lt;/h2&gt;
&lt;p&gt;The following channels provide the tutorials, talks, and session recordings from many of the smaller local Python conferences held throughout the world.&lt;/p&gt;
&lt;p&gt;Though on their own, most of these channels do not meet the requirement for 2000 subscribers, we list them here as honorable mentions because they represent the diverse Python community throughout the world.&lt;/p&gt;
&lt;p&gt;Note that some (maybe older) videos from these conferences are available (together with other non-Python content) on the &lt;a href=&quot;https://www.youtube.com/user/NextDayVideo/videos&quot;&gt;Next Day Video&lt;/a&gt; and &lt;a href=&quot;https://www.youtube.com/channel/UCjRZr5HQKHVKP3SZdX8y8Qw&quot;&gt;Engineers.SG&lt;/a&gt; channels. Alternatively, &lt;a href=&quot;http://pyvideo.org/&quot;&gt;PyVideo.org&lt;/a&gt; can serve as a one-stop-shop where you can find most (but not all) of these session recordings.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UC98CzaYuFNAA_gOINFB0e4Q&quot;&gt;EuroPython&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCruMegFU9dg2doEGOUaAWTg&quot;&gt;EuroSciPy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCJ_gIPLffA7ZTYc5gOV6MgA&quot;&gt;Kiwi PyCon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCtWI06j1EADmEOGj2iJhSyA&quot;&gt;PyCascades&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCa8tmvBoe5L6BGmRcQHF8qw&quot;&gt;PyCon Argentina (Ar)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCS9sdEyduD9K83K3GkvQlOA&quot;&gt;PyCon Australia (AU)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCclkPrurwUP_ajqi3vDTNDg&quot;&gt;PyCon Canada&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCRC2Vu7p4SJxhhuRdl8rQ6g&quot;&gt;PyCon Czech (CZ)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCztHeKs0ZU6T0Cy7VjA_RgA&quot;&gt;PyCon Finland&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCji5VWDkGzuRenyRQZ9OpFQ&quot;&gt;PyCon Germany (DE)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCQJEx-ZrVjpB7dYWnO4EecA&quot;&gt;PyCon Hong Kong (HG)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCXlA9u2VPI9nIALNUBF0Nzw&quot;&gt;PyCon Ireland (IE)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/user/pyconitalia&quot;&gt;PyCon Italy (Nove)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCxNoKygeZIE1AwZ_NdUCkhQ&quot;&gt;PyCon Japan (JP)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UC26x6D5xpKx6io4ShfXa_Ow&quot;&gt;PyCon Korea (KR)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCHbZFEch7FdQbK3ZXsTw0Cw&quot;&gt;PyCon Malaysia (MY)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCkq4w29wjhNCdNegMecivqg&quot;&gt;PyCon Phillipines (PH)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/user/pyconpl&quot;&gt;PyCon Poland (PL)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCVN315m23vfiVuU4Ov51tDw&quot;&gt;PyCon Singapore (SG)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UC8Tzn82aG4zdvtqlrfsLgSA&quot;&gt;PyCon Slovakia (SK)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCJ2lwx-pNVF_EoWlHAmNNtQ&quot;&gt;PyCon Ukraine (UA)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UChA9XP_feY1-1oSy2L7acog&quot;&gt;PyCon United Kingdom (UK)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCKWYZNMRBRuecwgZMLy-8gw&quot;&gt;PyGotham 2017&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCYqdrfvhGxNW3vXebypqXoQ&quot;&gt;PyOhio&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;If you think anything is missing from this list or if you&amp;rsquo;d like to see your own Python YouTube channel added, then please leave a comment below or &lt;a href=&quot;https://twitter.com/realpython&quot;&gt;tweet at us&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Variables in Python</title>
      <id>https://realpython.com/python-variables/</id>
      <link href="https://realpython.com/python-variables/"/>
      <updated>2018-06-12T14:00:00+00:00</updated>
      <summary>Learn how every item of data in a Python program can be described by the abstract term &quot;object,&quot; and how to manipulate objects using symbolic names called &quot;variables.&quot;</summary>
      <content type="html">
        &lt;p&gt;In the previous tutorial on &lt;a href=&quot;https://realpython.com/python-data-types/&quot;&gt;Basic Data Types in Python&lt;/a&gt;, you saw how values of various Python data types can be created.  But so far, all the values shown have been literal or constant values:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;5.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5.3&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you&amp;rsquo;re writing more complex code, your program will need data that can change as program execution proceeds.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Here&amp;rsquo;s what you&amp;rsquo;ll learn in this tutorial:&lt;/strong&gt; You will learn how every item of data in a Python program can be described by the abstract term &lt;strong&gt;object&lt;/strong&gt;,  and you&amp;rsquo;ll learn how to manipulate objects using symbolic names called &lt;strong&gt;variables&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free PDF Download:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/optins/view/python-cheat-sheet-short/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-cheat-sheet-short&quot; data-focus=&quot;false&quot;&gt;Python 3 Cheat Sheet&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;variable-assignment&quot;&gt;Variable Assignment&lt;/h2&gt;
&lt;p&gt;Think of a variable as a name attached to a particular object. In Python, variables need not be declared or defined in advance, as is the case in many other programming languages.  To create a variable, you just assign it a value and then start using it.  Assignment is done with a single equals sign (&lt;code&gt;=&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is read or interpreted as &amp;ldquo;&lt;code&gt;n&lt;/code&gt; is assigned the value &lt;code&gt;300&lt;/code&gt;.&amp;rdquo;  Once this is done, &lt;code&gt;n&lt;/code&gt; can be used in a statement or expression, and its value will be substituted:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;300&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Just as a literal value can be displayed directly from the interpreter prompt in a REPL session without the need for &lt;code&gt;print()&lt;/code&gt;, so can a variable:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;300&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Later, if you change the value of &lt;code&gt;n&lt;/code&gt; and use it again, the new value will be substituted instead:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1000&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1000&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Python also allows chained assignment, which makes it possible to assign the same value to several variables simultaneously:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;300 300 300&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The chained assignment above assigns &lt;code&gt;300&lt;/code&gt; to the variables &lt;code&gt;a&lt;/code&gt;, &lt;code&gt;b&lt;/code&gt;, and &lt;code&gt;c&lt;/code&gt; simultaneously.&lt;/p&gt;
&lt;h2 id=&quot;variable-types-in-python&quot;&gt;Variable Types in Python&lt;/h2&gt;
&lt;p&gt;In many programming languages, variables are statically typed.  That means a variable is initially declared to have a specific data type, and any value assigned to it during its lifetime must always have that type.&lt;/p&gt;
&lt;p&gt;Variables in Python are not subject to this restriction.  In Python, a variable may be assigned a value of one type and then later re-assigned a value of a different type:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;23.5&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;23.5&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Now I&amp;#39;m a string&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Now I&amp;#39;m a string&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;object-references&quot;&gt;Object References&lt;/h2&gt;
&lt;p&gt;What is actually happening when you make a variable assignment?  This is an important question in Python, because the answer differs somewhat from what you&amp;rsquo;d find in many other programming languages.&lt;/p&gt;
&lt;p&gt;Python is a highly &lt;a href=&quot;https://realpython.com/python3-object-oriented-programming/&quot;&gt;object-oriented language&lt;/a&gt;.  In fact, virtually every item of data in a Python program is an object of a specific type or class. (This point will be reiterated many times over the course of these tutorials.)&lt;/p&gt;
&lt;p&gt;Consider this code:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;300&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When presented with the statement &lt;code&gt;print(300)&lt;/code&gt;, the interpreter does the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creates an integer object&lt;/li&gt;
&lt;li&gt;Gives it the value &lt;code&gt;300&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Displays it to the console&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can see that an integer object is created using the built-in &lt;code&gt;type()&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;int&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A Python variable is a symbolic name that is a reference or pointer to an object.  Once an object is assigned to a variable, you can refer to the object by that name.  But the data itself is still contained within the object.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This assignment creates an integer object with the value &lt;code&gt;300&lt;/code&gt; and assigns the variable &lt;code&gt;n&lt;/code&gt; to point to that object.&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.2d7bcb9afaaf.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/t.2d7bcb9afaaf.png&quot; width=&quot;636&quot; height=&quot;186&quot; alt=&quot;Variable reference diagram&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Variable Assignment&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;The following code verifies that &lt;code&gt;n&lt;/code&gt; points to an integer object:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;300&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;int&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now consider the following statement:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What happens when it is executed? Python does not create another object.  It simply creates a new symbolic name or reference, &lt;code&gt;m&lt;/code&gt;, which points to the same object that &lt;code&gt;n&lt;/code&gt; points to.&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.d368386b8423.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/t.d368386b8423.png&quot; width=&quot;1083&quot; height=&quot;186&quot; alt=&quot;Python variable references to the same object (illustration)&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Multiple References to a Single Object&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Next, suppose you do this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now Python creates a new integer object with the value &lt;code&gt;400&lt;/code&gt;, and &lt;code&gt;m&lt;/code&gt; becomes a reference to it.&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.d476d91592cd.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/t.d476d91592cd.png&quot; width=&quot;1083&quot; height=&quot;426&quot; alt=&quot;References to separate objects in Python (diagram)&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;References to Separate Objects&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Lastly, suppose this statement is executed next:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now Python creates a string object with the value &lt;code&gt;&quot;foo&quot;&lt;/code&gt; and makes &lt;code&gt;n&lt;/code&gt; reference that.&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/t.344ab0b3aa8c.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/t.344ab0b3aa8c.png&quot; width=&quot;1083&quot; height=&quot;666&quot; alt=&quot;Python variable reference illustration&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Orphaned Object&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;There is no longer any reference to the integer object &lt;code&gt;300&lt;/code&gt;.  It is orphaned, and there is no way to access it.&lt;/p&gt;
&lt;p&gt;Tutorials in this series will occasionally refer to the lifetime of an object.  An object&amp;rsquo;s life begins when it is created, at which time at least one reference to it is created.  During an object&amp;rsquo;s lifetime, additional references to it may be created, as you saw above, and references to it may be deleted as well.  An object stays alive, as it were, so long as there is at least one reference to it.&lt;/p&gt;
&lt;p&gt;When the number of references to an object drops to zero, it is no longer accessible.  At that point, its lifetime is over.  Python will eventually notice that it is inaccessible and reclaim the allocated memory so it can be used for something else.  In computer lingo, this process is referred to as &lt;a href=&quot;https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29&quot;&gt;garbage collection&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;object-identity&quot;&gt;Object Identity&lt;/h2&gt;
&lt;p&gt;In Python, every object that is created is given a number that uniquely identifies it.  It is guaranteed that no two objects will have the same identifier during any period in which their lifetimes overlap.  Once an object&amp;rsquo;s reference count drops to zero and it is garbage collected, as happened to the &lt;code&gt;300&lt;/code&gt; object above, then its identifying number becomes available and may be used again.&lt;/p&gt;
&lt;p&gt;The built-in Python function &lt;code&gt;id()&lt;/code&gt; returns an object&amp;rsquo;s integer identifier.  Using the &lt;code&gt;id()&lt;/code&gt; function, you can verify that two variables indeed point to the same object:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;60127840&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;60127840&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;60127872&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After the assignment &lt;code&gt;m = n&lt;/code&gt;, &lt;code&gt;m&lt;/code&gt; and &lt;code&gt;n&lt;/code&gt; both point to the same object, confirmed by the fact that &lt;code&gt;id(m)&lt;/code&gt; and &lt;code&gt;id(n)&lt;/code&gt; return the same number.  Once &lt;code&gt;m&lt;/code&gt; is reassigned to &lt;code&gt;400&lt;/code&gt;, &lt;code&gt;m&lt;/code&gt; and &lt;code&gt;n&lt;/code&gt; point to different objects with different identities.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p class=&quot;h3&quot;&gt;Deep Dive: Caching Small Integer Values&lt;/p&gt;
&lt;p&gt;From what you now know about variable assignment and object references in Python, the following probably won&amp;rsquo;t surprise you:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;60062304&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;60062896&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With the statement &lt;code&gt;m = 300&lt;/code&gt;, Python creates an integer object with the value &lt;code&gt;300&lt;/code&gt; and sets &lt;code&gt;m&lt;/code&gt; as a reference to it.  &lt;code&gt;n&lt;/code&gt; is then similarly assigned to an integer object with value &lt;code&gt;300&lt;/code&gt;&amp;mdash;but not the same object.  Thus, they have different identities, which you can verify from the values returned by &lt;code&gt;id()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But consider this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1405569120&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1405569120&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, &lt;code&gt;m&lt;/code&gt; and &lt;code&gt;n&lt;/code&gt; are separately assigned to integer objects having value &lt;code&gt;30&lt;/code&gt;.  But in this case, &lt;code&gt;id(m)&lt;/code&gt; and &lt;code&gt;id(n)&lt;/code&gt; are identical!&lt;/p&gt;
&lt;p&gt;For purposes of optimization, the interpreter creates objects for the integers in the range &lt;code&gt;[-5, 256]&lt;/code&gt; at startup, and then reuses them during program execution.  Thus, when you assign separate variables to an integer value in this range, they will actually reference the same object.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;variable-names&quot;&gt;Variable Names&lt;/h2&gt;
&lt;p&gt;The examples you have seen so far have used short, terse variable names like &lt;code&gt;m&lt;/code&gt; and &lt;code&gt;n&lt;/code&gt;.  But variable names can be more verbose.  In fact, it is usually beneficial if they are because it makes the purpose of the variable more evident at first glance.&lt;/p&gt;
&lt;p&gt;Officially, variable names in Python can be any length and can consist of uppercase and lowercase letters (&lt;code&gt;A-Z&lt;/code&gt;, &lt;code&gt;a-z&lt;/code&gt;), digits (&lt;code&gt;0-9&lt;/code&gt;), and the underscore character (&lt;code&gt;_&lt;/code&gt;).  An additional restriction is that, although a variable name can contain digits, the first character of a variable name cannot be a digit.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; One of the additions to Python 3 was full Unicode support, which allows for Unicode characters in a variable name as well.  You will learn  about Unicode in greater depth in a future tutorial.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;For example, all of the following are valid variable names:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Bob&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;54&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;has_W2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;has_W2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Bob 54 True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But this one is not, because a variable name can&amp;rsquo;t begin with a digit:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1099&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_filed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;SyntaxError: invalid token&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that case is significant. Lowercase and uppercase letters are not the same.  Use of the underscore character is significant as well.  Each of the following defines a different variable:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aGe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AGE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a_g_e&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_age&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_AGE_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aGe&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AGE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a_g_e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_age&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;age_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_AGE_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1 2 3 4 5 6 7 8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There is nothing stopping you from creating two different variables in the same program called &lt;code&gt;age&lt;/code&gt; and &lt;code&gt;Age&lt;/code&gt;, or for that matter &lt;code&gt;agE&lt;/code&gt;.  But it is probably ill-advised.  It would certainly be likely to confuse anyone trying to read your code, and even you yourself, after you&amp;rsquo;d been away from it awhile.&lt;/p&gt;
&lt;p&gt;It is worthwhile to give a variable a name that is descriptive enough to make clear what it is being used for.  For example, suppose you are tallying the number of people who have graduated college.  You could conceivably choose any of the following:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numberofcollegegraduates&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2500&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NUMBEROFCOLLEGEGRADUATES&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2500&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numberOfCollegeGraduates&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2500&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NumberOfCollegeGraduates&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2500&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number_of_college_graduates&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2500&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numberofcollegegraduates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NUMBEROFCOLLEGEGRADUATES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numberOfCollegeGraduates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NumberOfCollegeGraduates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;number_of_college_graduates&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2500 2500 2500 2500 2500&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;All of them are probably better choices than &lt;code&gt;n&lt;/code&gt;, or &lt;code&gt;ncg&lt;/code&gt;, or the like.  At least you can tell from the name what the value of the variable is supposed to represent.&lt;/p&gt;
&lt;p&gt;On the other hand, they aren&amp;rsquo;t all necessarily equally legible.  As with many things, it is a matter of personal preference, but most people would find the first two examples, where the letters are all shoved together, to be harder to read, particularly the one in all capital letters.  The most commonly used methods of constructing a multi-word variable name are the last three examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Camel Case:&lt;/strong&gt; Second and subsequent words are capitalized, to make word boundaries easier to see.  (Presumably, it struck someone at some point that the capital letters strewn throughout the variable name vaguely resemble camel humps.)&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;numberOfCollegeGraduates&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pascal Case:&lt;/strong&gt; Identical to Camel Case, except the first word is also capitalized.&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;NumberOfCollegeGraduates&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Snake Case:&lt;/strong&gt; Words are separated by underscores.&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;number_of_college_graduates&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Programmers debate hotly, with surprising fervor, which of these is preferable.  Decent arguments can be made for all of them.  Use whichever of the three is most visually appealing to you. Pick one and use it consistently.&lt;/p&gt;
&lt;p&gt;You will see later that variables aren&amp;rsquo;t the only things that can be given names. You can also name functions, classes, modules, and so on.  The rules that apply to variable names also apply to identifiers, the more general term for names given to program objects.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://www.python.org/dev/peps/pep-0008/&quot;&gt;Style Guide for Python Code&lt;/a&gt;, also known as &lt;strong&gt;PEP 8&lt;/strong&gt;, contains &lt;a href=&quot;https://www.python.org/dev/peps/pep-0008/#naming-conventions&quot;&gt;Naming Conventions&lt;/a&gt; that list suggested standards for names of different object types.  PEP 8 includes the following recommendations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Snake Case should be used for functions and variable names.&lt;/li&gt;
&lt;li&gt;Pascal Case should be used for class names.  (PEP 8 refers to this as the &amp;ldquo;CapWords&amp;rdquo; convention.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;reserved-words-keywords&quot;&gt;Reserved Words (Keywords)&lt;/h2&gt;
&lt;p&gt;There is one more restriction on identifier names.  The Python language reserves a small set of keywords that designate special language functionality.  No object can have the same name as a reserved word.&lt;/p&gt;
&lt;p&gt;In Python 3.6, there are 33 reserved keywords:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Python&lt;br&gt;Keywords&lt;/th&gt;
&lt;th&gt;&amp;nbsp;&lt;/th&gt;
&lt;th&gt;&amp;nbsp;&lt;/th&gt;
&lt;th&gt;&amp;nbsp;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;False&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;def&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;if&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;raise&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;None&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;del&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;import&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;return&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;True&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;elif&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;in&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;try&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;and&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;else&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;is&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;while&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;as&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;except&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lambda&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;with&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;assert&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;finally&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nonlocal&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;yield&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;break&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;for&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;not&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;class&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;from&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;or&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;continue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;global&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pass&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;You can see this list any time by typing &lt;code&gt;help(&quot;keywords&quot;)&lt;/code&gt; to the Python interpreter.  Reserved words are case-sensitive and must be used exactly as shown.  They are all entirely lowercase, except for &lt;code&gt;False&lt;/code&gt;, &lt;code&gt;None&lt;/code&gt;, and &lt;code&gt;True&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Trying to create a variable with the same name as any reserved word results in an error:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;SyntaxError: invalid syntax&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This tutorial covered the basics of Python &lt;strong&gt;variables&lt;/strong&gt;, including object references and identity, and naming of Python identifiers.&lt;/p&gt;
&lt;p&gt;You now have a good understanding of some of Python&amp;rsquo;s data types and know how to create variables that reference objects of those types.&lt;/p&gt;
&lt;p&gt;Next, you will see how to combine data objects into &lt;strong&gt;expressions&lt;/strong&gt; involving various &lt;strong&gt;operations&lt;/strong&gt;.&lt;/p&gt;
&lt;div class=&quot;container py-3 series-nav mb-3&quot;&gt;
  &lt;div class=&quot;row justify-content-between&quot;&gt;
    &lt;div class=&quot;col-12 col-md-3 text-left text-muted ml-1&quot;&gt;&lt;a href=&quot;https://realpython.com/python-data-types/&quot;&gt; «&amp;nbsp;Basic Data Types in Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-center text-muted&quot;&gt;&lt;a href=&quot;#&quot;&gt;Variables in Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-right text-muted mr-1&quot;&gt;&lt;a href=&quot;https://realpython.com/python-operators-expressions/&quot;&gt;Operators and Expressions in Python&amp;nbsp;»&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Building and Documenting Python REST APIs With Flask and Connexion</title>
      <id>https://realpython.com/flask-connexion-rest-api/</id>
      <link href="https://realpython.com/flask-connexion-rest-api/"/>
      <updated>2018-06-11T14:00:00+00:00</updated>
      <summary>How to create a Python-powered RESTful API from scratch using Flask and the Connexion library. Also covers automated validation and documentation for your API endpoints using the Swagger / OpenAPI standard.</summary>
      <content type="html">
        &lt;p&gt;If you&amp;rsquo;re writing a web application, then you&amp;rsquo;re probably thinking about making HTTP calls to your server to get data to populate the dynamic parts of your application.&lt;/p&gt;
&lt;p&gt;The goal of this article is to show you how to use Python 3, &lt;a href=&quot;https://realpython.com/tutorials/flask/&quot;&gt;Flask&lt;/a&gt;, and &lt;a href=&quot;https://github.com/zalando/connexion&quot;&gt;Connexion&lt;/a&gt; to build useful REST APIs that can include input and output validation, and provide &lt;a href=&quot;https://swagger.io/&quot;&gt;Swagger&lt;/a&gt; documentation as a bonus. Also included is a simple but useful single page web application that demonstrates using the API with JavaScript and updating the DOM with it.&lt;/p&gt;
&lt;p&gt;The REST API you&amp;rsquo;ll be building will serve a simple people data structure where the people are keyed to the last name, and any updates are marked with a new timestamp.&lt;/p&gt;
&lt;p&gt;This data could be represented in a database, saved in a file, or be accessible through some network protocol, but for us an in-memory data structure works fine. One of the purposes of an API is to decouple the data from the application that uses it, hiding the data implementation details.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-rest-api-guide&quot; data-focus=&quot;false&quot;&gt;Click here to download a copy of the &quot;REST in a Nutshell&quot; Guide&lt;/a&gt; with a hands-on introduction to REST API principles and examples.&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;what-rest-is&quot;&gt;What REST Is&lt;/h2&gt;
&lt;p&gt;Before you get started creating an API server, I want to talk about REST a little bit. There&amp;rsquo;s lots of information about REST available through some quick Google searches, and my intent is not to duplicate that here.&lt;/p&gt;
&lt;p&gt;I just want to share how I view REST and use it to build APIs. I see REST as a set of conventions taking advantage of the HTTP protocol to provide CRUD (Create, Read, Update, and Delete) behavior on things and collections of those things. The CRUD behavior maps nicely to the HTTP protocol method verbs like this:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;HTTP Verb&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POST&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a new, unique thing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read the information about a thing or collection of things&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PUT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Update the information about an existing thing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DELETE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete a thing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;You can perform these actions on a thing or resource. It&amp;rsquo;s useful to think about a resource as something a noun can be applied to: a person, an order for something, a person&amp;rsquo;s address. This idea of a resource lines up nicely with a URL (Unique Resource Locator).&lt;/p&gt;
&lt;p&gt;A URL should identify a unique resource on the web, something that will work with the same thing over and over again for the same URL. With these two ideas, we have a way to take common application actions on something uniquely identified on the web. This is a very useful way of working.&lt;/p&gt;
&lt;p&gt;This idea goes a long way towards creating clean APIs and performing the actions many applications want from the API. &lt;/p&gt;
&lt;h2 id=&quot;what-rest-is-not&quot;&gt;What REST Is Not&lt;/h2&gt;
&lt;p&gt;Because REST is useful and helps map out how we might want to &lt;a href=&quot;https://realpython.com/api-integration-in-python/&quot;&gt;interact with a web based API&lt;/a&gt;, it&amp;rsquo;s sometimes used for things that don&amp;rsquo;t really fit well. There are lots of cases where what we want to do is perform some work or take an action directly. An example might be performing a string substitution, which granted is a silly thing to make an API for, but let&amp;rsquo;s go with it for now. Here&amp;rsquo;s a URL that might be constructed to provide this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;/api/substituteString/&amp;lt;string&amp;gt;/&amp;lt;search_string&amp;gt;/&amp;lt;sub_string&amp;gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here, &lt;code&gt;string&lt;/code&gt; is the string to make the substitution in, &lt;code&gt;search_string&lt;/code&gt; is the string to replace, and &lt;code&gt;sub_string&lt;/code&gt; is the string to replace &lt;code&gt;search_string&lt;/code&gt; with. This can certainly be tied to some code in the server that does the intended work. But this has some problems in REST terms.&lt;/p&gt;
&lt;p&gt;One problem that comes to mind is that this URL doesn&amp;rsquo;t point to a unique resource, so what it returns is entirely dependent on the path variable sections. Also, there is no concept of CRUD against this URL. It really only needs one HTTP method, and the method name conveys nothing about the action to take.&lt;/p&gt;
&lt;p&gt;As an API, it&amp;rsquo;s not great either. The meaning of the path variables is dependent on their position in the URL. This could be addressed by changing the URL to use a query string instead, like this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;/api/substituteString?string=&amp;lt;string&amp;gt;&amp;amp;search_string=&amp;lt;search_string&amp;gt;&amp;amp;sub_string=&amp;lt;sub_string&amp;gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But the URL portion &lt;code&gt;/api/substituteString&lt;/code&gt; isn&amp;rsquo;t a thing (noun) or collection of things at all: it&amp;rsquo;s an action (verb).&lt;/p&gt;
&lt;p&gt;This doesn&amp;rsquo;t fit well in the REST conventions, and trying to force it to do so makes for a poor API. What the above really represents is an RPC, or Remote Procedure Call. Thinking about this as an RPC makes much more sense.&lt;/p&gt;
&lt;p&gt;The beauty is that both REST and RPC conventions can coexist in an API without any problems! By keeping in mind the intention of each, you can use both to compliment each other in your API design. There are many situations where it would be useful to perform CRUD operations on something. There are also many situations where it would be useful to take an action with a thing (as a parameter) but not necessarily affect the thing itself.&lt;/p&gt;
&lt;h2 id=&quot;the-people-rest-api&quot;&gt;The People REST API&lt;/h2&gt;
&lt;p&gt;For our example program, you&amp;rsquo;re going to create a REST API providing access to a collection of people with CRUD access to an individual person within that collection. Here&amp;rsquo;s the API design for the people collection:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;HTTP Verb&lt;/th&gt;
&lt;th&gt;URL Path&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POST&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/api/people&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines a unique URL to create a new person&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/api/people&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines a unique URL to read a collection of people&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Read&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/api/people/Farrell&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines a unique URL to read a particular person in the people collection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PUT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/api/people/Farrell&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines a unique URL to update an existing order&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DELETE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/api/orders/Farrell&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines a unique URL to delete an existing person&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;First, you&amp;rsquo;ll create a simple web server using the Flask Micro Framework. To get started, create a directory where you can create the code. You should also work in a &lt;a href=&quot;https://realpython.com/python-virtual-environments-a-primer/&quot;&gt;virtualenv&lt;/a&gt; so you can install modules later on, which you&amp;rsquo;ll need to do. In addition, create a templates directory. &lt;/p&gt;
&lt;p&gt;The Python code below gets a very basic web server up and running, and responding with &lt;code&gt;Hello World&lt;/code&gt; for a request for the home page: &lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flask&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;render_template&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Create the application instance&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Flask&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;template_folder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;templates&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Create a URL route in our application for &amp;quot;/&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;home&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    This function just responds to the browser ULR&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    localhost:5000/&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    :return:        the rendered template &amp;#39;home.html&amp;#39;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;render_template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;home.html&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# If we&amp;#39;re running in stand alone mode, run the application&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You should also create a &lt;code&gt;home.html&lt;/code&gt; in the templates folder, as this is what will be served to a browser when navigating to the URL &lt;code&gt;&#39;/&#39;&lt;/code&gt;. Here is the contents of the &lt;code&gt;home.html&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;highlight html&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;en&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;UTF-8&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;Application Home Page&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;h2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        Hello World!
    &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;h2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You&amp;rsquo;ll notice the HTML file is named &lt;code&gt;home.html&lt;/code&gt; rather than &lt;code&gt;index.html&lt;/code&gt;. This is intentional because having an &lt;code&gt;index.html&lt;/code&gt; file in the templates directory causes problems once you import the Connexion module in your program.&lt;/p&gt;
&lt;p&gt;You can run your application with this command line in the directory containing the &lt;code&gt;server.py&lt;/code&gt; file with the Python VirtualEnv active:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;python server.py&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you run this application, a web server will start on port 5000, which is the default port used by Flask. If you open a browser and navigate to &lt;code&gt;localhost:5000&lt;/code&gt;, you should see &lt;code&gt;Hello World!&lt;/code&gt; displayed. Right now, this is useful to see the web server is running. You&amp;rsquo;ll extend the &lt;code&gt;home.html&lt;/code&gt; file later to become a full single page web application using the REST API you&amp;rsquo;re developing.&lt;/p&gt;
&lt;p&gt;In your Python program, you&amp;rsquo;ve imported the Flask module, giving the application access to the Flask functionality. You then created a Flask application instance, the &lt;code&gt;app&lt;/code&gt; variable. Next, you connected the URL route &lt;code&gt;&#39;/&#39;&lt;/code&gt; to the &lt;code&gt;home()&lt;/code&gt; function by &lt;a href=&quot;https://realpython.com/primer-on-python-decorators/&quot;&gt;decorating&lt;/a&gt; it with &lt;code&gt;@app.route(&#39;/&#39;)&lt;/code&gt;. This function calls the Flask &lt;code&gt;render_template()&lt;/code&gt; function to get the &lt;code&gt;home.html&lt;/code&gt; file from the templates directory and return it to the browser.&lt;/p&gt;
&lt;p&gt;All of the example code is available from a link provided at the &lt;a href=&quot;#example-code&quot;&gt;end of this article&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;using-connexion-to-add-a-rest-api-endpoint&quot;&gt;Using Connexion to Add a REST API Endpoint&lt;/h2&gt;
&lt;p&gt;Now that you&amp;rsquo;ve got a working web server, let&amp;rsquo;s add a REST API endpoint. To do this, you&amp;rsquo;ll use the &lt;a href=&quot;https://github.com/zalando/connexion&quot;&gt;Connexion&lt;/a&gt; module, which is installed using pip:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; pip install connexion
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This makes the Connexion module available to your program. The Connexion module allows a Python program to use the &lt;a href=&quot;https://swagger.io/&quot;&gt;Swagger&lt;/a&gt; specification. This provides a lot of functionality: validation of input and output data to and from your API, an easy way to configure the API URL endpoints and the parameters expected, and a really nice UI interface to work with the created API and explore it.&lt;/p&gt;
&lt;p&gt;All of this can happen when you create a configuration file your application can access. The &lt;a href=&quot;https://swagger.io/&quot;&gt;Swagger&lt;/a&gt; site even provides an online configuration editor tool to help create and/or syntax check the configuration file you will create.&lt;/p&gt;
&lt;h2 id=&quot;adding-connexion-to-the-server&quot;&gt;Adding Connexion to the Server&lt;/h2&gt;
&lt;p&gt;There are two parts to adding a REST API URL endpoint to your application with Connexion. You&amp;rsquo;ll add Connexion to the server and create a configuration file it will use. Modify your Python program like this to add Connexion to the server:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;flask&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;render_template&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;connexion&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Create the application instance&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;connexion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;specification_dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;./&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Read the swagger.yml file to configure the endpoints&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_api&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;swagger.yml&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Create a URL route in our application for &amp;quot;/&amp;quot;&lt;/span&gt;
&lt;span class=&quot;nd&quot;&gt;@app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;route&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;home&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    This function just responds to the browser ULR&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    localhost:5000/&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    :return:        the rendered template &amp;#39;home.html&amp;#39;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;render_template&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;home.html&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# If we&amp;#39;re running in stand alone mode, run the application&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;0.0.0.0&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You&amp;rsquo;ve added a couple of things to incorporate Connexion into the server. The &lt;code&gt;import connexion&lt;/code&gt; statement adds the module to the program. The next step is creating the application instance using Connexion rather than Flask. Internally, the Flask app is still created, but it now has additional functionality added to it.&lt;/p&gt;
&lt;p&gt;Part of the app instance creation includes the parameter &lt;code&gt;specification_dir&lt;/code&gt;. This informs Connexion what directory to look in for its configuration file, in this case our current directory. Right after this, you&amp;rsquo;ve added the line:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;app.add_api(&#39;swagger.yml&#39;)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This tells the app instance to read the file &lt;code&gt;swagger.yml&lt;/code&gt; from the specification directory and configure the system to provide the Connexion functionality.&lt;/p&gt;
&lt;h3 id=&quot;the-swagger-configuration-file&quot;&gt;The Swagger Configuration File&lt;/h3&gt;
&lt;p&gt;The file &lt;code&gt;swagger.yml&lt;/code&gt; is a YAML or JSON file containing all of the information necessary to configure your server to provide input parameter validation, output response data validation, URL endpoint definition, and the Swagger UI. Here is the &lt;code&gt;swagger.yml&lt;/code&gt; file defining the &lt;code&gt;GET /api/people&lt;/code&gt; endpoint your REST API will provide:&lt;/p&gt;
&lt;div class=&quot;highlight yaml&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;swagger&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;2.0&amp;quot;&lt;/span&gt;
&lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;This is the swagger file that goes with our server code&lt;/span&gt;
  &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;1.0.0&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;Swagger REST Article&lt;/span&gt;
&lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;consumes&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;p p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;application/json&amp;quot;&lt;/span&gt;
&lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;produces&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;p p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;application/json&amp;quot;&lt;/span&gt;

&lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;basePath&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/api&amp;quot;&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Paths supported by the server application&lt;/span&gt;
&lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;/people&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;operationId&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;people.read&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;p p-Indicator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;People&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;summary&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;The&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;people&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;structure&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;supported&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;by&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;the&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;application&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Read&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;the&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;people&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;responses&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;Successful&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;people&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;operation&amp;quot;&lt;/span&gt;
          &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;schema&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;array&amp;quot;&lt;/span&gt;
            &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
              &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;fname&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
                  &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;string&amp;quot;&lt;/span&gt;
                &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;lname&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
                  &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;string&amp;quot;&lt;/span&gt;
                &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt;
                  &lt;span class=&quot;l l-Scalar l-Scalar-Plain&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p p-Indicator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;string&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This file is organized in a hierarchical manner: the indentation levels represent a level of ownership, or scope. &lt;/p&gt;
&lt;p&gt;For example, &lt;code&gt;paths&lt;/code&gt; defines the beginning of where all the API URL endpoints are defined. The &lt;code&gt;/people&lt;/code&gt; value indented under that defines the start of where all the &lt;code&gt;/api/people&lt;/code&gt; URL endpoints will be defined. The &lt;code&gt;get:&lt;/code&gt; indented under that defines the section of definitions associated with an HTTP GET request to the &lt;code&gt;/api/people&lt;/code&gt; URL endpoint. This goes on for the entire configuration.&lt;/p&gt;
&lt;p&gt;Here are the meanings of the fields in this section of the &lt;code&gt;swagger.yml&lt;/code&gt; file:&lt;/p&gt;
&lt;p&gt;This section is part of the global configuration information:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;swagger:&lt;/code&gt; tells Connexion what version of the Swagger API is being used&lt;/li&gt;
&lt;li&gt;&lt;code&gt;info:&lt;/code&gt; begins a new &amp;lsquo;scope&amp;rsquo; of information about the API being built&lt;/li&gt;
&lt;li&gt;&lt;code&gt;description:&lt;/code&gt; a user defined description of what the API provides or is about. This is in the Connexion generated UI system&lt;/li&gt;
&lt;li&gt;&lt;code&gt;version:&lt;/code&gt; a user defined version value for the API&lt;/li&gt;
&lt;li&gt;&lt;code&gt;title:&lt;/code&gt; a user defined title included in the Connexion generated UI system&lt;/li&gt;
&lt;li&gt;&lt;code&gt;consumes:&lt;/code&gt; tells Connexion what &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types&quot;&gt;MIME type&lt;/a&gt; is expected by the API.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;produces:&lt;/code&gt; tells Connexion what content type is expected by the caller of the API.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;basePath: &quot;/api&quot;&lt;/code&gt; defines the root of the API, kind of like a namespace the REST API will come from. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This section begins the configuration of the API URL endpoint paths:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;paths:&lt;/code&gt; defines the section of the configuration containing all of the API REST endpoints. &lt;/li&gt;
&lt;li&gt;&lt;code&gt;/people:&lt;/code&gt; defines one path of your URL endpoint.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get:&lt;/code&gt; defines the HTTP method this URL endpoint will respond to. Together with the previous definitions, this creates the &lt;code&gt;GET /api/people&lt;/code&gt; URL endpoint.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This section begins the configuration of the single &lt;code&gt;/api/people&lt;/code&gt; URL endpoint:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;operationId: &quot;people.read&quot;&lt;/code&gt; defines the Python import path/function that will respond to an HTTP &lt;code&gt;GET /api/people&lt;/code&gt; request. The &lt;code&gt;&quot;people.read&quot;&lt;/code&gt; portion can go as deep as you need to in order to connect a function to the HTTP request. Something like &lt;code&gt;&quot;&amp;lt;package_name&amp;gt;.&amp;lt;package_name&amp;gt;.&amp;lt;package_name&amp;gt;.&amp;lt;function_name&amp;gt;&quot;&lt;/code&gt; would work just as well. You&amp;rsquo;ll create this shortly.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tags:&lt;/code&gt; defines a grouping for the UI interface. All the CRUD methods you&amp;rsquo;ll define for the people endpoint will share this tag definition.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;summary&lt;/code&gt; defines the UI interface display text for this endpoint.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;description:&lt;/code&gt; defines what the UI interface will display for implementation notes.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This section defines the section of the configuration of a successful response from the URL endpoint:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;response:&lt;/code&gt; defines the beginning of the expected response section.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;200:&lt;/code&gt; defines the section for a successful response, HTTP status code 200.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;description:&lt;/code&gt; defines the UI interface display text for a response of 200.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;schema:&lt;/code&gt; defines the response as a schema, or structure.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;type:&lt;/code&gt; defines the structure of the schema as an array.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;items:&lt;/code&gt; starts the definition of the items in the array.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;properties:&lt;/code&gt; defines the items in the array as objects having key/value pairs.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fname:&lt;/code&gt; defines the first key of the object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;type:&lt;/code&gt; defines the value associated with &lt;code&gt;fname&lt;/code&gt; as a string.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lname:&lt;/code&gt; defines the second key of the object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;type:&lt;/code&gt; defines the value associated with &lt;code&gt;lname&lt;/code&gt; as a string.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;timestamp:&lt;/code&gt; defines the third key of the object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;type:&lt;/code&gt; defines the value associated with &lt;code&gt;timestamp&lt;/code&gt; as a string.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;handler-for-people-endpoint&quot;&gt;Handler for People Endpoint&lt;/h2&gt;
&lt;p&gt;In the &lt;code&gt;swagger.yml&lt;/code&gt; file, you configured Connexion with the &lt;code&gt;operationId&lt;/code&gt; value to call the &lt;code&gt;people&lt;/code&gt; module and the &lt;code&gt;read&lt;/code&gt; function within the module when the API gets an HTTP request for &lt;code&gt;GET /api/people&lt;/code&gt;. This means a &lt;code&gt;people.py&lt;/code&gt; module must exist and contain a &lt;code&gt;read()&lt;/code&gt; function. Here is the &lt;code&gt;people.py&lt;/code&gt; module you will create:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_timestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strftime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;%Y-%m-&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; %H:%M:%S&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Data to serve with our API&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;PEOPLE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;Farrell&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;fname&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Doug&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;lname&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Farrell&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;timestamp&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_timestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;Brockman&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;fname&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Kent&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;lname&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Brockman&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;timestamp&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_timestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;Easter&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;fname&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Bunny&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;lname&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Easter&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&amp;quot;timestamp&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_timestamp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Create a handler for our read (GET) people&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    This function responds to a request for /api/people&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    with the complete lists of people&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    :return:        sorted list of people&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Create the list of people from our data&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PEOPLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PEOPLE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this code, you&amp;rsquo;ve created a helper function called &lt;code&gt;get_timestamp()&lt;/code&gt; that generates a string representation of the current timestamp. This is used to create your in-memory structure and modify the data when you start modifying it with the API.&lt;/p&gt;
&lt;p&gt;You then created the &lt;code&gt;PEOPLE&lt;/code&gt; dictionary data structure, which is a simple names database, keyed on the last name. This is a module variable, so its state persists between REST API calls. In a real application, the &lt;code&gt;PEOPLE&lt;/code&gt; data would exist in a database, file, or network resource, something that persists the data beyond running/stopping the web application.&lt;/p&gt;
&lt;p&gt;Then you created the &lt;code&gt;read()&lt;/code&gt; function. This is called when an HTTP request to &lt;code&gt;GET /api/people&lt;/code&gt; is received by the server. The return value of this function is converted to a &lt;a href=&quot;https://realpython.com/python-json/&quot;&gt;JSON&lt;/a&gt; string (recall the &lt;code&gt;produces:&lt;/code&gt; definition in the &lt;code&gt;swagger.yml&lt;/code&gt; file). The &lt;code&gt;read()&lt;/code&gt; function you created builds and returns a list of people sorted by last name.&lt;/p&gt;
&lt;p&gt;Running your server code and navigating in a browser to &lt;code&gt;localhost:5000/api/people&lt;/code&gt; will display the list of people on screen:&lt;/p&gt;
&lt;div class=&quot;highlight javascript&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;fname&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Kent&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;lname&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Brockman&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;timestamp&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;2018-05-10 18:12:42&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;fname&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Bunny&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;lname&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Easter&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;timestamp&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;2018-05-10 18:12:42&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;fname&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Doug&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;lname&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Farrell&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&amp;quot;timestamp&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;2018-05-10 18:12:42&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Congratulations, you&amp;rsquo;ve created a nice API and are on your way to building out a complete one!&lt;/p&gt;
&lt;h3 id=&quot;the-swagger-ui&quot;&gt;The Swagger UI&lt;/h3&gt;
&lt;p&gt;Now you have a simple web API running with a single URL endpoint. At this point, it would be reasonable to think, &amp;ldquo;configuring this with the &lt;code&gt;swagger.yml&lt;/code&gt; file was cool and all, but what did it get me?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;d be right to think that. We haven&amp;rsquo;t taken advantage of the input or output validation. All that &lt;code&gt;swagger.yml&lt;/code&gt; gave us was a definition for the code path connected to the URL endpoint. However, what you also get for the extra work is the creation of the Swagger UI for your API. &lt;/p&gt;
&lt;p&gt;If you navigate to &lt;code&gt;localhost:5000/api/ui&lt;/code&gt;, the system will bring up a page that looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/swagger_ui_initial.3bd1145882f8.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/swagger_ui_initial.3bd1145882f8.png&quot; width=&quot;995&quot; height=&quot;325&quot; alt=&quot;Swagger UI Interface&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is the initial Swagger interface and shows the list of URL endpoints supported at our &lt;code&gt;localhost:5000/api&lt;/code&gt; endpoint. This is built automatically by Connexion when it parses the &lt;code&gt;swagger.yml&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;If you click on the &lt;code&gt;/people&lt;/code&gt; endpoint in the interface, the interface will expand to show a great deal more information about your API and should look something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/swagger_ui_expanded_1.751b4216ef04.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/swagger_ui_expanded_1.751b4216ef04.png&quot; width=&quot;990&quot; height=&quot;740&quot; alt=&quot;Swagger UI Interface expanded 1&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This displays the structure of the expected response, the &lt;code&gt;content-type&lt;/code&gt; of that response, and the description text you entered about the endpoint in the &lt;code&gt;swagger.yml&lt;/code&gt; file. &lt;/p&gt;
&lt;p&gt;You can even try the endpoint out by clicking the &lt;code&gt;Try It Out!&lt;/code&gt; button at the bottom of the screen. That will further expand the interface to look something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/swagger_ui_expanded_2.1426ae4a6012.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/swagger_ui_expanded_2.1426ae4a6012.png&quot; width=&quot;979&quot; height=&quot;1264&quot; alt=&quot;Swagger UI Interface expanded 2&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This can be extremely useful when the API is complete as it gives you and your API users a way to explore and experiment with the API without having to write any code to do so.&lt;/p&gt;
&lt;p&gt;Building an API this way is very useful to me at work. Not only is the Swagger UI useful as a way to experiment with the API and read the provided documentation, but it&amp;rsquo;s also dynamic. Any time the configuration file changes, the Swagger UI changes as well. &lt;/p&gt;
&lt;p&gt;In addition, the configuration offers a nice, clean way to think about and create the API URL endpoints. I know from experience that APIs can develop in a sometimes random manner over time, making finding the code that supports the endpoints, and coordinating them, difficult at best.&lt;/p&gt;
&lt;p&gt;By separating the code from the API URL endpoint configuration, we decouple one from the other. This alone has been very useful to me in my work building API systems supporting single page web applications.&lt;/p&gt;
&lt;h2 id=&quot;building-out-the-complete-api&quot;&gt;Building Out the Complete API&lt;/h2&gt;
&lt;p&gt;Our original goal was to build out an API providing full CRUD access to our people structure. As you recall, the definition of our API looks like this:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;Action&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;HTTP Verb&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;URL Path&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Create&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code&gt;POST&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code&gt;/api/people&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Defines a unique URL to create a new person&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Read&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code&gt;GET&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code&gt;/api/people&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Defines a unique URL to read a collection of people&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Read&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code&gt;GET&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code&gt;/api/people/Farrell&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Defines a unique URL to read a particular person in the people collection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Update&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code&gt;PUT&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code&gt;/api/people/Farrell&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Defines a unique URL to update an existing order&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Delete&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code&gt;DELETE&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code&gt;/api/orders/Farrell&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Defines a unique URL to delete an existing person&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;To achieve this, you&amp;rsquo;ll extend both the &lt;code&gt;swagger.yml&lt;/code&gt; and &lt;code&gt;people.py&lt;/code&gt; files to fully support the API defined above. For the sake of brevity, only a link will be provided for both files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/realpython/materials/blob/master/flask-connexion-rest/version_3/swagger.yml&quot;&gt;&lt;code&gt;swagger.yml&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/realpython/materials/blob/master/flask-connexion-rest/version_3/people.py&quot;&gt;&lt;code&gt;people.py&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;the-swagger-ui-completed&quot;&gt;The Swagger UI Completed&lt;/h3&gt;
&lt;p&gt;Once you&amp;rsquo;ve updated the &lt;code&gt;swagger.yml&lt;/code&gt; and &lt;code&gt;people.py&lt;/code&gt; files to complete the people API functionality, the Swagger UI system will update accordingly and look something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/swagger_ui_complete.a61f81c9fe3d.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/swagger_ui_complete.a61f81c9fe3d.png&quot; width=&quot;979&quot; height=&quot;479&quot; alt=&quot;Swagger UI Interface complete&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This UI allows you to see all of the documentation you&amp;rsquo;ve included in the &lt;code&gt;swagger.yml&lt;/code&gt; file and interact with all of the URL endpoints making up the CRUD functionality of the people interface. &lt;/p&gt;
&lt;h2 id=&quot;demonstration-single-page-application&quot;&gt;Demonstration Single-Page Application&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;ve got a working REST API with a great Swagger UI documentation/interaction system. But what do you do with it now? The next step is to create a web application demonstrating the use of the API in a semi-practical manner.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll create a web application that displays the people on screen as well as allows the user to create new people, update existing people, and delete people. This will all be handled by AJAX calls from JavaScript to the people API URL endpoints.&lt;/p&gt;
&lt;p&gt;To begin, you need to extend the &lt;code&gt;home.html&lt;/code&gt; file to look like this:&lt;/p&gt;
&lt;div class=&quot;highlight html&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;en&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;UTF-8&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;Application Home Page&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;static/css/home.css&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;script&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;http://code.jquery.com/jquery-3.3.1.min.js&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;integrity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;crossorigin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;anonymous&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;container&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;h1&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;banner&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;People Demo Application&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;h1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;section editor&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;fname&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;First Name
                &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;fname&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;label&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;lname&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;Last Name
                &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;lname&amp;quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;text&amp;quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;br&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;create&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;Create&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;update&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;Update&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;delete&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;Delete&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;reset&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;Reset&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;button&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;people&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;caption&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;People&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;caption&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;thead&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;th&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;First Name&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;th&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;th&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;Last Name&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;th&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;th&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;Update Time&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;th&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;thead&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;tbody&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;tbody&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;error&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;body&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;script&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;static/js/home.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;html&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The above HTML code extends the &lt;code&gt;home.html&lt;/code&gt; file to pull in the external &lt;a href=&quot;https://necolas.github.io/normalize.css/&quot;&gt;&lt;code&gt;normalize.min.css&lt;/code&gt;&lt;/a&gt; file, which is a CSS reset file to normalize the formatting of elements across browsers.&lt;/p&gt;
&lt;p&gt;It also pulls in the external &lt;a href=&quot;https://jquery.com/&quot;&gt;&lt;code&gt;jquery-3.3.1.min.js&lt;/code&gt;&lt;/a&gt; file to provide the jQuery functionality you&amp;rsquo;ll use to create the single-page application interactivity.&lt;/p&gt;
&lt;p&gt;The HTML code above creates the static framework of the application. The dynamic parts appearing in the table structure will be added by JavaScript at load time and as the user interacts with the application.&lt;/p&gt;
&lt;h3 id=&quot;static-files&quot;&gt;Static Files&lt;/h3&gt;
&lt;p&gt;In the &lt;code&gt;home.html&lt;/code&gt; file you&amp;rsquo;ve created, there are references to two static files: &lt;code&gt;static/css/home.css&lt;/code&gt; and &lt;code&gt;static/js/home.js&lt;/code&gt;. To add these, you&amp;rsquo;ll need to add the following directory structure to the application:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;static/
│
├── css/
│   └── home.css
│
└── js/
    └── home.js
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Because a directory named &lt;code&gt;static&lt;/code&gt; will automatically be served by the Flask application, any files you place in the &lt;code&gt;css&lt;/code&gt; and &lt;code&gt;js&lt;/code&gt; folders will be available to the &lt;code&gt;home.html&lt;/code&gt; file. For the sake of brevity, here are links to the &lt;code&gt;home.css&lt;/code&gt; and &lt;code&gt;home.js&lt;/code&gt; files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/realpython/materials/blob/master/flask-connexion-rest/version_4/static/css/home.css&quot;&gt;&lt;code&gt;home.css&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/realpython/materials/blob/master/flask-connexion-rest/version_4/static/js/home.js&quot;&gt;&lt;code&gt;home.js&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;javascript-file&quot;&gt;JavaScript File&lt;/h3&gt;
&lt;p&gt;As was mentioned, the JavaScript file provides all the interaction with and updates to the web application. It does this by breaking up the necessary functionality into three parts by using the &lt;a href=&quot;https://realpython.com/the-model-view-controller-mvc-paradigm-summarized-with-legos/&quot;&gt;MVC (Model / View / Controller)&lt;/a&gt; design pattern.&lt;/p&gt;
&lt;p&gt;Each object is created by a &lt;a href=&quot;https://en.wikipedia.org/wiki/Immediately-invoked_function_expression&quot;&gt;self-invoking function&lt;/a&gt; returning its own API for use by the other pieces. For instance, the Controller is passed the instances of the Model and View as parameters in its instantiation. It interacts with those objects through their exposed API methods.&lt;/p&gt;
&lt;p&gt;The only other connection is between the Model and Controller by means of custom events on the AJAX method calls: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The Model&lt;/strong&gt; provides the connection to the people API. Its own API is what the Controller calls to interact with the server when a user interaction event requires it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The View&lt;/strong&gt; provides the mechanism to update the web application DOM. Its own API is what the Controller calls to update the DOM when a user interaction event requires it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Controller&lt;/strong&gt; provides all the event handlers for user interaction with the web application. This allows it to make calls to the Model to make requests to the people API, and to the View to update the DOM with new information received from the people API.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It also handles the custom events generated by the asynchronous AJAX requests made by the Model to the people API.&lt;/p&gt;
&lt;p&gt;Here is a diagram of the MVC structure used in the &lt;code&gt;home.js&lt;/code&gt; file:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/mvc.b7675fb5f043.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/mvc.b7675fb5f043.png&quot; width=&quot;975&quot; height=&quot;750&quot; alt=&quot;JavaScript MVC Diagram&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The idea is that the Controller has a strong link to both the Model and the View. The Model has a weak link (the custom events) to the Controller and no connection to the View at all. The weak link from the Model to the Controller reduces coupling and dependence, which is useful in this case.&lt;/p&gt;
&lt;h3 id=&quot;demo-application&quot;&gt;Demo Application&lt;/h3&gt;
&lt;p&gt;When created, the web application will look like this in the browser:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/connexion_application.2124789635a0.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/connexion_application.2124789635a0.png&quot; width=&quot;731&quot; height=&quot;391&quot; alt=&quot;Connexion Demo Applications&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;Create&lt;/code&gt; button allows the user to create a new person in the people structure on the server. When you enter a First and Last Name and hit &lt;code&gt;Create&lt;/code&gt;, the Controller calls the Model to make a request to the &lt;code&gt;POST /api/people&lt;/code&gt; URL endpoint. This will verify that the last name doesn&amp;rsquo;t already exist. If it doesn&amp;rsquo;t, it will create a new person in the people structure.&lt;/p&gt;
&lt;p&gt;This generates a custom event in the Model that causes the Controller to call the Model again to request a &lt;code&gt;GET /api/people&lt;/code&gt;, which will return the complete list of people sorted. The Controller then passes that onto the View to redraw the table of people.&lt;/p&gt;
&lt;p&gt;Double clicking on any row in the table will populate the First and Last Name fields in the editor section of the application. At this point, the user can either update or delete the person. &lt;/p&gt;
&lt;p&gt;To update successfully, the user must change something about the First Name. The Last Name must remain the same as it&amp;rsquo;s the lookup key for the person to update. When Update is clicked, the Controller calls the Model to make a request to the &lt;code&gt;PUT /api/people/{lname}&lt;/code&gt; URL endpoint. This will verify that the Last Name does currently exist. If so, it will update that person in the people structure.&lt;/p&gt;
&lt;p&gt;This generates a custom event in the Model that causes the Controller to call the Model again to request a &lt;code&gt;GET /api/people&lt;/code&gt;, which will return the complete list of people sorted. The Controller then passes that onto the View to redraw the table of people.&lt;/p&gt;
&lt;p&gt;To delete successfully, the user need only click &lt;code&gt;Delete&lt;/code&gt;. When &lt;code&gt;Delete&lt;/code&gt; is clicked, the Controller calls the Model to make a request to the &lt;code&gt;DELETE /api/people/{lname}&lt;/code&gt; URL endpoint. This will verify that the last name does currently exist. If so, it will delete that person from the people structure.&lt;/p&gt;
&lt;p&gt;This generates a custom event in the Model that causes the Controller to call the Model again to request a &lt;code&gt;GET /api/people&lt;/code&gt;, which will return the complete list of people sorted. The Controller then passes that onto the View to redraw the table of people.&lt;/p&gt;
&lt;p&gt;Try making intentional errors in the editor, like misspelling a Last Name, and see the errors generated by the API represented on the web application.&lt;/p&gt;
&lt;h2 id=&quot;example-code&quot;&gt;Example Code&lt;/h2&gt;
&lt;p&gt;All of the example code for this article is available &lt;a href=&quot;https://github.com/realpython/materials/tree/master/flask-connexion-rest&quot;&gt;here&lt;/a&gt;. There are four versions of the code, each in a &lt;code&gt;version_#&lt;/code&gt; directory, where &lt;code&gt;#&lt;/code&gt; ranges from 1 to 4. The four versions correspond to the article sections in this manner:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;version_1&lt;/code&gt;: This version contains the initial web server that serves up the &lt;code&gt;home.html&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;version_2&lt;/code&gt;: This version contains the web server with Connexion added and the first people API URL endpoint.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;version_3&lt;/code&gt;: This version contains the completed people API with all supported URL endpoints.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;version_4&lt;/code&gt;: This version contains the completed API and a single page web application to demonstrate it.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-rest-api-guide&quot; data-focus=&quot;false&quot;&gt;Click here to download a copy of the &quot;REST in a Nutshell&quot; Guide&lt;/a&gt; with a hands-on introduction to REST API principles and examples.&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this tutorial, you saw how relatively easy it is to create a comprehensive REST API with Python. With the Connexion module and some additional configuration work, a useful documentation and interactive system can be put in place, making your API a much more enjoyable experience for your users to interface with and understand.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Basic Data Types in Python</title>
      <id>https://realpython.com/python-data-types/</id>
      <link href="https://realpython.com/python-data-types/"/>
      <updated>2018-06-05T14:00:00+00:00</updated>
      <summary>Learn the basic data types that are built into Python, like numbers, strings, and Booleans. You&#39;ll also get an overview of Python&#39;s built-in functions.</summary>
      <content type="html">
        &lt;p&gt;Now you know &lt;a href=&quot;https://realpython.com/interacting-with-python/&quot;&gt;how to interact with the Python interpreter and execute Python code&lt;/a&gt;.  It&amp;rsquo;s time to dig into the Python language.  First up is a discussion of the basic data types that are built into Python.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Here&amp;rsquo;s what you&amp;rsquo;ll learn in this tutorial:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You&amp;rsquo;ll learn about several basic &lt;strong&gt;numeric, string&lt;/strong&gt;, and &lt;strong&gt;Boolean&lt;/strong&gt; types that are built into Python.  By the end of this tutorial, you&amp;rsquo;ll be familiar with what objects of these types look like, and how to represent them.&lt;/li&gt;
&lt;li&gt;You&amp;rsquo;ll also get an overview of Python&amp;rsquo;s built-in &lt;strong&gt;functions.&lt;/strong&gt;  These are pre-written chunks of code you can call to do useful things.  You have already seen the built-in &lt;code&gt;print()&lt;/code&gt; function, but there are many others.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free PDF Download:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/optins/view/python-cheat-sheet-short/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-cheat-sheet-short&quot; data-focus=&quot;false&quot;&gt;Python 3 Cheat Sheet&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;integers&quot;&gt;Integers&lt;/h2&gt;
&lt;p&gt;In Python 3, there is effectively no limit to how long an integer value can be.  Of course, it is constrained by the amount of memory your system has, as are all things, but beyond that an integer can be as long as you need it to be:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;123123123123123123123123123123123123123123123123&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;123123123123123123123123123123123123123123123124&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Python interprets a sequence of decimal digits without any prefix to be a decimal number:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;10&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The following strings can be prepended to an integer value to indicate a base other than 10:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Prefix&lt;/th&gt;
&lt;th&gt;Interpretation&lt;/th&gt;
&lt;th&gt;Base&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0b&lt;/code&gt; (zero + lowercase letter &lt;code&gt;&#39;b&#39;&lt;/code&gt;)&lt;br&gt;&lt;code&gt;0B&lt;/code&gt; (zero + uppercase letter &lt;code&gt;&#39;B&#39;&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Binary&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0o&lt;/code&gt; (zero + lowercase letter &lt;code&gt;&#39;o&#39;&lt;/code&gt;)&lt;br&gt;&lt;code&gt;0O&lt;/code&gt; (zero + uppercase letter &lt;code&gt;&#39;O&#39;&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Octal&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;0x&lt;/code&gt; (zero + lowercase letter &lt;code&gt;&#39;x&#39;&lt;/code&gt;)&lt;br&gt;&lt;code&gt;0X&lt;/code&gt; (zero + uppercase letter &lt;code&gt;&#39;X&#39;&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;Hexadecimal&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;8&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;16&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mb&quot;&gt;0b10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For more information on integer values with non-decimal bases, see the following Wikipedia sites: &lt;a href=&quot;https://en.wikipedia.org/wiki/Binary_number&quot;&gt;Binary&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/Octal&quot;&gt;Octal&lt;/a&gt;, and &lt;a href=&quot;https://en.wikipedia.org/wiki/Hexadecimal&quot;&gt;Hexadecimal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The underlying type of a Python integer, irrespective of the base used to specify it, is called &lt;code&gt;int&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;int&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;o10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;int&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;int&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This is a good time to mention that if you want to display a value while in a REPL session, you don&amp;rsquo;t need to use the &lt;code&gt;print()&lt;/code&gt; function.  Just typing the value at the &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; prompt and hitting &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt; will display it:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mh&quot;&gt;0x10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;16&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mb&quot;&gt;0b10&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Many of the examples in this tutorial series will use this feature.&lt;/p&gt;
&lt;p&gt;Note that this does not work inside a script file.  A value appearing on a line by itself in a script file will not do anything.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;floating-point-numbers&quot;&gt;Floating-Point Numbers&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;float&lt;/code&gt; type in Python designates a floating-point number. &lt;code&gt;float&lt;/code&gt; values are specified with a decimal point.  Optionally, the character &lt;code&gt;e&lt;/code&gt; or &lt;code&gt;E&lt;/code&gt; followed by a positive or negative integer may be appended to specify &lt;a href=&quot;https://en.wikipedia.org/wiki/Scientific_notation&quot;&gt;scientific notation&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;4.2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4.2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;4.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;float&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;4.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4.0&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.2&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;4e7&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;4000000.0&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;4e7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;float&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;4.2e-4&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.00042&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p class=&quot;h3&quot;&gt;Deep Dive: Floating-Point Representation&lt;/p&gt;
&lt;p&gt;The following is a bit more in-depth information on how Python represents floating-point numbers internally.  You can readily use floating-point numbers in Python without understanding them to this level, so don&amp;rsquo;t worry if this seems overly complicated.  The information is presented here in case you are curious.&lt;/p&gt;
&lt;p&gt;Almost all platforms represent Python &lt;code&gt;float&lt;/code&gt; values as 64-bit &amp;ldquo;double-precision&amp;rdquo; values, according to the &lt;a href=&quot;https://en.wikipedia.org/wiki/IEEE_754_revision&quot;&gt;IEEE 754&lt;/a&gt; standard.  In that case, the maximum value a floating-point number can have is approximately 1.8 ⨉ 10&lt;sup&gt;308&lt;/sup&gt;.  Python will indicate a number greater than that by the string &lt;code&gt;inf&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.79e308&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1.79e+308&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.8e308&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;inf&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The closest a nonzero number can be to zero is approximately 5.0 ⨉ 10&lt;sup&gt;-324&lt;/sup&gt;.  Anything closer to zero than that is effectively zero:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;5e-324&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;5e-324&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1e-325&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0.0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Floating point numbers are represented internally as binary (base-2) fractions.  Most decimal fractions cannot be represented exactly as binary fractions, so in most cases the internal representation of a floating-point number is an approximation of the actual value.  In practice, the difference between the actual value and the represented value is very small and should not usually cause significant problems.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Further Reading:&lt;/strong&gt; For additional information on floating-point representation in Python and the potential pitfalls involved, see &lt;a href=&quot;https://docs.python.org/3.6/tutorial/floatingpoint.html&quot;&gt;Floating Point Arithmetic: Issues and Limitations&lt;/a&gt; in the Python documentation.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;complex-numbers&quot;&gt;Complex Numbers&lt;/h2&gt;
&lt;p&gt;Complex numbers are specified as &lt;code&gt;&amp;lt;real part&amp;gt;+&amp;lt;imaginary part&amp;gt;j&lt;/code&gt;.  For example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3j&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(2+3j)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;complex&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;strings&quot;&gt;Strings&lt;/h2&gt;
&lt;p&gt;Strings are sequences of character data.  The string type in Python is called &lt;code&gt;str&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;String literals may be delimited using either single or double quotes.  All the characters between the opening delimiter and matching closing delimiter are part of the string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;I am a string.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;I am a string.&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;I am a string.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;str&amp;#39;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;I am too.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;I am too.&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;I am too.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;str&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A string in Python can contain as many characters as you wish. The only limit is your machine&amp;rsquo;s memory resources.  A string can also be empty:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What if you want to include a quote character as part of the string itself?  Your first impulse might be to try something like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;This string contains a single quote (&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;character&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;SyntaxError: invalid syntax&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, that doesn&amp;rsquo;t work so well.  The string in this example opens with a single quote, so Python assumes the next single quote, the one in parentheses which was intended to be part of the string, is the closing delimiter.  The final single quote is then a stray and causes the syntax error shown.&lt;/p&gt;
&lt;p&gt;If you want to include either type of quote character within the string, the simplest way is to delimit the string with the other type.  If a string is to contain a single quote, delimit it with double quotes and vice versa:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;This string contains a single quote (&amp;#39;) character.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;This string contains a single quote (&amp;#39;) character.&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;This string contains a double quote (&amp;quot;) character.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;This string contains a double quote (&amp;quot;) character.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;escape-sequences-in-strings&quot;&gt;Escape Sequences in Strings&lt;/h3&gt;
&lt;p&gt;Sometimes, you want Python to interpret a character or sequence of characters within a string differently. This may occur in one of two ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You may want to suppress the special interpretation that certain characters are usually given within a string.&lt;/li&gt;
&lt;li&gt;You may want to apply special interpretation to characters in a string which would normally be taken literally.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can accomplish this using a backslash (&lt;code&gt;\&lt;/code&gt;) character.  A backslash character in a string indicates that one or more characters that follow it should be treated specially.  (This is referred to as an escape sequence, because the backslash causes the subsequent character sequence to &amp;ldquo;escape&amp;rdquo; its usual meaning.)&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see how this works.&lt;/p&gt;
&lt;h4 id=&quot;suppressing-special-character-meaning&quot;&gt;Suppressing Special Character Meaning&lt;/h4&gt;
&lt;p&gt;You have already seen the problems you can come up against when you try to include quote characters in a string.  If a string is delimited by single quotes, you can&amp;rsquo;t directly specify a single quote character as part of the string because, for that string, the single quote has special meaning&amp;mdash;it terminates the string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;This string contains a single quote (&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;character&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;SyntaxError: invalid syntax&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Specifying a backslash in front of the quote character in a string &amp;ldquo;escapes&amp;rdquo; it and causes Python to suppress its usual special meaning.  It is then interpreted simply as a literal single quote character:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;This string contains a single quote (&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;#39;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;) character.&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;This string contains a single quote (&amp;#39;) character.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The same works in a string delimited by double quotes as well:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;This string contains a double quote (&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;) character.&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;This string contains a double quote (&amp;quot;) character.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The following is a table of escape sequences which cause Python to suppress the usual special interpretation of a character in a string:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Escape&lt;br&gt;Sequence&lt;/th&gt;
&lt;th&gt;Usual Interpretation of&lt;br&gt;Character(s) After Backslash&lt;/th&gt;
&lt;th&gt;&amp;ldquo;Escaped&amp;rdquo; Interpretation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\&#39;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Terminates string with single quote opening delimiter&lt;/td&gt;
&lt;td&gt;Literal single quote (&lt;code&gt;&#39;&lt;/code&gt;) character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Terminates string with double quote opening delimiter&lt;/td&gt;
&lt;td&gt;Literal double quote (&lt;code&gt;&quot;&lt;/code&gt;) character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\newline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Terminates input line&lt;/td&gt;
&lt;td&gt;Newline is ignored&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\\&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Introduces escape sequence&lt;/td&gt;
&lt;td&gt;Literal backslash (&lt;code&gt;\&lt;/code&gt;) character&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Ordinarily, a newline character terminates line input.  So pressing &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt; in the middle of a string will cause Python to think it is incomplete:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;SyntaxError: EOL while scanning string literal&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To break up a string over more than one line, include a backslash before each newline, and the newlines will be ignored:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;abc&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To include a literal backslash in a string, escape it with a backslash:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foo\bar&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;applying-special-meaning-to-characters&quot;&gt;Applying Special Meaning to Characters&lt;/h4&gt;
&lt;p&gt;Next, suppose you need to create a string that contains a tab character in it.  Some text editors may allow you to insert a tab character directly into your code.  But many programmers consider that poor practice, for several reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The computer can distinguish between a tab character and a sequence of space characters, but you can&amp;rsquo;t.  To a human reading the code, tab and space characters are visually indistinguishable.&lt;/li&gt;
&lt;li&gt;Some text editors are configured to automatically eliminate tab characters by expanding them to the appropriate number of spaces.&lt;/li&gt;
&lt;li&gt;Some Python REPL environments will not insert tabs into code.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In Python (and almost all other common computer languages), a tab character can be specified by the escape sequence &lt;code&gt;\t&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foo     bar&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The escape sequence &lt;code&gt;\t&lt;/code&gt; causes the &lt;code&gt;t&lt;/code&gt; character to lose its usual meaning, that of a literal &lt;code&gt;t&lt;/code&gt;.  Instead, the combination is interpreted as a tab character.&lt;/p&gt;
&lt;p&gt;Here is a list of escape sequences that cause Python to apply special meaning instead of interpreting literally:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Escape Sequence&lt;/th&gt;
&lt;th&gt;&amp;ldquo;Escaped&amp;rdquo; Interpretation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ASCII Bell (&lt;code&gt;BEL&lt;/code&gt;) character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ASCII Backspace (&lt;code&gt;BS&lt;/code&gt;) character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ASCII Formfeed (&lt;code&gt;FF&lt;/code&gt;) character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\n&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ASCII Linefeed (&lt;code&gt;LF&lt;/code&gt;) character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\N{&amp;lt;name&amp;gt;}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Character from Unicode database with given &lt;code&gt;&amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\r&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ASCII Carriage Return (&lt;code&gt;CR&lt;/code&gt;) character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\t&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ASCII Horizontal Tab (&lt;code&gt;TAB&lt;/code&gt;) character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\uxxxx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unicode character with 16-bit hex value &lt;code&gt;xxxx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\Uxxxxxxxx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unicode character with 32-bit hex value &lt;code&gt;xxxxxxxx&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\v&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ASCII Vertical Tab (&lt;code&gt;VT&lt;/code&gt;) character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\ooo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Character with octal value &lt;code&gt;ooo&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;\xhh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Character with hex value &lt;code&gt;hh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;b&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;a    b&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\141\x61&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;aaa&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;a&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;b&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;b&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\u2192&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\N{rightwards arrow}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;→ →&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This type of escape sequence is typically used to insert characters that are not readily generated from the keyboard or are not easily readable or printable.&lt;/p&gt;
&lt;h3 id=&quot;raw-strings&quot;&gt;Raw Strings&lt;/h3&gt;
&lt;p&gt;A raw string literal is preceded by &lt;code&gt;r&lt;/code&gt; or &lt;code&gt;R&lt;/code&gt;, which specifies that escape sequences in the associated string are not translated.  The backslash character is left in the string:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foo&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;bar&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo\nbar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foo\nbar&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foo\bar&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;bar&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;foo\\bar&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;triple-quoted-strings&quot;&gt;Triple-Quoted Strings&lt;/h3&gt;
&lt;p&gt;There is yet another way of delimiting strings in Python.  Triple-quoted strings are delimited by matching groups of three single quotes or three double quotes.  Escape sequences still work in triple-quoted strings, but single quotes, double quotes, and newlines can be included without escaping them.  This provides a convenient way to create a string with both single and double quotes in it:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&amp;#39;&amp;#39;This string has a single (&amp;#39;) and a double (&amp;quot;) quote.&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;This string has a single (&amp;#39;) and a double (&amp;quot;) quote.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Because newlines can be included without escaping them, this also allows for multiline strings:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&amp;quot;&amp;quot;This is a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;string that spans&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;across several lines&amp;quot;&amp;quot;&amp;quot;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;This is a&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;string that spans&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;across several lines&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You will see in the upcoming tutorial on Python Program Structure how triple-quoted strings can be used to add an explanatory comment to Python code.&lt;/p&gt;
&lt;h2 id=&quot;boolean-type-boolean-context-and-truthiness&quot;&gt;Boolean Type, Boolean Context, and &amp;ldquo;Truthiness&amp;rdquo;&lt;/h2&gt;
&lt;p&gt;Python 3 provides a Boolean data type.  Objects of Boolean type may have one of two values, &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;bool&amp;#39;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;class &amp;#39;bool&amp;#39;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you will see in upcoming tutorials, expressions in Python are often evaluated in Boolean context, meaning they are interpreted to represent truth or falsehood.  A value that is true in Boolean context is sometimes said to be &amp;ldquo;truthy,&amp;rdquo; and one that is false in Boolean context is said to be &amp;ldquo;falsy.&amp;rdquo;  (You may also see &amp;ldquo;falsy&amp;rdquo; spelled &amp;ldquo;falsey.&amp;rdquo;)&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;truthiness&amp;rdquo; of an object of Boolean type is self-evident:  Boolean objects that are equal to &lt;code&gt;True&lt;/code&gt; are truthy (true), and those equal to &lt;code&gt;False&lt;/code&gt; are falsy (false).  But non-Boolean objects can be evaluated in Boolean context as well and determined to be true or false.&lt;/p&gt;
&lt;p&gt;You will learn more about evaluation of objects in Boolean context when you encounter logical operators in the upcoming tutorial on operators and expressions in Python.&lt;/p&gt;
&lt;h2 id=&quot;built-in-functions&quot;&gt;Built-In Functions&lt;/h2&gt;
&lt;p&gt;The Python interpreter supports many functions that are built-in: sixty-eight, as of Python 3.6.  You will cover many of these in the following discussions, as they come up in context.&lt;/p&gt;
&lt;p&gt;For now, a brief overview follows, just to give a feel for what is available.  See the &lt;a href=&quot;https://docs.python.org/3.6/library/functions.html&quot;&gt;Python documentation on built-in functions&lt;/a&gt; for more detail.   Many of the following descriptions refer to topics and concepts that will be discussed in future tutorials.&lt;/p&gt;
&lt;h3 id=&quot;math&quot;&gt;Math&lt;/h3&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;abs()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns absolute value of a number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;divmod()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns quotient and remainder of integer division&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;max()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the largest of the given arguments or items in an iterable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;min()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the smallest of the given arguments or items in an iterable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pow()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Raises a number to a power&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;round()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rounds a floating-point value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sum()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sums the items of an iterable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h3 id=&quot;type-conversion&quot;&gt;Type Conversion&lt;/h3&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ascii()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a string containing a printable representation of an object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bin()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Converts an integer to a binary string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bool()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Converts an argument to a Boolean value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;chr()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns string representation of character given by integer argument&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;complex()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a complex number constructed from arguments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;float()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a floating-point object constructed from a number or string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hex()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Converts an integer to a hexadecimal string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;int()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns an integer object constructed from a number or string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;oct()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Converts an integer to an octal string&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ord()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns integer representation of a character&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;repr()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a string containing a printable representation of an object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;str()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a string version of an object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;type()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the type of an object or creates a new type object&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h3 id=&quot;iterables-and-iterators&quot;&gt;Iterables and Iterators&lt;/h3&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;all()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns &lt;code&gt;True&lt;/code&gt; if all elements of an iterable are true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;any()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns &lt;code&gt;True&lt;/code&gt; if any elements of an iterable are true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;enumerate()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a list of tuples containing indices and values from an iterable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;filter()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filters elements from an iterable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;iter()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns an iterator object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;len()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the length of an object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;map()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Applies a function to every item of an iterable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;next()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Retrieves the next item from an iterator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;range()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generates a range of integer values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;reversed()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a reverse iterator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;slice()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a &lt;code&gt;slice&lt;/code&gt; object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sorted()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a sorted list from an iterable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;zip()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates an iterator that aggregates elements from iterables&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h3 id=&quot;composite-data-type&quot;&gt;Composite Data Type&lt;/h3&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bytearray()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates and returns an object of the &lt;code&gt;bytearray&lt;/code&gt; class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bytes()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates and returns a &lt;code&gt;bytes&lt;/code&gt; object (similar to &lt;code&gt;bytearray&lt;/code&gt;, but immutable)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dict()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates a &lt;code&gt;dict&lt;/code&gt; object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;frozenset()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates a &lt;code&gt;frozenset&lt;/code&gt; object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;list()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Constructs a &lt;code&gt;list&lt;/code&gt; object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;object()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a new featureless object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;set()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates a &lt;code&gt;set&lt;/code&gt; object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tuple()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates a &lt;code&gt;tuple&lt;/code&gt; object&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h3 id=&quot;classes-attributes-and-inheritance&quot;&gt;Classes, Attributes, and Inheritance&lt;/h3&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;classmethod()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a class method for a function&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;delattr()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Deletes an attribute from an object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;getattr()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the value of a named attribute of an object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hasattr()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns &lt;code&gt;True&lt;/code&gt; if an object has a given attribute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;isinstance()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Determines whether an object is an instance of a given class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;issubclass()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Determines whether a class is a subclass of a given class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;property()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a property value of a class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;setattr()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Sets the value of a named attribute of an object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;super()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a proxy object that delegates method calls to a parent or sibling class&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h3 id=&quot;inputoutput&quot;&gt;Input/Output&lt;/h3&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;format()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Converts a value to a formatted representation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;input()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reads input from the console&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;open()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Opens a file and returns a file object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;print()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Prints to a text stream or the console&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h3 id=&quot;variables-references-and-scope&quot;&gt;Variables, References, and Scope&lt;/h3&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dir()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a list of names in current local scope or a list of object attributes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;globals()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a dictionary representing the current global symbol table&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;id()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the identity of an object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;locals()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Updates and returns a dictionary representing current local symbol table&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vars()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns &lt;code&gt;__dict__&lt;/code&gt; attribute for a module, class, or object&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h3 id=&quot;miscellaneous&quot;&gt;Miscellaneous&lt;/h3&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;callable()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns &lt;code&gt;True&lt;/code&gt; if object appears callable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;compile()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compiles source into a code or AST object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;eval()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Evaluates a Python expression&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;exec()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Implements dynamic execution of Python code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hash()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the hash value of an object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;help()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Invokes the built-in help system&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;memoryview()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a memory view object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;staticmethod()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns a static method for a function&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;__import__()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Invoked by the &lt;code&gt;import&lt;/code&gt; statement&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In this tutorial, you learned about the built-in &lt;strong&gt;data types&lt;/strong&gt; and &lt;strong&gt;functions&lt;/strong&gt; Python provides.&lt;/p&gt;
&lt;p&gt;The examples given so far have all manipulated and displayed only constant values.  In most programs, you are usually going to want to create objects that change in value as the program executes.&lt;/p&gt;
&lt;p&gt;Head to the next tutorial to learn about Python &lt;strong&gt;variables.&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;container py-3 series-nav mb-3&quot;&gt;
  &lt;div class=&quot;row justify-content-between&quot;&gt;
    &lt;div class=&quot;col-12 col-md-3 text-left text-muted ml-1&quot;&gt;&lt;a href=&quot;https://realpython.com/interacting-with-python/&quot;&gt; «&amp;nbsp;Interacting with Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-center text-muted&quot;&gt;&lt;a href=&quot;#&quot;&gt;Basic Data Types in Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-right text-muted mr-1&quot;&gt;&lt;a href=&quot;https://realpython.com/python-variables/&quot;&gt;Variables in Python&amp;nbsp;»&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python Application Layouts: A Reference</title>
      <id>https://realpython.com/python-application-layouts/</id>
      <link href="https://realpython.com/python-application-layouts/"/>
      <updated>2018-06-04T14:00:00+00:00</updated>
      <summary>A reference guide to common Python application layouts and project structures for command-line applications, web applications, and more.</summary>
      <content type="html">
        &lt;p&gt;Python, though opinionated on syntax and style, is surprisingly flexible when it comes to structuring your applications.&lt;/p&gt;
&lt;p&gt;On the one hand, this flexibility is great: it allows different use cases to use structures that are necessary for those use cases. On the other hand, though, it can be very confusing to the new developer. &lt;/p&gt;
&lt;p&gt;The Internet isn&amp;rsquo;t a lot of help either&amp;mdash;there are as many opinions as there are Python blogs. &lt;strong&gt;In this article, I want to give you a dependable Python application layout reference guide that you can refer to for the vast majority of your use cases&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll see examples of common Python application structures, including command-line applications (CLI apps), one-off scripts, installable packages, and web application layouts with popular frameworks like &lt;a href=&quot;https://realpython.com/tutorials/flask/&quot;&gt;Flask&lt;/a&gt; and &lt;a href=&quot;https://realpython.com/tutorials/django/&quot;&gt;Django&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This reference guide assumes a working knowledge of Python modules and packages. Check out our &lt;a href=&quot;https://realpython.com/python-modules-packages/&quot;&gt;introduction to Python modules and packages&lt;/a&gt; for a refresher if you&amp;rsquo;re feeling a little rusty.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;command-line-application-layouts&quot;&gt;Command-Line Application Layouts&lt;/h2&gt;
&lt;p&gt;A lot of us work primarily with Python applications that are run via &lt;a href=&quot;https://realpython.com/comparing-python-command-line-parsing-libraries-argparse-docopt-click/&quot;&gt;command-line interfaces (CLIs)&lt;/a&gt;. This is where you often start with a blank canvas, and the flexibility of Python application layouts can be a real headache. &lt;/p&gt;
&lt;p&gt;Starting with an empty project folder can be intimidating and lead to no shortage of coder&amp;rsquo;s block. In this section, I want to share some proven layouts that I personally use as a starting point for all of my Python CLI applications. &lt;/p&gt;
&lt;p&gt;We&amp;rsquo;ll start with a very basic layout for a very basic use case: a simple script that runs on its own. You&amp;rsquo;ll then see how to build up the layout as the use cases advance.&lt;/p&gt;
&lt;h3 id=&quot;one-off-script&quot;&gt;One-Off Script&lt;/h3&gt;
&lt;p&gt;You just make a &lt;code&gt;.py&lt;/code&gt; script, and it&amp;rsquo;s gravy, right? No need to install&amp;mdash;just run the script in its directory! &lt;/p&gt;
&lt;p&gt;Well, that&amp;rsquo;s fine if you&amp;rsquo;re just making a script for your own use, or one that doesn&amp;rsquo;t have any external dependencies, but what if you have to distribute it? Especially to a less tech-savvy user? &lt;/p&gt;
&lt;p&gt;The following layout will work for all of these cases and can easily be modified to reflect whatever installation or other tools you use in your workflow. This layout will cover you whether you&amp;rsquo;re creating a pure Python script (that is, one with no dependencies) or using a tool like &lt;a href=&quot;https://pypi.org/project/pip/&quot;&gt;pip&lt;/a&gt; or &lt;a href=&quot;https://realpython.com/pipenv-guide/&quot;&gt;Pipenv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While you read this reference guide, keep in mind that the exact location of the files in the layout matters less than the reason they are placed where they are. All of these files should be in a project directory named after your project. For this example, we will use (what else?) &lt;code&gt;helloworld&lt;/code&gt; as the project name and root directory.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the Python project structure I typically use for a CLI app:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;helloworld/
│
├── .gitignore
├── helloworld.py
├── LICENSE
├── README.md
├── requirements.txt
├── setup.py
└── tests.py
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is pretty straightforward: everything is in the same directory. The files shown here are not necessarily exhaustive, but I recommend keeping the number of files to a minimum if you plan on using a basic layout like this. Some of these files will be new to you, so let&amp;rsquo;s take a quick look at what each of them does. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;.gitignore&lt;/code&gt;: This is a file that tells Git which kinds of files to ignore, like IDE clutter or local configuration files. &lt;a href=&quot;https://realpython.com/python-git-github-intro/#gitignore&quot;&gt;Our Git tutorial has all the details&lt;/a&gt;, and you can find sample &lt;code&gt;.gitignore&lt;/code&gt; files for Python projects &lt;a href=&quot;https://github.com/github/gitignore&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;helloworld.py&lt;/code&gt;: This is the script that you&amp;rsquo;re distributing. As far as naming the main script file goes, I recommend that you go with the name of your project (which is the same as the name of the top-level directory).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;LICENSE&lt;/code&gt;: This plaintext file describes the license you&amp;rsquo;re using for a project. It&amp;rsquo;s always a good idea to have one if you&amp;rsquo;re distributing code. The filename is in all caps by convention.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Need help selecting a license for your project? Check out &lt;a href=&quot;https://choosealicense.com/&quot;&gt;ChooseALicense&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;README.md&lt;/code&gt;: This is a &lt;a href=&quot;https://en.wikipedia.org/wiki/Markdown&quot;&gt;Markdown&lt;/a&gt; (or &lt;a href=&quot;https://en.wikipedia.org/wiki/ReStructuredText&quot;&gt;reStructuredText&lt;/a&gt;) file documenting the purpose and usage of your application. Crafting a good &lt;code&gt;README&lt;/code&gt; is an art, but you can find a shortcut to mastery &lt;a href=&quot;https://dbader.org/blog/write-a-great-readme-for-your-github-project&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;requirements.txt&lt;/code&gt;: This file defines outside Python dependencies and their versions for your application.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;setup.py&lt;/code&gt;: This file can also be used to define dependencies, but it really shines for other work that needs to be done during installation. You can read more about both &lt;code&gt;setup.py&lt;/code&gt; and &lt;code&gt;requirements.txt&lt;/code&gt; in our &lt;a href=&quot;https://realpython.com/pipenv-guide/&quot;&gt;guide to Pipenv&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;tests.py&lt;/code&gt;: This script houses your tests, if you have any. You should have some.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But now that your application is growing, and you&amp;rsquo;ve broken it out into multiple pieces within the same package, should you keep all pieces in the top-level directory? Now that your application is more complex, it&amp;rsquo;s time to organize things more cleanly.&lt;/p&gt;
&lt;h3 id=&quot;installable-single-package&quot;&gt;Installable Single Package&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s imagine that &lt;code&gt;helloworld.py&lt;/code&gt; is still the main script to execute, but you&amp;rsquo;ve moved all helper methods to a new file called &lt;code&gt;helpers.py&lt;/code&gt;. &lt;/p&gt;
&lt;p&gt;We are going to package the &lt;code&gt;helloworld&lt;/code&gt; Python files together but keep all the miscellaneous files, such as your &lt;code&gt;README&lt;/code&gt;, &lt;code&gt;.gitignore&lt;/code&gt;, and so on, at the top directory. &lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at the updated structure:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;helloworld/
│
├── helloworld/
│   ├── __init__.py
│   ├── helloworld.py
│   └── helpers.py
│
├── tests/
│   ├── helloworld_tests.py
│   └── helpers_tests.py
│
├── .gitignore
├── LICENSE
├── README.md
├── requirements.txt
└── setup.py
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The only difference here is that your application code is now all held in the &lt;code&gt;helloworld&lt;/code&gt; subdirectory&amp;mdash;this directory is named after your package&amp;mdash;and that we&amp;rsquo;ve added a file called &lt;code&gt;__init__.py&lt;/code&gt;. Let&amp;rsquo;s introduce these new files:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;helloworld/__init__.py&lt;/code&gt;: This file has many functions, but for our purposes it tells the Python interpreter that this directory is a package directory. You can set up this &lt;code&gt;__init__.py&lt;/code&gt; file in a way that enables you to import classes and methods from the package as a whole, instead of knowing the internal module structure and importing from &lt;code&gt;helloworld.helloworld&lt;/code&gt; or &lt;code&gt;helloworld.helpers&lt;/code&gt;. &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For a deeper discussion on internal packages and &lt;code&gt;__init__.py&lt;/code&gt;, &lt;a href=&quot;https://realpython.com/python-modules-packages/&quot;&gt;our Python modules and packages overview&lt;/a&gt; has you covered.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;helloworld/helpers.py&lt;/code&gt;: As mentioned above, we&amp;rsquo;ve moved much of &lt;code&gt;helloworld.py&lt;/code&gt;&amp;rsquo;s business logic to this file. Thanks to &lt;code&gt;__init__.py&lt;/code&gt;, outside modules will be able to access these helpers simply by importing from the &lt;code&gt;helloworld&lt;/code&gt; package.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;tests/&lt;/code&gt;: We&amp;rsquo;ve moved our tests into their own directory, a pattern you&amp;rsquo;ll continue to see as our program structures gain complexity. We have also split our tests into separate modules, mirroring our package&amp;rsquo;s structure.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This layout is a stripped down version of &lt;a href=&quot;https://github.com/kennethreitz/samplemod&quot;&gt;Kenneth Reitz&amp;rsquo;s samplemod application structure&lt;/a&gt;. It is another great starting point for your CLI applications, especially for more expansive projects. &lt;/p&gt;
&lt;h3 id=&quot;application-with-internal-packages&quot;&gt;Application with Internal Packages&lt;/h3&gt;
&lt;p&gt;In larger applications, you may have one or more internal packages that are either tied together with a main runner script or that provide specific functionality to a larger library you are packaging. We will extend the conventions laid out above to accommodate for this:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;helloworld/
│
├── bin/
│
├── docs/
│   ├── hello.md
│   └── world.md
│
├── helloworld/
│   ├── __init__.py
│   ├── runner.py
│   ├── hello/
│   │   ├── __init__.py
│   │   ├── hello.py
│   │   └── helpers.py
│   │
│   └── world/
│       ├── __init__.py
│       ├── helpers.py
│       └── world.py
│
├── data/
│   ├── input.csv
│   └── output.xlsx
│
├── tests/
│   ├── hello
│   │   ├── helpers_tests.py
│   │   └── hello_tests.py
│   │
│   └── world/
│       ├── helpers_tests.py
│       └── world_tests.py
│
├── .gitignore
├── LICENSE
└── README.md
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There&amp;rsquo;s a bit more to digest here, but as long as you remember that it follows from the previous layout, you will have an easier time following along. I&amp;rsquo;ll go through the additions and modifications in order, their uses, and the reasons you might want them. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;bin/&lt;/code&gt;: This directory holds any executable files. I&amp;rsquo;ve adapted this from &lt;a href=&quot;http://as.ynchrono.us/2007/12/filesystem-structure-of-python-project_21.html&quot;&gt;Jean-Paul Calderone&amp;rsquo;s classic structure post&lt;/a&gt;, and his prescriptions for the use of a &lt;code&gt;bin/&lt;/code&gt; directory are still important. The most important point to remember is that your executable shouldn&amp;rsquo;t have a lot of code, just an import and a call to a main function in your runner script. If you are using pure Python or don&amp;rsquo;t have any executable files, you can leave out this directory. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;/docs&lt;/code&gt;: With a more advanced application, you&amp;rsquo;ll want to maintain good documentation of all its parts. I like to put any documentation for internal modules here, which is why you see separate documents for the &lt;code&gt;hello&lt;/code&gt; and &lt;code&gt;world&lt;/code&gt; packages. If you use docstrings in your internal modules (and you should!), your whole-module documentation should at the very least give a holistic view of the purpose and function of the module.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;helloworld/&lt;/code&gt;: This is similar to &lt;code&gt;helloworld/&lt;/code&gt; in the previous structure, but now there are subdirectories. As you add more complexity, you&amp;rsquo;ll want to use a &amp;ldquo;divide and conquer&amp;rdquo; tactic and split out parts of your application logic into more manageable chunks. Remember that the directory name refers to the overall package name, and so the subdirectory names (&lt;code&gt;hello/&lt;/code&gt; and &lt;code&gt;world/&lt;/code&gt;) should reflect their package names.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;data/&lt;/code&gt;: Having this directory is helpful for testing. It&amp;rsquo;s a central location for any files that your application will ingest or produce. Depending on how you deploy your application, you can keep &amp;ldquo;production-level&amp;rdquo; inputs and outputs pointed to this directory, or only use it for internal testing. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;tests/&lt;/code&gt;: Here, you can put all your tests&amp;mdash;unit tests, execution tests, integration tests, and so on. Feel free to structure this directory in the most convenient way for your testing strategies, import strategies, and more. For a refresher on testing command-line applications with Python, check out my article &lt;a href=&quot;https://realpython.com/python-cli-testing/&quot;&gt;4 Techniques for Testing Python Command-Line (CLI) Apps&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The top-level files remain largely the same as in the previous layout. These three layouts should cover most use cases for command-line applications, and even GUI applications with the caveat that you may have to tinker with some things depending on the GUI framework you use. &lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Keep in mind that these are just layouts. If a directory or file doesn&amp;rsquo;t make sense for your specific use case (like &lt;code&gt;tests/&lt;/code&gt; if you aren&amp;rsquo;t distributing tests with your code), feel free to leave it out. But try not to leave out &lt;code&gt;docs/&lt;/code&gt;. It&amp;rsquo;s always a good idea to document your work.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;web-application-layouts&quot;&gt;Web Application Layouts&lt;/h2&gt;
&lt;p&gt;Another major use case of Python is web applications. &lt;a href=&quot;https://www.djangoproject.com/&quot;&gt;Django&lt;/a&gt; and &lt;a href=&quot;http://flask.pocoo.org/&quot;&gt;Flask&lt;/a&gt; are arguably the most popular web frameworks for Python and thankfully are a little more opinionated when it comes to application layout. &lt;/p&gt;
&lt;p&gt;In order to make sure this article is a complete, full-fledged layout reference, I wanted to highlight the structure common to these frameworks.&lt;/p&gt;
&lt;h3 id=&quot;django&quot;&gt;Django&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s go in alphabetical order and start with Django. One of the nice things about Django is that it will create a project skeleton for you after running &lt;code&gt;django-admin startproject project&lt;/code&gt;, where &lt;code&gt;project&lt;/code&gt; is the name of your project. This will create a directory in your current working directory called &lt;code&gt;project&lt;/code&gt; with the following internal structure:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;project/
│
├── project/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
│
└── manage.py
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This seems a little empty, doesn&amp;rsquo;t it? Where does all the logic go? The views? There aren&amp;rsquo;t even any tests! &lt;/p&gt;
&lt;p&gt;In Django, this is a project, which ties together the other Django concept, apps. Apps are where logic, models, views, and so on all live, and in doing so they do some task, such as maintaining a blog. &lt;/p&gt;
&lt;p&gt;Django apps can be imported into projects and used across projects, and are structured like specialized Python packages.&lt;/p&gt;
&lt;p&gt;Like projects, Django makes generating Django app layouts really easy. After you set up your project, all you have to do is navigate to the location of &lt;code&gt;manage.py&lt;/code&gt; and run &lt;code&gt;python manage.py startapp app&lt;/code&gt;, where &lt;code&gt;app&lt;/code&gt; is the name of your app. &lt;/p&gt;
&lt;p&gt;This will result in a directory called &lt;code&gt;app&lt;/code&gt; with the following layout:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;app/
│
├── migrations/
│   └── __init__.py
│
├── __init__.py
├── admin.py
├── apps.py
├── models.py
├── tests.py
└── views.py
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This can then be imported directly into your project. Details on what these files do, how to harness them for your project, and so forth are outside the scope of this reference, but you can get all that information and more &lt;a href=&quot;https://realpython.com/learn/start-django/&quot;&gt;in our Django tutorial&lt;/a&gt; and also &lt;a href=&quot;https://docs.djangoproject.com/en/2.0/intro/tutorial01/&quot;&gt;in the official Django docs&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;This file and folder structure is very barebones and the basic requirements for Django. For any open-source Django project, you can (and should) adapt the structures from the command-line application layouts. I typically end up with something like this in the outer &lt;code&gt;project/&lt;/code&gt; directory:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;project/
│
├── app/
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   │
│   ├── migrations/
│   │   └── __init__.py
│   │
│   ├── models.py
│   ├── tests.py
│   └── views.py
│
├── docs/
│
├── project/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
│
├── static/
│   └── style.css
│
├── templates/
│   └── base.html
│
├── .gitignore
├── manage.py
├── LICENSE
└── README.md
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For a deeper discussion on more advanced Django application layouts, &lt;a href=&quot;https://stackoverflow.com/questions/22841764/best-practice-for-django-project-working-directory-structure&quot;&gt;this Stack Overflow thread&lt;/a&gt; has you covered. The &lt;a href=&quot;http://django-project-skeleton.readthedocs.io/en/latest/structure.html&quot;&gt;django-project-skeleton&lt;/a&gt; project documentation explains some of the directories you will find in the Stack Overflow thread. A comprehensive dive into Django can be found in the pages of &lt;a href=&quot;https://realpython.com/asins/0692915729&quot;&gt;Two Scoops of Django&lt;/a&gt;, which will teach you all of the latest best practices for Django development.&lt;/p&gt;
&lt;p&gt;For more Django tutorials, &lt;a href=&quot;https://realpython.com/tutorials/django/&quot;&gt;visit our Django section at Real Python&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;flask&quot;&gt;Flask&lt;/h3&gt;
&lt;p&gt;Flask is a Python web &amp;ldquo;microframework.&amp;rdquo; One of the main selling points is that it is very quick to set up with minimal overhead. The &lt;a href=&quot;http://flask.pocoo.org/docs/1.0/&quot;&gt;Flask documentation&lt;/a&gt; has a web application example that&amp;rsquo;s under 10 lines of code and in a single script. Of course, in practice, it&amp;rsquo;s highly unlikely you&amp;rsquo;ll be writing a web application this small. &lt;/p&gt;
&lt;p&gt;Luckily, the Flask documentation &lt;a href=&quot;http://flask.pocoo.org/docs/1.0/tutorial/layout/&quot;&gt;swoops in to save us&lt;/a&gt; with a suggested layout for their tutorial project (a blogging web application called Flaskr), and we will examine that here from within the main project directory:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;flaskr/
│
├── flaskr/
│   ├── ___init__.py
│   ├── db.py
│   ├── schema.sql
│   ├── auth.py
│   ├── blog.py
│   ├── templates/
│   │   ├── base.html
│   │   ├── auth/
│   │   │   ├── login.html
│   │   │   └── register.html
│   │   │
│   │   └── blog/
│   │       ├── create.html
│   │       ├── index.html
│   │       └── update.html
│   │ 
│   └── static/
│       └── style.css
│
├── tests/
│   ├── conftest.py
│   ├── data.sql
│   ├── test_factory.py
│   ├── test_db.py
│   ├── test_auth.py
│   └── test_blog.py
│
├── venv/
│
├── .gitignore
├── setup.py
└── MANIFEST.in
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From these contents, we can see that a Flask application, like most Python applications, is built around Python packages. &lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Not seeing it? A quick tip for spotting packages is by looking for an &lt;code&gt;__init__.py&lt;/code&gt; file. This sits in the highest-level directory for that particular package. In the above layout, &lt;code&gt;flaskr&lt;/code&gt; is a package containing the &lt;code&gt;db&lt;/code&gt;, &lt;code&gt;auth&lt;/code&gt;, and &lt;code&gt;blog&lt;/code&gt; modules. &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In this layout, everything lives in the &lt;code&gt;flaskr&lt;/code&gt; package except for your tests, a directory for your &lt;a href=&quot;https://realpython.com/python-virtual-environments-a-primer/&quot;&gt;virtual environments&lt;/a&gt;, and your usual top-level files. As in other layouts, your tests will roughly match the individual modules residing within the &lt;code&gt;flaskr&lt;/code&gt; package. Your templates also reside in the main project package, which would not happen with the Django layouts.&lt;/p&gt;
&lt;p&gt;Be sure to also visit our &lt;a href=&quot;https://github.com/realpython/flask-boilerplate&quot;&gt;Flask Boilerplate Github page&lt;/a&gt; for a view of a more fully fleshed-out Flask application and see the boilerplate in action &lt;a href=&quot;http://www.flaskboilerplate.com/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;For more on Flask, &lt;a href=&quot;https://realpython.com/tutorials/flask/&quot;&gt;check out all of our Flask tutorials here&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusions-and-reminders&quot;&gt;Conclusions and Reminders&lt;/h2&gt;
&lt;p&gt;Now you&amp;rsquo;ve seen example layouts for a number of different application types: one-off Python scripts, installable single packages, larger applications with internal packages, Django web applications, and Flask web applications. &lt;/p&gt;
&lt;p&gt;Coming away from this guide, you will have the tools to successfully prevent coder&amp;rsquo;s block by building out your application structure so that you&amp;rsquo;re not staring at a blank canvas trying to figure out where to start. &lt;/p&gt;
&lt;p&gt;Because Python is largely non-opinionated when it comes to application layouts, you can customize these example layouts to your heart&amp;rsquo;s content to better fit your use case. &lt;/p&gt;
&lt;p&gt;I want you to not only have an application layout reference but also come away with the understanding that these examples are neither hard-and-fast rules nor the only way to structure your application. Over time and with practice, you&amp;rsquo;ll develop the ability to build and customize your own useful Python application layouts.&lt;/p&gt;
&lt;p&gt;Did I miss a use case? Do you have another application structure philosophy? Did this article help prevent coder&amp;rsquo;s block? Let me know in the comments!&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Itertools in Python 3, By Example</title>
      <id>https://realpython.com/python-itertools/</id>
      <link href="https://realpython.com/python-itertools/"/>
      <updated>2018-05-30T14:00:00+00:00</updated>
      <summary>Master Python&#39;s itertools module by constructing practical examples. We&#39;ll start out simple and then gradually increase in complexity, encouraging you to &quot;think iteratively.&quot;</summary>
      <content type="html">
        &lt;p&gt;It has been called a &lt;a href=&quot;https://more-itertools.readthedocs.io/en/latest/index.html&quot;&gt;&amp;ldquo;gem&amp;rdquo;&lt;/a&gt; and &lt;a href=&quot;http://jmduke.com/posts/a-gentle-introduction-to-itertools/&quot;&gt;&amp;ldquo;pretty much the coolest thing ever,&amp;rdquo;&lt;/a&gt; and if you have not heard of it, then you are missing out on one of the greatest corners of the Python 3 standard library: &lt;code&gt;itertools&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A handful of excellent resources exist for learning what functions are available in the &lt;code&gt;itertools&lt;/code&gt; module. The &lt;a href=&quot;https://docs.python.org/3/library/itertools.html&quot;&gt;docs&lt;/a&gt; themselves are a great place to start. So is &lt;a href=&quot;https://pymotw.com/3/itertools/index.html&quot;&gt;this post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The thing about &lt;code&gt;itertools&lt;/code&gt;, though, is that it is not enough to just know the definitions of the functions it contains. The real power lies in composing these functions to create fast, memory-efficient, and good-looking code.&lt;/p&gt;
&lt;p&gt;This article takes a different approach. Rather than introducing &lt;code&gt;itertools&lt;/code&gt; to you one function at a time, you will construct practical examples designed to encourage you to &amp;ldquo;think iteratively.&amp;rdquo; In general, the examples will start simple and gradually increase in complexity.&lt;/p&gt;
&lt;p&gt;A word of warning: this article is long and intended for the intermediate-to-advanced Python programmer. Before diving in, you should be confident using iterators and generators in Python 3, multiple assignment, and tuple unpacking. If you aren&amp;rsquo;t, or if you need to brush up on your knowledge, consider checking out the following before reading on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dbader.org/blog/python-iterators&quot;&gt;Python Iterators: A Step-By-Step Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://realpython.com/introduction-to-python-generators/&quot;&gt;Introduction to Python Generators&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Chapter 6 of &lt;a href=&quot;https://realpython.com/asins/1775093301&quot;&gt;Python Tricks: The Book&lt;/a&gt; by Dan Bader&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://treyhunner.com/2018/03/tuple-unpacking-improves-python-code-readability/&quot;&gt;Multiple assignment and tuple unpacking improve Python code readability&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/optins/view/itertools-cheatsheet/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-itertools-cheatsheet&quot; data-focus=&quot;false&quot;&gt;Click here to get our itertools cheat sheet&lt;/a&gt; that summarizes the techniques demonstrated in this tutorial.&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;All set? Let&amp;rsquo;s start the way any good journey should&amp;mdash;with a question.&lt;/p&gt;
&lt;h2 id=&quot;what-is-itertools-and-why-should-you-use-it&quot;&gt;What Is &lt;code&gt;Itertools&lt;/code&gt; and Why Should You Use It?&lt;/h2&gt;
&lt;p&gt;According to the &lt;a href=&quot;https://docs.python.org/3/library/itertools.html&quot;&gt;&lt;code&gt;itertools&lt;/code&gt; docs&lt;/a&gt;, it is a &amp;ldquo;module [that] implements a number of iterator building blocks inspired by constructs from APL, Haskell, and SML&amp;hellip; Together, they form an &amp;lsquo;iterator algebra&amp;rsquo; making it possible to construct specialized tools succinctly and efficiently in pure Python.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Loosely speaking, this means that the functions in &lt;code&gt;itertools&lt;/code&gt; &amp;ldquo;operate&amp;rdquo; on iterators to produce more complex iterators. Consider, for example, the &lt;a href=&quot;https://docs.python.org/3/library/functions.html#zip&quot;&gt;built-in &lt;code&gt;zip()&lt;/code&gt; function&lt;/a&gt;, which takes any number of iterables as arguments and returns an iterator over tuples of their corresponding elements:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, &amp;#39;a&amp;#39;), (2, &amp;#39;b&amp;#39;), (3, &amp;#39;c&amp;#39;)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;How, exactly, does &lt;code&gt;zip()&lt;/code&gt; work?&lt;/p&gt;
&lt;p&gt;&lt;code&gt;[1, 2, 3]&lt;/code&gt; and &lt;code&gt;[&#39;a&#39;, &#39;b&#39;, &#39;c&#39;]&lt;/code&gt;, like all lists, are iterable, which means they can return their elements one at a time. Technically, any Python object that implements the &lt;code&gt;.__iter__()&lt;/code&gt; or &lt;code&gt;.__getitem__()&lt;/code&gt; methods is iterable. (See the &lt;a href=&quot;https://docs.python.org/3/glossary.html#term-iterable&quot;&gt;Python 3 docs glossary&lt;/a&gt; for a more detailed explanation.)&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;https://docs.python.org/3/library/functions.html#iter&quot;&gt;&lt;code&gt;iter()&lt;/code&gt; built-in function&lt;/a&gt;, when called on an iterable, returns an &lt;a href=&quot;https://docs.python.org/3/library/stdtypes.html#typeiter&quot;&gt;iterator object&lt;/a&gt; for that iterable:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;lt;list_iterator object at 0x7fa80af0d898&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Under the hood, the &lt;code&gt;zip()&lt;/code&gt; function works, in essence, by calling &lt;code&gt;iter()&lt;/code&gt; on each of its arguments, then advancing each iterator returned by &lt;code&gt;iter()&lt;/code&gt; with &lt;code&gt;next()&lt;/code&gt; and aggregating the results into tuples. The iterator returned by &lt;code&gt;zip()&lt;/code&gt; iterates over these tuples.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.python.org/3/library/functions.html#map&quot;&gt;The &lt;code&gt;map()&lt;/code&gt; built-in function&lt;/a&gt; is another &amp;ldquo;iterator operator&amp;rdquo; that, in its simplest form, applies a single-parameter function to each element of an iterable one element at a time:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;de&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;fghi&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[3, 2, 4]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;map()&lt;/code&gt; function works by calling &lt;code&gt;iter()&lt;/code&gt; on its second argument, advancing this iterator with &lt;code&gt;next()&lt;/code&gt; until the iterator is exhausted, and applying the function passed to its first argument to the value returned by &lt;code&gt;next()&lt;/code&gt; at each step. In the above example, &lt;code&gt;len()&lt;/code&gt; is called on each element of &lt;code&gt;[&#39;abc&#39;, &#39;de&#39;, &#39;fghi&#39;]&lt;/code&gt; to return an iterator over the lengths of each string in the list.&lt;/p&gt;
&lt;p&gt;Since &lt;a href=&quot;https://docs.python.org/3/glossary.html#term-iterator&quot;&gt;iterators are iterable&lt;/a&gt;, you can compose &lt;code&gt;zip()&lt;/code&gt; and &lt;code&gt;map()&lt;/code&gt; to produce an iterator over combinations of elements in more than one iterable. For example, the following sums corresponding elements of two lists:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[5, 7, 9]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is what is meant by the functions in &lt;code&gt;itertools&lt;/code&gt; forming an &amp;ldquo;iterator algebra.&amp;rdquo; &lt;code&gt;itertools&lt;/code&gt; is best viewed as a collection of building blocks that can be combined to form specialized &amp;ldquo;data pipelines&amp;rdquo; like the one in the example above.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Historical Note:&lt;/strong&gt; In Python 2, the built-in &lt;a href=&quot;https://docs.python.org/2/library/functions.html#zip&quot;&gt;&lt;code&gt;zip()&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://docs.python.org/2/library/functions.html#map&quot;&gt;&lt;code&gt;map()&lt;/code&gt;&lt;/a&gt; functions do not return an iterator, but rather a list. To return an iterator, the &lt;a href=&quot;https://docs.python.org/2/library/itertools.html#itertools.izip&quot;&gt;&lt;code&gt;izip()&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://docs.python.org/2/library/itertools.html#itertools.imap&quot;&gt;&lt;code&gt;imap()&lt;/code&gt;&lt;/a&gt; functions of &lt;code&gt;itertools&lt;/code&gt; must be used. In Python 3,  &lt;code&gt;izip()&lt;/code&gt; and &lt;code&gt;imap()&lt;/code&gt; have been &lt;a href=&quot;https://docs.python.org/3.0/whatsnew/3.0.html#views-and-iterators-instead-of-lists&quot;&gt;removed from &lt;code&gt;itertools&lt;/code&gt;&lt;/a&gt; and replaced the &lt;code&gt;zip()&lt;/code&gt; and &lt;code&gt;map()&lt;/code&gt; built-ins. So, in a way, if you have ever used &lt;code&gt;zip()&lt;/code&gt; or &lt;code&gt;map()&lt;/code&gt; in Python 3, you have already been using &lt;code&gt;itertools&lt;/code&gt;!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are two main reasons why such an &amp;ldquo;iterator algebra&amp;rdquo; is useful: improved memory efficiency (via &lt;a href=&quot;https://en.wikipedia.org/wiki/Lazy_evaluation&quot;&gt;lazy evaluation&lt;/a&gt;) and faster execuction time. To see this, consider the following problem:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Given a list of values &lt;code&gt;inputs&lt;/code&gt; and a positive integer &lt;code&gt;n&lt;/code&gt;, write a function that splits &lt;code&gt;inputs&lt;/code&gt; into groups of length &lt;code&gt;n&lt;/code&gt;. For simplicity, assume that the length of the input list is divisible by &lt;code&gt;n&lt;/code&gt;. For example, if &lt;code&gt;inputs = [1, 2, 3, 4, 5, 6]&lt;/code&gt; and &lt;code&gt;n = 2&lt;/code&gt;, your function should return &lt;code&gt;[(1, 2), (3, 4), (5, 6)]&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Taking a naive approach, you might write something like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;naive_grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;num_groups&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_groups&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When you test it, you see that it works as expected:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nums&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;naive_grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nums&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What happens when you try to pass it a list with, say, 100 million elements? You will need a whole lot of available memory! Even if you have enough memory available, your program will hang for a while until the output list is populated.&lt;/p&gt;
&lt;p&gt;To see this, store the following in a script called &lt;code&gt;naive.py&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;naive_grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;num_groups&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;//&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num_groups&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;naive_grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100000000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;From the console, you can use the &lt;code&gt;time&lt;/code&gt; command (on UNIX systems) to measure memory usage and CPU user time. &lt;strong&gt;Make sure you have at least 5GB of free memory before executing the following:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt; -f &lt;span class=&quot;s2&quot;&gt;&amp;quot;Memory used (kB): %M\nUser time (seconds): %U&amp;quot;&lt;/span&gt; python3 naive.py
&lt;span class=&quot;go&quot;&gt;Memory used (kB): 4551872&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;User time (seconds): 11.04&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; On Ubuntu, you may need to run &lt;code&gt;/usr/bin/time&lt;/code&gt; instead of &lt;code&gt;time&lt;/code&gt; for the above example to work.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &lt;code&gt;list&lt;/code&gt; and &lt;code&gt;tuple&lt;/code&gt; implementation in &lt;code&gt;naive_grouper()&lt;/code&gt; requires approximately 4.5GB of memory to process &lt;code&gt;range(100000000)&lt;/code&gt;. Working with iterators drastically improves this situation. Consider the following:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;better_grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There&amp;rsquo;s a lot going on in this little function, so let&amp;rsquo;s break it down with a concrete example. The expression &lt;code&gt;[iters(inputs)] * n&lt;/code&gt; creates a list of &lt;code&gt;n&lt;/code&gt; references to the same iterator:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nums&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nums&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;itr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itr&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# IDs are the same.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[139949748267160, 139949748267160]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, &lt;code&gt;zip(*iters)&lt;/code&gt; returns an iterator over pairs of corresponding elements of each iterator in &lt;code&gt;iters&lt;/code&gt;. When the first element, &lt;code&gt;1&lt;/code&gt;, is taken from the &amp;ldquo;first&amp;rdquo; iterator, the &amp;ldquo;second&amp;rdquo; iterator now starts at &lt;code&gt;2&lt;/code&gt; since it is just a reference to the &amp;ldquo;first&amp;rdquo; iterator and has therefore been advanced one step. So, the first tuple produced by &lt;code&gt;zip()&lt;/code&gt; is &lt;code&gt;(1, 2)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;At this point, &amp;ldquo;both&amp;rdquo; iterators in &lt;code&gt;iters&lt;/code&gt; start at &lt;code&gt;3&lt;/code&gt;, so when &lt;code&gt;zip()&lt;/code&gt; pulls &lt;code&gt;3&lt;/code&gt; from the &amp;ldquo;first&amp;rdquo; iterator, it gets &lt;code&gt;4&lt;/code&gt; from the &amp;ldquo;second&amp;rdquo; to produce the tuple &lt;code&gt;(3, 4)&lt;/code&gt;. This process continues until &lt;code&gt;zip()&lt;/code&gt; finally produces &lt;code&gt;(9, 10)&lt;/code&gt; and &amp;ldquo;both&amp;rdquo; iterators in &lt;code&gt;iters&lt;/code&gt; are exhausted:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nums&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;better_grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nums&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;better_grouper()&lt;/code&gt; function is better for a couple of reasons. First, without the reference to the &lt;code&gt;len()&lt;/code&gt; built-in, &lt;code&gt;better_grouper()&lt;/code&gt; can take any iterable as an argument (even infinite iterators). Second, by returning an iterator rather than a list, &lt;code&gt;better_grouper()&lt;/code&gt; can process enormous iterables without trouble and uses much less memory.&lt;/p&gt;
&lt;p&gt;Store the following in a file called &lt;code&gt;better.py&lt;/code&gt; and run it with &lt;code&gt;time&lt;/code&gt; from the console again:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;better_grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;better_grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100000000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;time&lt;/span&gt; -f &lt;span class=&quot;s2&quot;&gt;&amp;quot;Memory used (kB): %M\nUser time (seconds): %U&amp;quot;&lt;/span&gt; python3 better.py
&lt;span class=&quot;go&quot;&gt;Memory used (kB): 7224&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;User time (seconds): 2.48&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That&amp;rsquo;s a whopping 630 times less memory used than &lt;code&gt;naive.py&lt;/code&gt; in less than a quarter of the time!&lt;/p&gt;
&lt;p&gt;Now that you&amp;rsquo;ve seen what &lt;code&gt;itertools&lt;/code&gt; is (&amp;ldquo;iterator algebra&amp;rdquo;) and why you should use it (improved memory efficiency and faster execution time), let&amp;rsquo;s take a look at how to take &lt;code&gt;better_grouper()&lt;/code&gt; to the next level with &lt;code&gt;itertools&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;the-grouper-recipe&quot;&gt;The &lt;code&gt;grouper&lt;/code&gt; Recipe&lt;/h2&gt;
&lt;p&gt;The problem with &lt;code&gt;better_grouper()&lt;/code&gt; is that it doesn&amp;rsquo;t handle situations where the value passed to the second argument isn&amp;rsquo;t a factor of the length of the iterable in the first argument:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nums&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;better_grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nums&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 2, 3, 4), (5, 6, 7, 8)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The elements 9 and 10 are missing from the grouped output. This happens because &lt;code&gt;zip()&lt;/code&gt; stops aggregating elements once the shortest iterable passed to it is exhausted. It would make more sense to return a third group containing 9 and 10.&lt;/p&gt;
&lt;p&gt;To do this, you can use &lt;code&gt;itertools.zip_longest()&lt;/code&gt;. This function accepts any number of iterables as arguments and a &lt;code&gt;fillvalue&lt;/code&gt; keyword argument that defaults to &lt;code&gt;None&lt;/code&gt;. The easiest way to get a sense of the difference between &lt;code&gt;zip()&lt;/code&gt; and &lt;code&gt;zip_longest()&lt;/code&gt; is to look at some example output:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;itertools&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;it&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, &amp;#39;a&amp;#39;), (2, &amp;#39;b&amp;#39;), (3, &amp;#39;c&amp;#39;)]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zip_longest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, &amp;#39;a&amp;#39;), (2, &amp;#39;b&amp;#39;), (3, &amp;#39;c&amp;#39;), (4, None), (5, None)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;With this in mind, replace &lt;code&gt;zip()&lt;/code&gt; in &lt;code&gt;better_grouper()&lt;/code&gt; with &lt;code&gt;zip_longest()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;itertools&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;it&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fillvalue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zip_longest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fillvalue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fillvalue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now you get a better result:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nums&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nums&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 2, 3, 4), (5, 6, 7, 8), (9, 10, None, None)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;grouper()&lt;/code&gt; function can be found in the &lt;a href=&quot;https://docs.python.org/3.6/library/itertools.html#itertools-recipes&quot;&gt;Recipes section&lt;/a&gt; of the &lt;code&gt;itertools&lt;/code&gt; docs. The recipes are an excellent source of inspiration for ways to use &lt;code&gt;itertools&lt;/code&gt; to your advantage.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: From this point forward, the line &lt;code&gt;import itertools as it&lt;/code&gt; will not be included at the beginning of examples. All &lt;code&gt;itertools&lt;/code&gt; methods in code examples are prefaced with &lt;code&gt;it.&lt;/code&gt; The module import is implied.&lt;/p&gt;
&lt;p&gt;If you get a &lt;code&gt;NameError: name &#39;itertools&#39; is not defined&lt;/code&gt; or a &lt;code&gt;NameError: name &#39;it&#39; is not defined&lt;/code&gt; exception when running one of the examples in this tutorial you&amp;rsquo;ll need to import the &lt;code&gt;itertools&lt;/code&gt; module first.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;et-tu-brute-force&quot;&gt;Et tu, Brute Force?&lt;/h2&gt;
&lt;p&gt;Here&amp;rsquo;s a common interview-style problem:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You have three $20 dollar bills, five $10 dollar bills, two $5 dollar bills, and five $1 dollar bills. How many ways can you make change for a $100 dollar bill?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To &lt;a href=&quot;https://en.wikipedia.org/wiki/Brute-force_search&quot;&gt;&amp;ldquo;brute force&amp;rdquo;&lt;/a&gt; this problem, you just start listing off the ways there are to choose one bill from your wallet, check whether any of these makes change for $100, then list the ways to pick two bills from your wallet, check again, and so on and so forth.&lt;/p&gt;
&lt;p&gt;But you are a programmer, so naturally you want to automate this process.&lt;/p&gt;
&lt;p&gt;First, create a list of the bills you have in your wallet:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bills&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A choice of &lt;em&gt;k&lt;/em&gt; things from a set of &lt;em&gt;n&lt;/em&gt; things is called a &lt;a href=&quot;https://en.wikipedia.org/wiki/Combination&quot;&gt;&lt;strong&gt;combination&lt;/strong&gt;&lt;/a&gt;, and &lt;code&gt;itertools&lt;/code&gt; has your back here. The &lt;code&gt;itertools.combinations()&lt;/code&gt; function takes two arguments&amp;mdash;an iterable &lt;code&gt;inputs&lt;/code&gt; and a positive integer &lt;code&gt;n&lt;/code&gt;&amp;mdash;and produces an iterator over tuples of all combinations of &lt;code&gt;n&lt;/code&gt; elements in &lt;code&gt;inputs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For example, to list the combinations of three bills in your wallet, just do:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;combinations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bills&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; [(20, 20, 20), (20, 20, 10), (20, 20, 10), ... ]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To solve the problem, you can loop over the positive integers from 1 to &lt;code&gt;len(bills)&lt;/code&gt;, then check which combinations of each size add up to $100:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;makes_100&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bills&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;combination&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;combinations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bills&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;combination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;makes_100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;combination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you print out &lt;code&gt;makes_100&lt;/code&gt;, you will notice there are a lot of repeated combinations. This makes sense because you can make change for $100 with three $20 dollar bills and four $10 bills, but &lt;code&gt;combinations()&lt;/code&gt; does this with the first four $10 dollars bills in your wallet; the first, third, fourth and fifth $10 dollar bills; the first, second, fourth and fifth $10 bills; and so on.&lt;/p&gt;
&lt;p&gt;To remove duplicates from &lt;code&gt;makes_100&lt;/code&gt;, you can convert it to a &lt;code&gt;set&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;makes_100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;{(20, 20, 10, 10, 10, 10, 10, 5, 1, 1, 1, 1, 1),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; (20, 20, 10, 10, 10, 10, 10, 5, 5),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; (20, 20, 20, 10, 10, 10, 5, 1, 1, 1, 1, 1),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; (20, 20, 20, 10, 10, 10, 5, 5),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; (20, 20, 20, 10, 10, 10, 10)}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;So, there are five ways to make change for a $100 bill with the bills you have in your wallet.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a variation on the same problem:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;How many ways are there to make change for a $100 bill using any number of $50, $20, $10, $5, and $1 dollar bills?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this case, you don&amp;rsquo;t have a pre-set collection of bills, so you need a way to generate all possible combinations using any number of bills. For this, you&amp;rsquo;ll need the &lt;code&gt;itertools.combinations_with_replacement()&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;It works just like &lt;code&gt;combinations()&lt;/code&gt;, accepting an iterable &lt;code&gt;inputs&lt;/code&gt; and a positive integer &lt;code&gt;n&lt;/code&gt;, and returns an iterator over &lt;code&gt;n&lt;/code&gt;-tuples of elements from &lt;code&gt;inputs&lt;/code&gt;. The difference is that &lt;code&gt;combinations_with_replacement()&lt;/code&gt; allows elements to be repeated in the tuples it returns.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;combinations_with_replacement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 1), (1, 2), (2, 2)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Compare that to &lt;code&gt;combinations()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;combinations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, 2)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here&amp;rsquo;s what the solution to the revised problem looks like:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bills&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;make_100&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;101&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;combination&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;combinations_with_replacement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bills&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;combination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;            &lt;span class=&quot;n&quot;&gt;makes_100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;combination&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In this case, you do not need to remove any duplicates since &lt;code&gt;combinations_with_replacement()&lt;/code&gt; won&amp;rsquo;t produce any:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;makes_100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;343&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you run the above solution, you may notice that it takes a while for the output to display. That is because it has to process 96,560,645 combinations!&lt;/p&gt;
&lt;p&gt;Another &amp;ldquo;brute force&amp;rdquo; &lt;code&gt;itertools&lt;/code&gt; function is &lt;code&gt;permutations()&lt;/code&gt;, which accepts a single iterable and produces all possible permutations (rearrangements) of its elements:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;permutations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;), (&amp;#39;a&amp;#39;, &amp;#39;c&amp;#39;, &amp;#39;b&amp;#39;), (&amp;#39;b&amp;#39;, &amp;#39;a&amp;#39;, &amp;#39;c&amp;#39;),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; (&amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;, &amp;#39;a&amp;#39;), (&amp;#39;c&amp;#39;, &amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;), (&amp;#39;c&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;a&amp;#39;)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Any iterable of three elements will have six permutations, and the number of permutations of longer iterables grows extremely fast. In fact, an iterable of length &lt;em&gt;n&lt;/em&gt; has &lt;em&gt;n!&lt;/em&gt; permutations, where&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/n_factorial.ac839fb0429e.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/n_factorial.ac839fb0429e.png&quot; width=&quot;1428&quot; height=&quot;83&quot; alt=&quot;Definition of a factorial&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To put this in perspective, here&amp;rsquo;s a table of these numbers for &lt;em&gt;n = 1&lt;/em&gt; to &lt;em&gt;n = 10&lt;/em&gt;:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;em&gt;n&lt;/em&gt;&lt;/th&gt;
&lt;th&gt;&lt;em&gt;n!&lt;/em&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;120&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;720&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;5,040&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;40,320&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;362,880&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;3,628,800&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;The phenomenon of just a few inputs producing a large number of outcomes is called a &lt;a href=&quot;https://en.wikipedia.org/wiki/Combinatorial_explosion&quot;&gt;combinatorial explosion&lt;/a&gt; and is something to keep in mind when working with &lt;code&gt;combinations()&lt;/code&gt;, &lt;code&gt;combinations_with_replacement()&lt;/code&gt;, and &lt;code&gt;permutations()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;It is usually best to avoid brute force algorithms, although there are times you may need to use one (for example, if the correctness of the algorithm is critical, or every possible outcome &lt;em&gt;must&lt;/em&gt; be considered). In that case, &lt;code&gt;itertools&lt;/code&gt; has you covered.&lt;/p&gt;
&lt;h3 id=&quot;section-recap&quot;&gt;Section Recap&lt;/h3&gt;
&lt;p&gt;In this section you met three &lt;code&gt;itertools&lt;/code&gt; functions: &lt;code&gt;combinations()&lt;/code&gt;, &lt;code&gt;combinations_with_replacement()&lt;/code&gt;, and &lt;code&gt;permutations()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s review these functions before moving on:&lt;/p&gt;
&lt;h4 id=&quot;itertoolscombinations-example&quot;&gt;&lt;code&gt;itertools.combinations&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;combinations(iterable, n)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Return successive n-length combinations of elements in the iterable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;combinations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(1, 2), (1, 3), (2, 3)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;itertoolscombinations_with_replacement-example&quot;&gt;&lt;code&gt;itertools.combinations_with_replacement&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;combinations_with_replacement(iterable, n)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Return successive n-length combinations of elements in the iterable allowing individual elements to have successive repeats.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;combinations_with_replacement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(1, 1), (1, 2), (2, 2)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;itertoolspermutations-example&quot;&gt;&lt;code&gt;itertools.permutations&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;permutations(iterable, n=None)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Return successive n-length permutations of elements in the iterable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;permutations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;), (&amp;#39;a&amp;#39;, &amp;#39;c&amp;#39;, &amp;#39;b&amp;#39;), (&amp;#39;b&amp;#39;, &amp;#39;a&amp;#39;, &amp;#39;c&amp;#39;),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(&amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;, &amp;#39;a&amp;#39;), (&amp;#39;c&amp;#39;, &amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;), (&amp;#39;c&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;a&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;sequences-of-numbers&quot;&gt;Sequences of Numbers&lt;/h2&gt;
&lt;p&gt;With &lt;code&gt;itertools&lt;/code&gt;, you can easily generate iterators over infinite sequences. In this section, you will explore numeric sequences, but the tools and techniques seen here are by no means limited to numbers.&lt;/p&gt;
&lt;h3 id=&quot;evens-and-odds&quot;&gt;Evens and Odds&lt;/h3&gt;
&lt;p&gt;For the first example, you will create a pair of iterators over even and odd integers &lt;em&gt;without explicitly doing any arithmetic.&lt;/em&gt; Before diving in, let&amp;rsquo;s look at an arithmetic solution using generators:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;evens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Generate even integers, starting with 0.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evens&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[0, 2, 4, 6, 8]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;odds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Generate odd integers, starting with 1.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;odds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;odds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;odds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 3, 5, 7, 9]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That is pretty straightforward, but with &lt;code&gt;itertools&lt;/code&gt; you can do this much more compactly. The function you need is &lt;code&gt;itertools.count()&lt;/code&gt;, which does exactly what it sounds like: it counts, starting by default with the number 0.&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[0, 1, 2, 3, 4]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can start counting from any number you like by setting the &lt;code&gt;start&lt;/code&gt; keyword argument, which defaults to 0. You can even set a &lt;code&gt;step&lt;/code&gt; keyword argument to determine the interval between numbers returned from &lt;code&gt;count()&lt;/code&gt;&amp;mdash;this defaults to 1.&lt;/p&gt;
&lt;p&gt;With &lt;code&gt;count()&lt;/code&gt;, iterators over even and odd integers become literal one-liners:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evens&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[0, 2, 4, 6, 8]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;odds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;odds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 3, 5, 7, 9]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.python.org/3.1/whatsnew/3.1.html#new-improved-and-deprecated-modules&quot;&gt;Ever since Python 3.1&lt;/a&gt;, the &lt;code&gt;count()&lt;/code&gt; function also accepts non-integer arguments:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count_with_floats&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.75&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count_with_floats&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[0.5, 1.25, 2.0, 2.75, 3.5]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can even pass it negative numbers:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;negative_count&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;negative_count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[-1, -1.5, -2.0, -2.5, -3.0]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In some ways, &lt;code&gt;count()&lt;/code&gt; is similar to the built-in &lt;code&gt;range()&lt;/code&gt; function, but &lt;code&gt;count()&lt;/code&gt; always returns an infinite sequence. You might wonder what good an infinite sequence is since it&amp;rsquo;s impossible to iterate over completely. That is a valid question, and I admit the first time I was introduced to infinite iterators, I too didn&amp;rsquo;t quite see the point.&lt;/p&gt;
&lt;p&gt;The example that made me realize the power of the infinite iterator was the following, which emulates the behavior of the &lt;a href=&quot;https://docs.python.org/3/library/functions.html#enumerate&quot;&gt;built-in &lt;code&gt;enumerate()&lt;/code&gt; function&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(0, &amp;#39;a&amp;#39;), (1, &amp;#39;b&amp;#39;), (2, &amp;#39;c&amp;#39;)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;It is a simple example, but think about it: you just enumerated a list without a &lt;code&gt;for&lt;/code&gt; loop and without knowing the length of the list ahead of time.&lt;/p&gt;
&lt;h3 id=&quot;recurrence-relations&quot;&gt;Recurrence Relations&lt;/h3&gt;
&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Recurrence_relation&quot;&gt;recurrence relation&lt;/a&gt; is a way of describing a sequence of numbers with a recursive formula. One of the best-known recurrence relations is the one that describes the &lt;a href=&quot;https://en.wikipedia.org/wiki/Fibonacci_number&quot;&gt;Fibonacci sequence&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The Fibonacci sequence is the sequence &lt;code&gt;0, 1, 1, 2, 3, 5, 8, 13, ...&lt;/code&gt;. It starts with 0 and 1, and each subsequent number in the sequence is the sum of the previous two. The numbers in this sequence are called the Fibonacci numbers. In mathematical notation, the recurrence relation describing the &lt;em&gt;n&lt;/em&gt;-th Fibonacci number looks like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/fibonacci.cf3bafbe6578.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/fibonacci.cf3bafbe6578.png&quot; width=&quot;1269&quot; height=&quot;73&quot; alt=&quot;Fibonacci Recurrence Relation&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you search Google, you will find a host of implementations of these numbers in Python. You can find a recursive function that produces them in the &lt;a href=&quot;https://realpython.com/python-thinking-recursively/#naive-recursion-is-naive&quot;&gt;Thinking Recursively in Python&lt;/a&gt; article here on Real Python.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It is common to see the Fibonacci sequence produced with a generator:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fibs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;b&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The recurrence relation describing the Fibonacci numbers is called a &lt;em&gt;second order recurrence relation&lt;/em&gt; because, to calculate the next number in the sequence, you need to look back two numbers behind it.&lt;/p&gt;
&lt;p&gt;In general, second order recurrence relations have the form:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/second_order.b210039d7890.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/second_order.b210039d7890.png&quot; width=&quot;926&quot; height=&quot;76&quot; alt=&quot;Second Order Recurrence Relation&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here, &lt;em&gt;P&lt;/em&gt;, &lt;em&gt;Q&lt;/em&gt;, and &lt;em&gt;R&lt;/em&gt; are constants. To generate the sequence, you need two initial values. For the Fibonacci numbers, &lt;em&gt;P&lt;/em&gt; = &lt;em&gt;Q&lt;/em&gt; = 1, &lt;em&gt;R&lt;/em&gt; = 0, and the initial values are 0 and 1.&lt;/p&gt;
&lt;p&gt;As you might guess, a &lt;em&gt;first order recurrence relation&lt;/em&gt; has the following form:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/first_order.fca566e6fd61.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-33&quot; src=&quot;https://files.realpython.com/media/first_order.fca566e6fd61.png&quot; width=&quot;589&quot; height=&quot;76&quot; alt=&quot;First Order Recurrence Relation&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There are countless sequences of numbers that can be described by first and second order recurrence relations. For example, the positive integers can be described as a first order recurrence relation with &lt;em&gt;P&lt;/em&gt; = &lt;em&gt;Q&lt;/em&gt; = 1 and initial value 1. For the even integers, take &lt;em&gt;P&lt;/em&gt; = 1 and &lt;em&gt;Q&lt;/em&gt; = 2 with initial value 0.&lt;/p&gt;
&lt;p&gt;In this section, you will construct functions for producing &lt;em&gt;any&lt;/em&gt; sequence whose values can be described with a first or second order recurrence relation.&lt;/p&gt;
&lt;h4 id=&quot;first-order-recurrence-relations&quot;&gt;First Order Recurrence Relations&lt;/h4&gt;
&lt;p&gt;You&amp;rsquo;ve already seen how &lt;code&gt;count()&lt;/code&gt; can generate the sequence of non-negative integers, the even integers, and the odd integers. You can also use it to generate the sequence &lt;em&gt;3n = 0, 3, 6, 9, 12, &amp;hellip;&lt;/em&gt; and &lt;em&gt;4n = 0, 4, 8, 12, 16, &amp;hellip;&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count_by_three&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;count_by_four&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In fact, &lt;code&gt;count()&lt;/code&gt; can produce sequences of multiples of any number you wish. These sequences can be described with first-order recurrence relations. For example, to generate the sequence of multiples of some number &lt;em&gt;n&lt;/em&gt;, just take &lt;em&gt;P&lt;/em&gt; = 1, &lt;em&gt;Q&lt;/em&gt; = &lt;em&gt;n&lt;/em&gt;, and initial value 0.&lt;/p&gt;
&lt;p&gt;Another easy example of a first-order recurrence relation is the constant sequence &lt;em&gt;n, n, n, n, n&amp;hellip;&lt;/em&gt;, where &lt;em&gt;n&lt;/em&gt; is any value you&amp;rsquo;d like. For this sequence,  set &lt;em&gt;P&lt;/em&gt; = 1 and &lt;em&gt;Q&lt;/em&gt; = 0 with initial value &lt;em&gt;n&lt;/em&gt;. &lt;code&gt;itertools&lt;/code&gt; provides an easy way to implement this sequence as well, with the &lt;code&gt;repeat()&lt;/code&gt; function:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all_ones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 1, 1, 1, 1, ...&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;all_twos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 2, 2, 2, 2, ...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you need a finite sequence of repeated values, you can set a stopping point by passing a positive integer as a second argument:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;five_ones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 1, 1, 1, 1, 1&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;three_fours&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 4, 4, 4&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What may not be quite as obvious is that the sequence &lt;code&gt;1, -1, 1, -1, 1, -1, ...&lt;/code&gt; of alternating 1s and -1s can also be described by a first order recurrence relation. Just take &lt;em&gt;P&lt;/em&gt; = -1, &lt;em&gt;Q&lt;/em&gt; = 0, and initial value 1.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s an easy way to generate this sequence with the &lt;code&gt;itertools.cycle()&lt;/code&gt; function. This function takes an iterable &lt;code&gt;inputs&lt;/code&gt; as an argument and returns an infinite iterator over the values in &lt;code&gt;inputs&lt;/code&gt; that returns to the beginning once the end of &lt;code&gt;inputs&lt;/code&gt; is reached. So, to produce the alternating sequence of 1s and -1s, you could do this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alternating_ones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cycle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 1, -1, 1, -1, 1, -1, ...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The goal of this section, though, is to produce a single function that can generate &lt;em&gt;any&lt;/em&gt; first order recurrence relation&amp;mdash;just pass it &lt;em&gt;P&lt;/em&gt;, &lt;em&gt;Q&lt;/em&gt;, and an initial value. One way to do this is with &lt;code&gt;itertools.accumulate()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;accumulate()&lt;/code&gt; function takes two arguments&amp;mdash;an iterable &lt;code&gt;inputs&lt;/code&gt; and a &lt;strong&gt;binary function&lt;/strong&gt; &lt;code&gt;func&lt;/code&gt; (that is, a function with exactly two inputs)&amp;mdash;and returns an iterator over accumulated results of applying &lt;code&gt;func&lt;/code&gt; to elements of &lt;code&gt;inputs&lt;/code&gt;. It is roughly equivalent to the following generator:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;itr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;itr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cur&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cur&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;For example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;operator&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 3, 6, 10, 15]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The first value in the iterator returned by &lt;code&gt;accumulate()&lt;/code&gt; is always the first value in the input sequence. In the above example, this is 1&amp;mdash;the first value in &lt;code&gt;[1, 2, 3, 4, 5]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The next value in the output iterator is the sum of the first two elements of the input sequence: &lt;code&gt;add(1, 2) = 3&lt;/code&gt;. To produce the next value, &lt;code&gt;accumulate()&lt;/code&gt; takes the result of &lt;code&gt;add(1, 2)&lt;/code&gt; and adds this to the third value in the input sequence:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;add(3, 3) = add(add(1, 2), 3) = 6
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The fourth value produced by &lt;code&gt;accumulate()&lt;/code&gt; is &lt;code&gt;add(add(add(1, 2), 3), 4) = 10&lt;/code&gt;, and so on.&lt;/p&gt;
&lt;p&gt;The second argument of &lt;code&gt;accumulate()&lt;/code&gt; defaults to &lt;code&gt;operator.add()&lt;/code&gt;, so the previous example can be simplified to:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 3, 6, 10, 15]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Passing the built-in &lt;code&gt;min()&lt;/code&gt; to &lt;code&gt;accumulate()&lt;/code&gt; will keep track of a running minimum:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[9, 9, 9, 5, 5, 5, 2, 2]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;More complex functions can be passed to &lt;code&gt;accumulate()&lt;/code&gt; with &lt;code&gt;lambda&lt;/code&gt; expressions:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 1.5, 2.25, 3.125, 4.0625]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The order of the arguments in the binary function passed to &lt;code&gt;accumulate()&lt;/code&gt; is important. The first argument is always the previously accumulated result and the second argument is always the next element of the input iterable. For example, consider the difference in output of the following expressions:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, -1, -4, -8, -13]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 1, 2, 2, 3]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To model a recurrence relation, you can just ignore the second argument of the binary function passed to &lt;code&gt;accumulate()&lt;/code&gt;. That is, given values &lt;code&gt;p&lt;/code&gt;, &lt;code&gt;q&lt;/code&gt;, and &lt;code&gt;s&lt;/code&gt;, &lt;code&gt;lambda x, _: p*s + q&lt;/code&gt; will return the value following &lt;code&gt;x&lt;/code&gt; in the recurrence relation defined by &lt;em&gt;sᵢ&lt;/em&gt; = &lt;em&gt;Psᵢ₋₁&lt;/em&gt; + &lt;em&gt;Q&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;In order for &lt;code&gt;accumulate()&lt;/code&gt; to iterate over the resulting recurrence relation, you need to pass to it an infinite sequence with the right initial value. It doesn&amp;rsquo;t matter what the rest of the values in the sequence are, as long as the initial value is the initial value of the recurrence relation. You can do this is with &lt;code&gt;repeat()&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;first_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Return sequence defined by s(n) = p * s(n-1) + q.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initial_val&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Using &lt;code&gt;first_order()&lt;/code&gt;, you can build the sequences from above as follows:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evens&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evens&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;odds&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;odds&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count_by_threes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count_by_threes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count_by_fours&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count_by_fours&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;all_ones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all_ones&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;all_twos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;all_twos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alternating_ones&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;first_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_val&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alternating_ones&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;second-order-recurrence-relations&quot;&gt;Second Order Recurrence Relations&lt;/h4&gt;
&lt;p&gt;Generating sequences described by second order recurrence relations, like the Fibonacci sequence, can be accomplished using a similar technique as the one used for first order recurrence relations.&lt;/p&gt;
&lt;p&gt;The difference here is that you need to create an intermediate sequence of tuples that keep track of the previous two elements of the sequence, and then &lt;code&gt;map()&lt;/code&gt; each of these tuples to their first component to get the final sequence.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s what it looks like:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;second_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Return sequence defined by s(n) = p * s(n-1) + q * s(n-2) + r.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;intermediate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initial_values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;intermediate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Using &lt;code&gt;second_order()&lt;/code&gt;, you can generate the Fibonacci sequence like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fibs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;second_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fibs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Other sequences can be easily generated by changing the values of &lt;code&gt;p&lt;/code&gt;, &lt;code&gt;q&lt;/code&gt;, and &lt;code&gt;r&lt;/code&gt;. For example, the &lt;a href=&quot;https://en.wikipedia.org/wiki/Pell_number&quot;&gt;Pell numbers&lt;/a&gt; and the &lt;a href=&quot;https://en.wikipedia.org/wiki/Lucas_number&quot;&gt;Lucas numbers&lt;/a&gt; can be generated as follows:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pell&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;second_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;29&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lucas&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;second_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lucas&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can even generate the alternating Fibonacci numbers:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alt_fibs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;second_order&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;q&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_values&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alt_fibs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is all really cool if you are a giant math nerd like I am, but step back for a second and compare &lt;code&gt;second_order()&lt;/code&gt; to the &lt;code&gt;fibs()&lt;/code&gt; generator from the beginning of this section. Which one is easier to understand?&lt;/p&gt;
&lt;p&gt;This is a valuable lesson. The &lt;code&gt;accumulate()&lt;/code&gt; function is a powerful tool to have in your toolkit, but there are times when using it could mean sacrificing clarity and readability.&lt;/p&gt;
&lt;h3 id=&quot;section-recap_1&quot;&gt;Section Recap&lt;/h3&gt;
&lt;p&gt;You saw several &lt;code&gt;itertools&lt;/code&gt; function in this section. Let&amp;rsquo;s review those now.&lt;/p&gt;
&lt;h4 id=&quot;itertoolscount-example&quot;&gt;&lt;code&gt;itertools.count&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;count(start=0, step=1)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Return a count object whose .&lt;code&gt;__next__()&lt;/code&gt; method returns consecutive values.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0, 1, 2, 3, 4, ...&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;step&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1, 3, 5, 7, 9, ...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;itertoolsrepeat-example&quot;&gt;&lt;code&gt;itertools.repeat&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;repeat(object, times=1)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Create an iterator which returns the object for the specified number of times. If not specified, returns the object endlessly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2, 2, 2, 2, 2 ...&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Stops after 5 repititions.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2, 2, 2, 2, 2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;itertoolscycle-example&quot;&gt;&lt;code&gt;itertools.cycle&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;cycle(iterable)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Return elements from the iterable until it is exhausted. Then repeat the sequence indefinitely.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cycle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;a, b, c, a, b, c, a, ...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;itertools-accumulate-example&quot;&gt;&lt;code&gt;itertools accumulate&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;accumulate(iterable, func=operator.add)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Return series of accumulated sums (or other binary function results).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;accumulate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1, 3, 6&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Alright, let&amp;rsquo;s take a break from the math and have some fun with cards.&lt;/p&gt;
&lt;h2 id=&quot;dealing-a-deck-of-cards&quot;&gt;Dealing a Deck of Cards&lt;/h2&gt;
&lt;p&gt;Suppose you are building a Poker app. You&amp;rsquo;ll need a deck of cards. You might start by defining a list of ranks (ace, king, queen, jack, 10, 9, and so on) and a list of suits (hearts, diamonds, clubs, and spades):&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ranks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;K&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Q&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;J&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;10&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;9&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;8&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;7&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;6&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;5&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;4&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;3&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;2&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;suits&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;H&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;D&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;C&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;S&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You could represent a card as a tuple whose first element is a rank and second element is a suit. A deck of cards would be a collection of such tuples. The deck should act like the real thing, so it makes sense to define a generator that yields cards one at a time and becomes exhausted once all the cards are dealt.&lt;/p&gt;
&lt;p&gt;One way to achieve this is to write a generator with a nested &lt;code&gt;for&lt;/code&gt; loop over &lt;code&gt;ranks&lt;/code&gt; and &lt;code&gt;suits&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cards&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Return a generator that yields playing cards.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rank&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ranks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;suit&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;suits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;suit&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You could write this more compactly with a generator expression:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cards&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;suit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rank&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ranks&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;suit&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;suits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;However, some might argue that this is actually more difficult to understand than the more explicit nested &lt;code&gt;for&lt;/code&gt; loop.&lt;/p&gt;
&lt;p&gt;It helps to view nested &lt;code&gt;for&lt;/code&gt; loops from a mathematical standpoint&amp;mdash;that is, as a &lt;a href=&quot;https://en.wikipedia.org/wiki/Cartesian_product&quot;&gt;Cartesian product&lt;/a&gt; of two or more iterables. In mathematics, the Cartesian product of two sets &lt;em&gt;A&lt;/em&gt; and &lt;em&gt;B&lt;/em&gt; is the set of all tuples of the form &lt;em&gt;(a, b)&lt;/em&gt; where &lt;em&gt;a&lt;/em&gt; is an element of &lt;em&gt;A&lt;/em&gt; and &lt;em&gt;b&lt;/em&gt; is an element of &lt;em&gt;B&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example with Python iterables: the Cartesian product of &lt;code&gt;A = [1, 2]&lt;/code&gt; and &lt;code&gt;B = [&#39;a&#39;, &#39;b&#39;]&lt;/code&gt; is &lt;code&gt;[(1, &#39;a&#39;), (1, &#39;b&#39;), (2, &#39;a&#39;), (2, &#39;b&#39;)]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;itertools.product()&lt;/code&gt; function is for exactly this situation. It takes any number of iterables as arguments and returns an iterator over tuples in the Cartesian product:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# (1, &amp;#39;a&amp;#39;), (1, &amp;#39;b&amp;#39;), (2, &amp;#39;a&amp;#39;), (2, &amp;#39;b&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;product()&lt;/code&gt; function is by no means limited to two iterables. You can pass it as many as you like&amp;mdash;they don&amp;rsquo;t even have to all be of the same size! See if you can predict what &lt;code&gt;product([1, 2, 3], [&#39;a&#39;, &#39;b&#39;], [&#39;c&#39;])&lt;/code&gt; is, then check your work by running it in the interpreter.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt; The &lt;code&gt;product()&lt;/code&gt; function is another &amp;ldquo;brute force&amp;rdquo; function and can lead to a combinatorial explosion if you aren&amp;rsquo;t careful.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Using &lt;code&gt;product()&lt;/code&gt;, you can re-write the &lt;code&gt;cards&lt;/code&gt; in a single line:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cards&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ranks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;suits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is all fine and dandy, but any Poker app worth its salt better start with a shuffled deck:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;random&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Return iterator over shuffled deck.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;cards&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shuffle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cards&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The &lt;code&gt;random.shuffle()&lt;/code&gt; function uses the &lt;a href=&quot;https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle&quot;&gt;Fisher-Yates shuffle&lt;/a&gt; to shuffle a list (or any mutable sequence) in place &lt;a href=&quot;https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_modern_algorithm&quot;&gt;in &lt;em&gt;O(n)&lt;/em&gt; time&lt;/a&gt;. This algorithm is well-suited for shuffling &lt;code&gt;cards&lt;/code&gt; because it produces an unbiased permutation&amp;mdash;that is, all permutations of the iterable are equally likely to be returned by &lt;code&gt;random.shuffle()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That said, you probably noticed that &lt;code&gt;shuffle()&lt;/code&gt; creates a copy of its input &lt;code&gt;deck&lt;/code&gt; in memory by calling &lt;code&gt;list(deck)&lt;/code&gt;. While this seemingly goes against the spirit of this article, this author is unaware of a good way to shuffle an iterator without making a copy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As a courtesy to your users, you would like to give them the opportunity to cut the deck. If you imagine the cards being stacked neatly on a table, you have the user pick a number &lt;em&gt;n&lt;/em&gt; and then remove the first &lt;em&gt;n&lt;/em&gt; cards from the top of the stack and move them to the bottom.&lt;/p&gt;
&lt;p&gt;If you know a thing or two about &lt;a href=&quot;https://stackoverflow.com/questions/509211/understanding-pythons-slice-notation&quot;&gt;slicing&lt;/a&gt;, you might accomplish this like so:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Return an iterator over a deck of cards cut at index `n`.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ValueError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;`n` must be a non-negative integer&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;cards&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cards&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Cut the deck in half.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;cut()&lt;/code&gt; function first converts &lt;code&gt;deck&lt;/code&gt; to a list so that you can slice it to make the cut. To guarantee your slices behave as expected, you&amp;rsquo;ve got to check that &lt;code&gt;n&lt;/code&gt; is non-negative. If it isn&amp;rsquo;t, you better throw an exception so that nothing crazy happens.&lt;/p&gt;
&lt;p&gt;Cutting the deck is pretty straightforward: the top of the cut deck is just &lt;code&gt;deck[:n]&lt;/code&gt;, and the bottom is the remaining cards, or &lt;code&gt;deck[n:]&lt;/code&gt;. To construct the new deck with the top &amp;ldquo;half&amp;rdquo; moved to the bottom, you just append it to the bottom: &lt;code&gt;deck[n:] + deck[:n]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;cut()&lt;/code&gt; function is pretty simple, but it suffers from a couple of problems. When you slice a list, you make a copy of the original list and return a new list with the selected elements. With a deck of only 52 cards, this increase in space complexity is trivial, but you could reduce the memory overhead using &lt;code&gt;itertools&lt;/code&gt;. To do this, you&amp;rsquo;ll need three functions: &lt;code&gt;itertools.tee()&lt;/code&gt;, &lt;code&gt;itertools.islice()&lt;/code&gt;, and &lt;code&gt;itertools.chain()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s take a look at how those functions work.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;tee()&lt;/code&gt; function can be used to create any number of independent iterators from a single iterable. It takes two arguments: the first is an iterable &lt;code&gt;inputs&lt;/code&gt;, and the second is the number &lt;code&gt;n&lt;/code&gt; of independent iterators over &lt;code&gt;inputs&lt;/code&gt; to return (by default, &lt;code&gt;n&lt;/code&gt; is set to 2). The iterators are returned in a tuple of length &lt;code&gt;n&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iterator2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 2, 3, 4, 5]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# iterator1 is now exhausted.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterator2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# iterator2 works independently of iterator1&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 2, 3, 4, 5].&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;While &lt;code&gt;tee()&lt;/code&gt; is useful for creating independent iterators, it is important to understand a little bit about how it works under the hood. When you call &lt;code&gt;tee()&lt;/code&gt; to create &lt;em&gt;n&lt;/em&gt; independent iterators, each iterator is essentially working with its own FIFO queue.&lt;/p&gt;
&lt;p&gt;When a value is extracted from one iterator, that value is appended to the queues for the other iterators. Thus, if one iterator is exhausted before the others, each remaining iterator will hold a copy of the entire iterable in memory. (You can find a Python function that emulates &lt;code&gt;tee()&lt;/code&gt; in the &lt;code&gt;itertools&lt;/code&gt; &lt;a href=&quot;https://docs.python.org/3/library/itertools.html#itertools.tee&quot;&gt;docs&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;For this reason, &lt;code&gt;tee()&lt;/code&gt; should be used with care. If you are exhausting large portions of an iterator before working with the other returned by &lt;code&gt;tee()&lt;/code&gt;, you may be better off casting the input iterator to a &lt;code&gt;list&lt;/code&gt; or &lt;code&gt;tuple&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;islice()&lt;/code&gt; function works much the same way as slicing a list or tuple. You pass it an iterable, a starting, and stopping point, and, just like slicing a list, the slice returned stops at the index just before the stopping point. You can optionally include a step value, as well. The biggest difference here is, of course, that &lt;code&gt;islice()&lt;/code&gt; returns an iterator.&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Slice from index 2 to 4&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ABCDEFG&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;C&amp;#39; &amp;#39;D&amp;#39; &amp;#39;E&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Slice from beginning to index 4, in steps of 2&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 3, 5]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Slice from index 3 to the end&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[3, 4, 5, 6, 7, 8, 9]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# Slice from beginning to index 3&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ABCDE&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;A&amp;#39;, &amp;#39;B&amp;#39;, &amp;#39;C&amp;#39;, &amp;#39;D&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The last two examples above are useful for truncating iterables. You can use this to replace the list slicing used in &lt;code&gt;cut()&lt;/code&gt; to select the &amp;ldquo;top&amp;rdquo; and &amp;ldquo;bottom&amp;rdquo; of the deck. As an added bonus, &lt;code&gt;islice()&lt;/code&gt; won&amp;rsquo;t accept negative indices for the start/stop positions and the step value, so you won&amp;rsquo;t need to raise an exception if &lt;code&gt;n&lt;/code&gt; is negative.&lt;/p&gt;
&lt;p&gt;The last function you need is &lt;code&gt;chain()&lt;/code&gt;. This function takes any number of iterables as arguments and &amp;ldquo;chains&amp;rdquo; them together. For example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;ABC&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;DEF&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;A&amp;#39; &amp;#39;B&amp;#39; &amp;#39;C&amp;#39; &amp;#39;D&amp;#39; &amp;#39;E&amp;#39; &amp;#39;F&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 2, 3, 4, 5, 6, 7, 8, 9]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that you&amp;rsquo;ve got some additional firepower in your arsenal, you can re-write the &lt;code&gt;cut()&lt;/code&gt; function to cut the deck of cards without making a full copy &lt;code&gt;cards&lt;/code&gt; in memory:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Return an iterator over a deck of cards cut at index `n`.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;deck1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deck2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;top&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bottom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;cards&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cards&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that you have shuffled and cut the cards, it is time to deal some hands. You could write a function &lt;code&gt;deal()&lt;/code&gt; that takes a deck, the number of hands, and the hand size as arguments and returns a tuple containing the specified number of hands.&lt;/p&gt;
&lt;p&gt;You do not need any new &lt;code&gt;itertools&lt;/code&gt; functions to write this function. See what you can come up with on your own before reading ahead.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s one solution:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;deal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_hands&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hand_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deck&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hand_size&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;itr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_hands&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itr&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You start by creating a list of &lt;code&gt;hand_size&lt;/code&gt; references to an iterator over &lt;code&gt;deck&lt;/code&gt;. You then iterate over this list, removing &lt;code&gt;num_hands&lt;/code&gt; cards at each step and storing them in tuples.&lt;/p&gt;
&lt;p&gt;Next, you &lt;code&gt;zip()&lt;/code&gt; these tuples up to emulate dealing one card at a time to each player. This produces &lt;code&gt;num_hands&lt;/code&gt; tuples, each containing &lt;code&gt;hand_size&lt;/code&gt; cards. Finally, you package the hands up into a tuple to return them all at once.&lt;/p&gt;
&lt;p&gt;This implementation sets the default values for &lt;code&gt;num_hands&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt; and &lt;code&gt;hand_size&lt;/code&gt; to &lt;code&gt;5&lt;/code&gt;&amp;mdash;maybe you are making a &amp;ldquo;Five Card Draw&amp;rdquo; app. Here&amp;rsquo;s how you would use this function, with some sample output:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p1_hand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p2_hand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p3_hand&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cards&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num_hands&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p1_hand&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;((&amp;#39;A&amp;#39;, &amp;#39;S&amp;#39;), (&amp;#39;5&amp;#39;, &amp;#39;S&amp;#39;), (&amp;#39;7&amp;#39;, &amp;#39;H&amp;#39;), (&amp;#39;9&amp;#39;, &amp;#39;H&amp;#39;), (&amp;#39;5&amp;#39;, &amp;#39;H&amp;#39;))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p2_hand&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;((&amp;#39;10&amp;#39;, &amp;#39;H&amp;#39;), (&amp;#39;2&amp;#39;, &amp;#39;D&amp;#39;), (&amp;#39;2&amp;#39;, &amp;#39;S&amp;#39;), (&amp;#39;J&amp;#39;, &amp;#39;C&amp;#39;), (&amp;#39;9&amp;#39;, &amp;#39;C&amp;#39;))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;p3_hand&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;((&amp;#39;2&amp;#39;, &amp;#39;C&amp;#39;), (&amp;#39;Q&amp;#39;, &amp;#39;S&amp;#39;), (&amp;#39;6&amp;#39;, &amp;#39;C&amp;#39;), (&amp;#39;Q&amp;#39;, &amp;#39;H&amp;#39;), (&amp;#39;A&amp;#39;, &amp;#39;C&amp;#39;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What do you think the state of &lt;code&gt;cards&lt;/code&gt; is now that you have dealt three hands of five cards?&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cards&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;37&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The fifteen cards dealt are consumed from the &lt;code&gt;cards&lt;/code&gt; iterator, which is exactly what you want. That way, as the game continues, the state of the &lt;code&gt;cards&lt;/code&gt; iterator reflects the state of the deck in play.&lt;/p&gt;
&lt;h3 id=&quot;section-recap_2&quot;&gt;Section Recap&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s review the &lt;code&gt;itertools&lt;/code&gt; functions you saw in this section.&lt;/p&gt;
&lt;h4 id=&quot;itertoolsproduct-example&quot;&gt;&lt;code&gt;itertools.product&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;product(*iterables, repeat=1)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Cartesian product of input iterables. Equivalent to nested for-loops.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(1, &amp;#39;a&amp;#39;), (1, &amp;#39;b&amp;#39;), (2, &amp;#39;a&amp;#39;), (2, &amp;#39;b&amp;#39;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;itertoolstee-example&quot;&gt;&lt;code&gt;itertools.tee&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;tee(iterable, n=2)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Create any number of independent iterators from a single input iterable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;iter2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;itertoolsislice-example&quot;&gt;&lt;code&gt;itertools.islice&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;islice(iterable, stop)&lt;/code&gt;
&lt;code&gt;islice(iterable, start, stop, step=1)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Return an iterator whose &lt;code&gt;__next__()&lt;/code&gt; method returns selected values from an iterable. Works like a &lt;code&gt;slice()&lt;/code&gt; on a list but returns an iterator.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1, 2, 3&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2, 3&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;itertoolschain-example&quot;&gt;&lt;code&gt;itertools.chain&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;chain(*iterables)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Return a chain object whose &lt;code&gt;__next__()&lt;/code&gt; method returns elements from the first iterable until it is exhausted, then elements from the next iterable, until all of the iterables are exhausted.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;#39;a&amp;#39;, &amp;#39;b&amp;#39;, &amp;#39;c&amp;#39;, 1, 2, 3&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;intermission-flattening-a-list-of-lists&quot;&gt;Intermission: Flattening A List of Lists&lt;/h2&gt;
&lt;p&gt;In the previous example, you used &lt;code&gt;chain()&lt;/code&gt; to tack one iterator onto the end of another. The &lt;code&gt;chain()&lt;/code&gt; function has a class method &lt;code&gt;.from_iterable()&lt;/code&gt; that takes a single iterable as an argument. The elements of the iterable must themselves be iterable, so the net effect is that &lt;code&gt;chain.from_iterable()&lt;/code&gt; flattens its argument:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_iterable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[1, 2, 3, 4, 5, 6]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;There&amp;rsquo;s no reason the argument of &lt;code&gt;chain.from_iterable()&lt;/code&gt; needs to be finite. You could emulate the behavior of &lt;code&gt;cycle()&lt;/code&gt;, for example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cycle&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;from_iterable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;abc&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cycle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;chain.from_interable()&lt;/code&gt; function is useful when you need to build an iterator over data that has been &amp;ldquo;chunked.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;In the next section, you will see how to use &lt;code&gt;itertools&lt;/code&gt; to do some data analysis on a large dataset. But you deserve a break for having stuck with it this far. Why not hydrate yourself and relax a bit? Maybe even play a little &lt;a href=&quot;https://archive.org/details/Trek-nTheNthIteration&quot;&gt;Star Trek: The Nth Iteration&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Back? Great! Let&amp;rsquo;s do some data analysis.&lt;/p&gt;
&lt;h2 id=&quot;analyzing-the-sp500&quot;&gt;Analyzing the S&amp;amp;P500&lt;/h2&gt;
&lt;p&gt;In this example, you will get your first taste of using &lt;code&gt;itertools&lt;/code&gt; to manipulate a large dataset&amp;mdash;in particular, the historical daily price data of the S&amp;amp;P500 index. A CSV file &lt;code&gt;SP500.csv&lt;/code&gt; with this data can be found &lt;a href=&quot;https://github.com/realpython/materials/tree/master/itertools-in-python3&quot;&gt;here&lt;/a&gt; (source: &lt;a href=&quot;https://finance.yahoo.com/quote/%5EGSPC?p=^GSPC&quot;&gt;Yahoo Finance&lt;/a&gt;). The problem you&amp;rsquo;ll tackle is this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Determine the maximum daily gain, daily loss (in percent change), and the longest growth streak in the history of the S&amp;amp;P500.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;To get a feel for what you&amp;rsquo;re dealing with, here are the first ten rows of &lt;code&gt;SP500.csv&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; head -n &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt; SP500.csv
&lt;span class=&quot;go&quot;&gt;Date,Open,High,Low,Close,Adj Close,Volume&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1950-01-03,16.660000,16.660000,16.660000,16.660000,16.660000,1260000&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1950-01-04,16.850000,16.850000,16.850000,16.850000,16.850000,1890000&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1950-01-05,16.930000,16.930000,16.930000,16.930000,16.930000,2550000&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1950-01-06,16.980000,16.980000,16.980000,16.980000,16.980000,2010000&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1950-01-09,17.080000,17.080000,17.080000,17.080000,17.080000,2520000&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1950-01-10,17.030001,17.030001,17.030001,17.030001,17.030001,2160000&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1950-01-11,17.090000,17.090000,17.090000,17.090000,17.090000,2630000&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1950-01-12,16.760000,16.760000,16.760000,16.760000,16.760000,2970000&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1950-01-13,16.670000,16.670000,16.670000,16.670000,16.670000,3330000&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As you can see, the early data is limited. The data improves for later dates, and, as a whole, is sufficient for this example.&lt;/p&gt;
&lt;p&gt;The strategy for solving this problem is as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Read data from the CSV file and transform it into a sequence &lt;code&gt;gains&lt;/code&gt; of daily percent changes using the &amp;ldquo;Adj Close&amp;rdquo; column.&lt;/li&gt;
&lt;li&gt;Find the maximum and minimum values of the &lt;code&gt;gains&lt;/code&gt; sequence, and the date on which they occur. (Note that it is possible that these values are attained on more than on date; in that case, the most recent date will suffice.)&lt;/li&gt;
&lt;li&gt;Transform &lt;code&gt;gains&lt;/code&gt; into a sequence &lt;code&gt;growth_streaks&lt;/code&gt; of tuples of consecutive positive values in &lt;code&gt;gains&lt;/code&gt;. Then determine the length of the longest tuple in &lt;code&gt;growth_streaks&lt;/code&gt; and the beginning and ending dates of the streak. (It is possible that the maximum length is attained by more than one tuple in &lt;code&gt;growth_streaks&lt;/code&gt;; in that case, the tuple with the most recent beginning and ending dates will suffice.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;em&gt;percent change&lt;/em&gt; between two values &lt;em&gt;x&lt;/em&gt; and &lt;em&gt;y&lt;/em&gt; is given by the following formula:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/percent_change.3c81a67b1906.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/percent_change.3c81a67b1906.png&quot; width=&quot;1097&quot; height=&quot;200&quot; alt=&quot;Percent Change Formula&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For each step in the analysis, it is necessary to compare values associated with dates. To facilitate these comparisons, you can subclass the &lt;a href=&quot;https://docs.python.org/3/library/collections.html#collections.namedtuple&quot;&gt;&lt;code&gt;namedtuple&lt;/code&gt; object&lt;/a&gt; from the &lt;a href=&quot;https://docs.python.org/3/library/collections.html&quot;&gt;&lt;code&gt;collections&lt;/code&gt; module&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;collections&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;namedtuple&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DataPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;namedtuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;DataPoint&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;date&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])):&lt;/span&gt;
    &lt;span class=&quot;vm&quot;&gt;__slots__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__le__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__lt__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__gt__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;DataPoint&lt;/code&gt; class has two attributes: &lt;code&gt;date&lt;/code&gt; (a &lt;a href=&quot;https://docs.python.org/3/library/datetime.html#datetime.datetime&quot;&gt;&lt;code&gt;datetime.datetime&lt;/code&gt;&lt;/a&gt; instance) and &lt;code&gt;value&lt;/code&gt;. The &lt;a href=&quot;https://docs.python.org/3/reference/datamodel.html#object.__le__&quot;&gt;&lt;code&gt;.__le__()&lt;/code&gt;&lt;/a&gt;,  &lt;a href=&quot;https://docs.python.org/3/reference/datamodel.html#object.__lt__&quot;&gt;&lt;code&gt;.__lt__()&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://docs.python.org/3/reference/datamodel.html#object.__gt__&quot;&gt;&lt;code&gt;.__gt__()&lt;/code&gt;&lt;/a&gt; &lt;a href=&quot;https://realpython.com/operator-function-overloading/&quot;&gt;dunder methods&lt;/a&gt; are implemented so that the &lt;code&gt;&amp;lt;=&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, and &lt;code&gt;&amp;gt;&lt;/code&gt; boolean comparators can be used to compare the values of two &lt;code&gt;DataPoint&lt;/code&gt; objects. This also allows the  &lt;a href=&quot;https://docs.python.org/3/library/functions.html#max&quot;&gt;&lt;code&gt;max()&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://docs.python.org/3/library/functions.html#min&quot;&gt;&lt;code&gt;min()&lt;/code&gt;&lt;/a&gt; built-in functions to be called with &lt;code&gt;DataPoint&lt;/code&gt; arguments.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you are not familiar with &lt;a href=&quot;https://docs.python.org/3/library/collections.html#collections.namedtuple&quot;&gt;&lt;code&gt;namedtuple&lt;/code&gt;&lt;/a&gt;, check out &lt;a href=&quot;https://dbader.org/blog/writing-clean-python-with-namedtuples&quot;&gt;this excellent resource&lt;/a&gt;.  The &lt;code&gt;namedtuple&lt;/code&gt; implementation for &lt;code&gt;DataPoint&lt;/code&gt; is just one of many ways to build this data structure. For example, in Python 3.7 you could implement &lt;code&gt;DataPoint&lt;/code&gt; as a data class. Check out our &lt;a href=&quot;https://realpython.com/python-data-classes/&quot;&gt;Ultimate Guide to Data Classes&lt;/a&gt; for more information.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The following reads the data from &lt;code&gt;SP500.csv&lt;/code&gt; to a tuple of &lt;code&gt;DataPoint&lt;/code&gt; objects:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;csv&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;read_prices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csvfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_strptime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strptime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csvfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;infile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DictReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;infile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_strptime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Date&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;%Y-%m-&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Adj Close&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;prices&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_prices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;SP500.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;read_prices()&lt;/code&gt; generator opens &lt;code&gt;SP500.csv&lt;/code&gt; and reads each row with a &lt;a href=&quot;https://docs.python.org/3/library/csv.html#csv.DictWriter&quot;&gt;&lt;code&gt;csv.DictReader()&lt;/code&gt;&lt;/a&gt; object. &lt;code&gt;DictReader()&lt;/code&gt; returns each row as an &lt;a href=&quot;https://docs.python.org/3/library/collections.html#collections.OrderedDict&quot;&gt;&lt;code&gt;OrderedDict&lt;/code&gt;&lt;/a&gt; whose keys are the column names from the header row of the CSV file.&lt;/p&gt;
&lt;p&gt;For each row, &lt;code&gt;read_prices()&lt;/code&gt; yields a &lt;code&gt;DataPoint&lt;/code&gt; object containing the values in the &amp;ldquo;Date&amp;rdquo; and &amp;ldquo;Adj Close&amp;rdquo; columns. Finally, the full sequence of data points is committed to memory as a &lt;code&gt;tuple&lt;/code&gt; and stored in the &lt;code&gt;prices&lt;/code&gt; variable.&lt;/p&gt;
&lt;p&gt;Next, &lt;code&gt;prices&lt;/code&gt; needs to be transformed to a sequence of daily percent changes:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gains&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prev_day&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev_day&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The choice of storing the data in a &lt;code&gt;tuple&lt;/code&gt; is intentional. Although you could point &lt;code&gt;gains&lt;/code&gt; to an iterator, you will need to iterate over the data twice to find the minimum and maximum values.&lt;/p&gt;
&lt;p&gt;If you use &lt;code&gt;tee()&lt;/code&gt; to create two independent iterators, exhausting one iterator to find the maximum will create a copy of all of the data in memory for the second iterator. By creating a &lt;code&gt;tuple&lt;/code&gt; up front, you do not lose anything in terms of space complexity compared to &lt;code&gt;tee()&lt;/code&gt;, and you may even gain a little speed.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This example focuses on leveraging &lt;code&gt;itertools&lt;/code&gt; for analyzing the S&amp;amp;P500 data. Those intent on working with a lot of time series financial data might also want to check out the &lt;a href=&quot;https://pandas.pydata.org/&quot;&gt;Pandas&lt;/a&gt; library, which is well suited for such tasks.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;maximum-gain-and-loss&quot;&gt;Maximum Gain and Loss&lt;/h3&gt;
&lt;p&gt;To determine the maximum gain on any single day, you might do something like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_gain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data_point&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;max_gain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data_point&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;max_gain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_gain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;c1&quot;&gt;# DataPoint(date=&amp;#39;2008-10-28&amp;#39;, value=11.58)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can simplify the &lt;code&gt;for&lt;/code&gt; loop using the &lt;a href=&quot;https://docs.python.org/3/library/functools.html#functools.reduce&quot;&gt;&lt;code&gt;functools.reduce()&lt;/code&gt; function&lt;/a&gt;. This function accepts a binary function &lt;code&gt;func&lt;/code&gt; and an iterable &lt;code&gt;inputs&lt;/code&gt; as arguments, and &amp;ldquo;reduces&amp;rdquo; &lt;code&gt;inputs&lt;/code&gt; to a single value by applying &lt;code&gt;func&lt;/code&gt; cumulatively to pairs of objects in the iterable.&lt;/p&gt;
&lt;p&gt;For example, &lt;code&gt;functools.reduce(operator.add, [1, 2, 3, 4, 5])&lt;/code&gt; will return the sum &lt;code&gt;1 + 2 + 3 + 4 + 5 = 15&lt;/code&gt;. You can think of &lt;code&gt;reduce()&lt;/code&gt; as working in much the same way as &lt;code&gt;accumulate()&lt;/code&gt;, except that it returns only the final value in the new sequence.&lt;/p&gt;
&lt;p&gt;Using &lt;code&gt;reduce()&lt;/code&gt;, you can get rid of the &lt;code&gt;for&lt;/code&gt; loop altogether in the above example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;functools&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ft&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;max_gain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ft&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_gain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# DataPoint(date=&amp;#39;2008-10-28&amp;#39;, value=11.58)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The above solution works, but it isn&amp;rsquo;t equivalent to the &lt;code&gt;for&lt;/code&gt; loop you had before. Do you see why? Suppose the data in your CSV file recorded a loss every single day. What would the value of &lt;code&gt;max_gain&lt;/code&gt; be?&lt;/p&gt;
&lt;p&gt;In the &lt;code&gt;for&lt;/code&gt; loop, you first set &lt;code&gt;max_gain = DataPoint(None, 0)&lt;/code&gt;, so if there are no gains, the final &lt;code&gt;max_gain&lt;/code&gt; value will be this empty &lt;code&gt;DataPoint&lt;/code&gt; object. However, the &lt;code&gt;reduce()&lt;/code&gt; solution returns the smallest loss. That is not what you want and could introduce a difficult to find bug.&lt;/p&gt;
&lt;p&gt;This is where &lt;code&gt;itertools&lt;/code&gt; can help you out. The &lt;code&gt;itertools.filterfalse()&lt;/code&gt; function takes two arguments: a function that returns &lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False&lt;/code&gt; (called a &lt;strong&gt;predicate&lt;/strong&gt;), and an iterable &lt;code&gt;inputs&lt;/code&gt;. It returns an iterator over the elements in &lt;code&gt;inputs&lt;/code&gt; for which the predicate returns &lt;code&gt;False&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a simple example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;only_positives&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filterfalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;only_positives&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can use &lt;code&gt;filterfalse()&lt;/code&gt; to filter out the values in &lt;code&gt;gains&lt;/code&gt; that are negative or zero so that &lt;code&gt;reduce()&lt;/code&gt; only works on positive values:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_gain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ft&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filterfalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;What happens if there are never any gains? Consider the following:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&amp;gt;&amp;gt; ft.reduce(max, it.filterfalse(lambda x: x &amp;lt;= 0, [-1, -2, -3]))&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;reduce() of empty sequence with no initial value&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Well, that&amp;rsquo;s not what you want! But, it makes sense because the iterator returned by &lt;code&gt;filterflase()&lt;/code&gt; is empty. You could handle the &lt;code&gt;TypeError&lt;/code&gt; by wrapping the call to &lt;code&gt;reduce()&lt;/code&gt; with &lt;code&gt;try...except&lt;/code&gt;, but there&amp;rsquo;s a better way.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;reduce()&lt;/code&gt; function accepts an optional third argument for an initial value. Passing &lt;code&gt;0&lt;/code&gt; to this third argument gets you the expected behavior:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ft&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filterfalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Applying this to the S&amp;amp;P500 example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zdp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# zero DataPoint&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;max_gain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ft&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filterfalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;diffs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zdp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Great! You&amp;rsquo;ve got it working just the way it should! Now, finding the maximum loss is easy:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ft&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filterfalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zdp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# DataPoint(date=&amp;#39;2018-02-08&amp;#39;, value=-20.47)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;longest-growth-streak&quot;&gt;Longest Growth Streak&lt;/h3&gt;
&lt;p&gt;Finding the longest growth streak in the history of the S&amp;amp;P500 is equivalent to finding the largest number of consecutive positive data points in the &lt;code&gt;gains&lt;/code&gt; sequence. The &lt;code&gt;itertools.takewhile()&lt;/code&gt; and &lt;code&gt;itertools.dropwhile()&lt;/code&gt; functions are perfect for this situation.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;takewhile()&lt;/code&gt; function takes a predicate and an iterable &lt;code&gt;inputs&lt;/code&gt; as arguments and returns an iterator over &lt;code&gt;inputs&lt;/code&gt; that stops at the first instance of an element for which the predicate returns &lt;code&gt;False&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;takewhile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 0, 1, 2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;dropwhile()&lt;/code&gt; function does exactly the opposite. It returns an iterator  beginning at the first element for which the predicate returns &lt;code&gt;False&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropwhile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 3, 4&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the following generator function, &lt;code&gt;takewhile()&lt;/code&gt; and &lt;code&gt;dropwhile()&lt;/code&gt; are composed to yield tuples of consecutive positive elements of a sequence:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;consecutive_positives&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_consecutives&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itr&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;takewhile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                     &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropwhile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;takewhile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_consecutives&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;consecutive_positives()&lt;/code&gt; function works because &lt;code&gt;repeat()&lt;/code&gt; keeps returning a pointer to an iterator over the &lt;code&gt;sequence&lt;/code&gt; argument, which is being partially consumed at each iteration by the call to &lt;code&gt;tuple()&lt;/code&gt; in the &lt;code&gt;yield&lt;/code&gt; statement.&lt;/p&gt;
&lt;p&gt;You can use &lt;code&gt;consecutive_positives()&lt;/code&gt; to get a generator that produces tuples of consecutive positive data points in &lt;code&gt;gains&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;growth_streaks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;consecutive_positives&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now you can use &lt;code&gt;reduce()&lt;/code&gt; to extract the longest growth streak:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;longest_streak&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ft&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                           &lt;span class=&quot;n&quot;&gt;growth_streaks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Putting the whole thing together, here&amp;rsquo;s a full script that will read data from the &lt;code&gt;SP500.csv&lt;/code&gt; file and print out the max gain/loss and longest growth streak:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;collections&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;namedtuple&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;csv&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;itertools&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;it&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;functools&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ft&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DataPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;namedtuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;DataPoint&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;date&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])):&lt;/span&gt;
    &lt;span class=&quot;vm&quot;&gt;__slots__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__le__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__lt__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__gt__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;consecutive_positives&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_consecutives&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itr&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sequence&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;takewhile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                                     &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropwhile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;itr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;takewhile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_consecutives&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;read_prices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csvfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_strptime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strptime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csvfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;infile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DictReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;infile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_strptime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Date&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;%Y-%m-&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%d&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
                            &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Adj Close&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# Read prices and calculate daily percent change.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;prices&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_prices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;SP500.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;gains&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prev_day&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
              &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;day&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prev_day&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prices&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Find maximum daily gain/loss.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;zdp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DataPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# zero DataPoint&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;max_gain&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ft&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filterfalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zdp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;max_loss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ft&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filterfalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zdp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zdp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;c1&quot;&gt;# Find longest growth streak.&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;growth_streaks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;consecutive_positives&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gains&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;zero&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DataPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;longest_streak&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ft&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                           &lt;span class=&quot;n&quot;&gt;growth_streaks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Display results.&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Max gain: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1:.2f}% o&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;n &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_gain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Max loss: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{1:.2f}% o&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;n &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{0}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;max_loss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Longest growth streak: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{num_days}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; days (&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{first}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; to &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{last}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;)&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;num_days&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;longest_streak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;longest_streak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;longest_streak&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;date&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Running the above script produces the following output:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;Max gain: 11.58% on 2008-10-13&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Max loss: -20.47% on 1987-10-19&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Longest growth streak: 14 days (1971-03-26 to 1971-04-15)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;section-recap_3&quot;&gt;Section Recap&lt;/h3&gt;
&lt;p&gt;In this section, you covered a lot of ground, but you only saw a few functions from &lt;code&gt;itertools&lt;/code&gt;. Let&amp;rsquo;s review those now.&lt;/p&gt;
&lt;h4 id=&quot;itertoolsfilterfalse-example&quot;&gt;&lt;code&gt;itertools.filterfalse&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;filterfalse(pred, iterable)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Return those items of sequence for which &lt;code&gt;pred(item)&lt;/code&gt; is false. If &lt;code&gt;pred&lt;/code&gt; is &lt;code&gt;None&lt;/code&gt;, return the items that are false.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filterfalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0, 0, 0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;itertoolstakewhile-example&quot;&gt;&lt;code&gt;itertools.takewhile&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;takewhile(pred, iterable)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Return successive entries from an iterable as long as &lt;code&gt;pred&lt;/code&gt; evaluates to true for each entry.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;takewhile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1, 1, 1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;itertoolsdropwhile-example&quot;&gt;&lt;code&gt;itertools.dropwhile&lt;/code&gt; Example&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;dropwhile(pred, iterable)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Drop items from the iterable while &lt;code&gt;pred(item)&lt;/code&gt; is true. Afterwards, return every element until the iterable is exhausted.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dropwhile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0, 0, 1, 1, 0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You are really starting to master this whole &lt;code&gt;itertools&lt;/code&gt; thing! The community swim team would like to commission you for a small project.&lt;/p&gt;
&lt;h2 id=&quot;building-relay-teams-from-swimmer-data&quot;&gt;Building Relay Teams From Swimmer Data&lt;/h2&gt;
&lt;p&gt;In this example, you will read data from a CSV file containing swimming event times for a community swim team from all of the swim meets over the course of a season. The goal is to determine which swimmers should be in the relay teams for each stroke next season.&lt;/p&gt;
&lt;p&gt;Each stroke should have an &amp;ldquo;A&amp;rdquo; and a &amp;ldquo;B&amp;rdquo; relay team with four swimmers each. The &amp;ldquo;A&amp;rdquo; team should contain the four swimmers with the best times for the stroke and the &amp;ldquo;B&amp;rdquo; team the swimmers with the next four best times.&lt;/p&gt;
&lt;p&gt;The data for this example can be found &lt;a href=&quot;https://github.com/realpython/materials/tree/master/itertools-in-python3&quot;&gt;here&lt;/a&gt;. If you want to follow along, download it to your current working directory and save it as &lt;code&gt;swimmers.csv&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here are the first 10 rows of &lt;code&gt;swimmers.csv&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; head -n &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt; swimmers.csv
&lt;span class=&quot;go&quot;&gt;Event,Name,Stroke,Time1,Time2,Time3&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0,Emma,freestyle,00:50:313667,00:50:875398,00:50:646837&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0,Emma,backstroke,00:56:720191,00:56:431243,00:56:941068&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0,Emma,butterfly,00:41:927947,00:42:062812,00:42:007531&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0,Emma,breaststroke,00:59:825463,00:59:397469,00:59:385919&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0,Olivia,freestyle,00:45:566228,00:46:066985,00:46:044389&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0,Olivia,backstroke,00:53:984872,00:54:575110,00:54:932723&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0,Olivia,butterfly,01:12:548582,01:12:722369,01:13:105429&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0,Olivia,breaststroke,00:49:230921,00:49:604561,00:49:120964&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;0,Sophia,freestyle,00:55:209625,00:54:790225,00:55:351528&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The three times in each row represent the times recorded by three different stopwatches, and are given in &lt;code&gt;MM:SS:mmmmmm&lt;/code&gt; format (minutes, seconds, microseconds). The accepted time for an event is the &lt;em&gt;median&lt;/em&gt; of these three times, &lt;em&gt;not&lt;/em&gt; the average.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start by creating a subclass &lt;code&gt;Event&lt;/code&gt; of the &lt;code&gt;namedtuple&lt;/code&gt; object, just like we did in the &lt;a href=&quot;#analyzing-the-sp500&quot;&gt;SP500 example&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;collections&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;namedtuple&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;namedtuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Event&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;stroke&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;time&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])):&lt;/span&gt;
    &lt;span class=&quot;vm&quot;&gt;__slots__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__lt__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;.stroke&lt;/code&gt; property stores the name of the stroke in the event, &lt;code&gt;.name&lt;/code&gt; stores the swimmer name, and &lt;code&gt;.time&lt;/code&gt; records the accepted time for the event. The &lt;code&gt;.__lt__()&lt;/code&gt; dunder method will allow &lt;code&gt;min()&lt;/code&gt; to be called on a sequence of &lt;code&gt;Event&lt;/code&gt; objects.&lt;/p&gt;
&lt;p&gt;To read the data from the CSV into a tuple of &lt;code&gt;Event&lt;/code&gt; objects, you can use the &lt;code&gt;csv.DictReader&lt;/code&gt; object:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;csv&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;statistics&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;read_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csvfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_strptime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strptime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_median&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;times&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;statistics&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;median&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_strptime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;%M:%S:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                                  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Times&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;fieldnames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Event&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Stroke&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csvfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;infile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DictReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;infile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fieldnames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fieldnames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;restkey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Times&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# skip header&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Stroke&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_median&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Times&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;swimmers.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;read_events()&lt;/code&gt; generator reads each row in the &lt;code&gt;swimmers.csv&lt;/code&gt; file into an &lt;code&gt;OrderedDict&lt;/code&gt; object in the following line:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DictReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;infile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fieldnames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fieldnames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;restkey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Times&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;By assigning the &lt;code&gt;&#39;Times&#39;&lt;/code&gt; field to &lt;code&gt;restkey&lt;/code&gt;, the &amp;ldquo;Time1&amp;rdquo;, &amp;ldquo;Time2&amp;rdquo;, and &amp;ldquo;Time3&amp;rdquo; columns of each row in the CSV file will be stored in a list on the &lt;code&gt;&#39;Times&#39;&lt;/code&gt; key of the &lt;code&gt;OrderedDict&lt;/code&gt; returned by &lt;code&gt;csv.DictReader&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For example, the first row of the file (excluding the header row) is read into the following object:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OrderedDict&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Event&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;0&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
             &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Emma&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
             &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Stroke&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;freestyle&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
             &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Times&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;00:50:313667&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;00:50:875398&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;00:50:646837&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, &lt;code&gt;read_events()&lt;/code&gt; yields an &lt;code&gt;Event&lt;/code&gt; object with the stroke, swimmer name, and median time (as a &lt;a href=&quot;https://docs.python.org/3/library/datetime.html#time-objects&quot;&gt;&lt;code&gt;datetime.time&lt;/code&gt; object&lt;/a&gt;) returned by the &lt;code&gt;_median()&lt;/code&gt; function, which calls &lt;a href=&quot;https://docs.python.org/3/library/statistics.html#statistics.median&quot;&gt;&lt;code&gt;statistics.median()&lt;/code&gt;&lt;/a&gt; on the list of times in the row.&lt;/p&gt;
&lt;p&gt;Since each item in the list of times is read as a string by &lt;code&gt;csv.DictReader()&lt;/code&gt;, &lt;code&gt;_median()&lt;/code&gt; uses the &lt;a href=&quot;https://docs.python.org/3/library/datetime.html#datetime.datetime.strptime&quot;&gt;&lt;code&gt;datetime.datetime.strptime()&lt;/code&gt; classmethod&lt;/a&gt; to instantiate a time object from each string.&lt;/p&gt;
&lt;p&gt;Finally, a tuple of &lt;code&gt;Event&lt;/code&gt; objects is created:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;swimmers.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The first five elements of &lt;code&gt;events&lt;/code&gt; look like this:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(Event(stroke=&amp;#39;freestyle&amp;#39;, name=&amp;#39;Emma&amp;#39;, time=datetime.time(0, 0, 50, 646837)),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; Event(stroke=&amp;#39;backstroke&amp;#39;, name=&amp;#39;Emma&amp;#39;, time=datetime.time(0, 0, 56, 720191)),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; Event(stroke=&amp;#39;butterfly&amp;#39;, name=&amp;#39;Emma&amp;#39;, time=datetime.time(0, 0, 42, 7531)),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; Event(stroke=&amp;#39;breaststroke&amp;#39;, name=&amp;#39;Emma&amp;#39;, time=datetime.time(0, 0, 59, 397469)),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; Event(stroke=&amp;#39;freestyle&amp;#39;, name=&amp;#39;Olivia&amp;#39;, time=datetime.time(0, 0, 46, 44389)))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now that you&amp;rsquo;ve got the data into memory, what do you do with it? Here&amp;rsquo;s the plan of attack:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Group the events by stroke.&lt;/li&gt;
&lt;li&gt;For each stroke:&lt;ul&gt;
&lt;li&gt;Group its events by swimmer name and determine the best time for each swimmer.&lt;/li&gt;
&lt;li&gt;Order the swimmers by best time.&lt;/li&gt;
&lt;li&gt;The first four swimmers make the &amp;ldquo;A&amp;rdquo; team for the stroke, and the next four swimmers make the &amp;ldquo;B&amp;rdquo; team.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;itertools.groupby()&lt;/code&gt; function makes grouping objects in an iterable a snap. It takes an iterable &lt;code&gt;inputs&lt;/code&gt; and a &lt;code&gt;key&lt;/code&gt; to group by, and returns an object containing iterators over the elements of &lt;code&gt;inputs&lt;/code&gt; grouped by the key.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a simple &lt;code&gt;groupby()&lt;/code&gt; example:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Alan&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;age&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;34&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Catherine&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;age&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;34&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Betsy&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;age&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;29&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;David&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;age&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;33&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grouped_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;age&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grp&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grouped_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{}: {}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;34: [{&amp;#39;name&amp;#39;: &amp;#39;Alan&amp;#39;, &amp;#39;age&amp;#39;: 34}, {&amp;#39;name&amp;#39;: &amp;#39;Betsy&amp;#39;, &amp;#39;age&amp;#39;: 34}]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;29: [{&amp;#39;name&amp;#39;: &amp;#39;Catherine&amp;#39;, &amp;#39;age&amp;#39;: 29}]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;33: [{&amp;#39;name&amp;#39;: &amp;#39;David&amp;#39;, &amp;#39;age&amp;#39;: 33}]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If no key is specified, &lt;code&gt;groupby()&lt;/code&gt; defaults to grouping by &amp;ldquo;identity&amp;rdquo;&amp;mdash;that is, aggregating identical elements in the iterable:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grp&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{}: {}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1: [1, 1]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2: [2, 2, 2]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3: [3]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The object returned by &lt;code&gt;groupby()&lt;/code&gt; is sort of like a dictionary in the sense that the iterators returned are associated with a key. However, unlike a dictionary, it won&amp;rsquo;t allow you to access its values by key name:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;&amp;gt;&amp;gt; grouped_data[1]&lt;/span&gt;
&lt;span class=&quot;gt&quot;&gt;Traceback (most recent call last):&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;, in &lt;span class=&quot;n&quot;&gt;&amp;lt;module&amp;gt;&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;TypeError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;&amp;#39;itertools.groupby&amp;#39; object is not subscriptable&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In fact, &lt;strong&gt;&lt;code&gt;groupby()&lt;/code&gt; returns an iterator over tuples whose first components are keys and second components are iterators over the grouped data&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grouped_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grouped_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;[(1, &amp;lt;itertools._grouper object at 0x7ff3056130b8&amp;gt;),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; (2, &amp;lt;itertools._grouper object at 0x7ff3056130f0&amp;gt;),&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; (3, &amp;lt;itertools._grouper object at 0x7ff305613128&amp;gt;)]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;One thing to keep in mind with &lt;code&gt;groupby()&lt;/code&gt; is that it isn&amp;rsquo;t as smart as you might like. As &lt;code&gt;groupby()&lt;/code&gt; traverses the data, it aggregates elements until an element with a different key is encountered, at which point it starts a new group:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grouped_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grp&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;grouped_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;{}: {}&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1: [1]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2: [2]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;1: [1]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2: [2]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;3: [3]&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2: [2]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Compare this to, say, the SQL &lt;code&gt;GROUP BY&lt;/code&gt; command, which groups elements regardless of their order of appearance.&lt;/p&gt;
&lt;p&gt;When working with &lt;code&gt;groupby()&lt;/code&gt;, you need to sort your data on the same key that you would like to group by. Otherwise, you may get unexpected results. This is so common that it helps to write a utility function to take care of this for you:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sort_and_group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Group sorted `iterable` on `key`.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Returning to the swimmers example, the first thing you need to do is create a for loop that iterates over the data in the &lt;code&gt;events&lt;/code&gt; tuple grouped by stroke:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stroke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evts&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sort_and_group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stroke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Next, you need to group the &lt;code&gt;evts&lt;/code&gt; iterator by swimmer name inside of the above &lt;code&gt;for&lt;/code&gt; loop:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;events_by_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sort_and_group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;To calculate the best time for each swimmer in &lt;code&gt;events_by_name&lt;/code&gt;, you can call &lt;code&gt;min()&lt;/code&gt; on the events in that swimmers group. (This works because you implemented the &lt;code&gt;.__lt__()&lt;/code&gt; dunder method in the &lt;code&gt;Events&lt;/code&gt; class.)&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;best_times&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;events_by_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Note that the &lt;code&gt;best_times&lt;/code&gt; generator yields &lt;code&gt;Event&lt;/code&gt; objects containing the best stroke time for each swimmer. To build the relay teams, you&amp;rsquo;ll need to sort &lt;code&gt;best_times&lt;/code&gt; by time and aggregate the result into groups of four. To aggregate the results, you can use the &lt;code&gt;grouper()&lt;/code&gt; function from &lt;a href=&quot;#the-grouper-recipe&quot;&gt;The &lt;code&gt;grouper()&lt;/code&gt; recipe&lt;/a&gt; section and use &lt;code&gt;islice()&lt;/code&gt; to grab the first two groups.&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sorted_by_time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;best_times&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;teams&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;B&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sorted_by_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now &lt;code&gt;teams&lt;/code&gt; is an iterator over exactly two tuples representing the &amp;ldquo;A&amp;rdquo; and the &amp;ldquo;B&amp;rdquo; team for the stroke. The first component of each tuple is the letter &amp;ldquo;A&amp;rdquo; or &amp;ldquo;B&amp;rdquo;, and the second component is an iterator over &lt;code&gt;Event&lt;/code&gt; objects containing the swimmers in the team. You can now print the results:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;team&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;swimmers&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;teams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{stroke}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{team}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{names}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;stroke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stroke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;team&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;team&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;swimmer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;swimmer&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;swimmers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here&amp;rsquo;s the full script:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;collections&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;namedtuple&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;csv&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;datetime&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;itertools&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;it&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;statistics&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;namedtuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Event&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;stroke&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;time&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])):&lt;/span&gt;
    &lt;span class=&quot;vm&quot;&gt;__slots__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__lt__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sort_and_group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groupby&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fillvalue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;iter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iterable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;zip_longest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fillvalue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fillvalue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;read_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csvfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_strptime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strptime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_median&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;times&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;statistics&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;median&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_strptime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;%M:%S:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%f&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
                                  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Times&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;fieldnames&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Event&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;Stroke&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csvfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;infile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DictReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;infile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fieldnames&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fieldnames&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;restkey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Times&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# Skip header.&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Event&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Stroke&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Name&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_median&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;Times&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;events&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;tuple&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read_events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;swimmers.csv&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stroke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evts&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sort_and_group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stroke&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;events_by_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sort_and_group&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;best_times&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;events_by_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sorted_by_time&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;best_times&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;teams&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;B&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;islice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;grouper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sorted_by_time&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;team&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;swimmers&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;teams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{stroke}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{team}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{names}&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;stroke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stroke&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;team&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;team&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;names&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;, &amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;swimmer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;swimmer&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;swimmers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you run the above code, you&amp;rsquo;ll get the following output:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;go&quot;&gt;Backstroke A: Sophia, Grace, Penelope, Addison&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Backstroke B: Elizabeth, Audrey, Emily, Aria&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Breaststroke A: Samantha, Avery, Layla, Zoe&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Breaststroke B: Lillian, Aria, Ava, Alexa&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Butterfly A: Audrey, Leah, Layla, Samantha&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Butterfly B: Alexa, Zoey, Emma, Madison&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Freestyle A: Aubrey, Emma, Olivia, Evelyn&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Freestyle B: Elizabeth, Zoe, Addison, Madison&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;where-to-go-from-here&quot;&gt;Where to Go From Here&lt;/h2&gt;
&lt;p&gt;If you have made it this far, congratulations! I hope you have enjoyed the journey.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;itertools&lt;/code&gt; is a powerful module in the Python standard library, and an essential tool to have in your toolkit. With it, you can write faster and more memory efficient code that is often simpler and easier to read (although that is not always the case, as you saw in the section on &lt;a href=&quot;#second-order-recurrence-relations&quot;&gt;second order recurrence relations&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;If anything, though, &lt;code&gt;itertools&lt;/code&gt; is a testament to the power of iterators and &lt;a href=&quot;https://en.wikipedia.org/wiki/Lazy_evaluation&quot;&gt;lazy evaluation&lt;/a&gt;. Even though you have seen many techniques, this article only scratches the surface.&lt;/p&gt;
&lt;p&gt;So I guess this means your journey is only just beginning.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free Bonus:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/optins/view/itertools-cheatsheet/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-itertools-cheatsheet&quot; data-focus=&quot;false&quot;&gt;Click here to get our itertools cheat sheet&lt;/a&gt; that summarizes the techniques demonstrated in this tutorial.&lt;/p&gt;&lt;/div&gt;

&lt;p&gt;In fact, this article skipped two &lt;code&gt;itertools&lt;/code&gt; functions: &lt;a href=&quot;https://docs.python.org/3/library/itertools.html#itertools.starmap&quot;&gt;&lt;code&gt;starmap()&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://docs.python.org/3/library/itertools.html#itertools.compress&quot;&gt;&lt;code&gt;compress()&lt;/code&gt;&lt;/a&gt;. In my experience, these are two of the lesser used &lt;code&gt;itertools&lt;/code&gt; functions, but I urge you to read their docs an experiment with your own use cases!&lt;/p&gt;
&lt;p&gt;Here are a few places where you can find more examples of &lt;code&gt;itertools&lt;/code&gt; in action (thanks to Brad Solomon for these fine suggestions):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/9059173/what-is-the-purpose-in-pythons-itertools-repeat/9098860#9098860&quot;&gt;What is the Purpose of &lt;code&gt;itertools.repeat()&lt;/code&gt;&lt;/a&gt;?&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/48421142/fastest-way-to-generate-a-random-like-unique-string-with-random-length-in-python/48421303#48421303&quot;&gt;Fastest Way to Generate a Random-like Unique String With Random Length in Python 3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/49372880/write-pandas-dataframe-to-string-buffer-with-chunking/49374826#49374826&quot;&gt;Write a Pandas DataFrame to a String Buffer with Chunking&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, for even more tools for constructing iterators, take a look at &lt;a href=&quot;https://github.com/erikrose/more-itertools&quot;&gt;more-itertools&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Do you have any favorite &lt;code&gt;itertools&lt;/code&gt; recipes/use-cases? We would love to hear about them in the comments!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;We would like to thank our readers Putcher and Samir Aghayev for pointing out a couple of errors in the original version of this article.&lt;/em&gt;&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Interacting with Python</title>
      <id>https://realpython.com/interacting-with-python/</id>
      <link href="https://realpython.com/interacting-with-python/"/>
      <updated>2018-05-28T14:00:00+00:00</updated>
      <summary>How to actually execute Python code and run Python programs using the CPython REPL, executing script files, and integrated development environments.</summary>
      <content type="html">
        &lt;p&gt;At this point, you should have a working Python 3 interpreter at hand. If you need help getting Python set up correctly, please refer to the &lt;a href=&quot;https://realpython.com/installing-python/&quot;&gt;previous section&lt;/a&gt; in this tutorial series.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Here&amp;rsquo;s what you&amp;rsquo;ll learn in this tutorial:&lt;/strong&gt; Now that you have a working Python setup, you&amp;rsquo;ll see how to actually execute Python code and run Python programs. By the end of this article, you&amp;rsquo;ll know how to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use Python interactively by typing code directly into the interpreter&lt;/li&gt;
&lt;li&gt;Execute code contained in a script file from the command line&lt;/li&gt;
&lt;li&gt;Work within a Python Integrated Development Environment (IDE)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It&amp;rsquo;s time to write some Python code!&lt;/p&gt;
&lt;h2 id=&quot;hello-world&quot;&gt;Hello, World!&lt;/h2&gt;
&lt;p&gt;There is a long-standing custom in the field of computer programming that the first code written in a newly installed language is a short program that simply displays the string &lt;code&gt;Hello, World!&lt;/code&gt; to the console.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This is a time-honored tradition dating back to the 1970s.  See &lt;a href=&quot;https://en.wikipedia.org/wiki/%22Hello,_World!%22_program&quot;&gt;Hello, World!&lt;/a&gt; for a brief history.  You seriously risk upsetting the &lt;em&gt;qi&lt;/em&gt; of the universe if you don&amp;rsquo;t abide by this custom.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The simplest Python 3 code to display &lt;code&gt;Hello, World!&lt;/code&gt; is:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You will explore several different ways to execute this code below.&lt;/p&gt;
&lt;h2 id=&quot;using-the-python-interpreter-interactively&quot;&gt;Using the Python Interpreter Interactively&lt;/h2&gt;
&lt;p&gt;The most straightforward way to start talking to Python is in an interactive &lt;a href=&quot;https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop&quot;&gt;Read-Eval-Print Loop (REPL)&lt;/a&gt; environment.  That simply means starting up the interpreter and typing commands to it directly.  The interpreter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;R&lt;/strong&gt;eads the command you enter&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;E&lt;/strong&gt;valuates and executes the command&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P&lt;/strong&gt;rints the output (if any) to the console&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;L&lt;/strong&gt;oops back and repeats the process&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The session continues in this manner until you instruct the interpreter to terminate.  Most of the example code in this tutorial series is presented as REPL interaction.&lt;/p&gt;
&lt;h3 id=&quot;starting-the-interpreter&quot;&gt;Starting the Interpreter&lt;/h3&gt;
&lt;p&gt;In a GUI desktop environment, it is likely that the installation process placed an icon on the desktop or an item in the desktop menu system that starts Python.&lt;/p&gt;
&lt;p&gt;For example, in Windows, there will likely be a program group in the &lt;strong&gt;Start&lt;/strong&gt; menu labeled &lt;strong&gt;Python 3.x&lt;/strong&gt;, and under it a menu item labeled &lt;strong&gt;Python 3.x (32-bit),&lt;/strong&gt; or something similar depending on the particular installation you chose.&lt;/p&gt;
&lt;p&gt;Clicking on that item will start the Python interpreter:&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/python-interpreter-window.24c17cb2fd60.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/python-interpreter-window.24c17cb2fd60.png&quot; width=&quot;903&quot; height=&quot;489&quot; alt=&quot;Python Interpreter window&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;The Python interpreter (REPL) running inside a terminal window.&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Alternatively, you can open a terminal window and run the interpreter from the command line.  How you go about opening a terminal window varies depending on which operating system you&amp;rsquo;re using:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In Windows, it is called &lt;strong&gt;Command Prompt&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;In macOS or Linux, it should be called &lt;strong&gt;Terminal&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using your operating system&amp;rsquo;s search function to search for &amp;ldquo;command&amp;rdquo; in Windows or &amp;ldquo;terminal&amp;rdquo; in macOS or Linux should find it.&lt;/p&gt;
&lt;p&gt;Once a terminal window is open, if paths have been set up properly by the Python install process, you should be able to just type &lt;code&gt;python&lt;/code&gt;. Then, you should see a response from the Python interpreter.&lt;/p&gt;
&lt;p&gt;This example is from the Windows Command Prompt window:&lt;/p&gt;
&lt;div class=&quot;highlight doscon&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;C:\Users\john&amp;gt;&lt;/span&gt;python
&lt;span class=&quot;go&quot;&gt;Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 07:18:10) [MSC v.1900 32 bit (Intel)] on win32&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Type &amp;quot;help&amp;quot;, &amp;quot;copyright&amp;quot;, &amp;quot;credits&amp;quot; or &amp;quot;license&amp;quot; for more information.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Technical Note:&lt;/strong&gt; If you are on a Linux system and installed Python 3, it may be that both Python 2 and Python 3 are installed.  In that case, it is possible that typing &lt;code&gt;python&lt;/code&gt; at the prompt will start Python 2.  Starting Python 3 may require typing something else, like &lt;code&gt;python3&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you installed a more recent version of Python 3 than the one that was included in the distribution, you may even need to specify the version you installed specifically&amp;mdash;for example &lt;code&gt;python3.6&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;If you are not seeing the &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; prompt, then you are not talking to the Python interpreter. This could be because Python is either not installed or not in your terminal window session&amp;rsquo;s path. It&amp;rsquo;s also possible that you just haven&amp;rsquo;t found the correct command to execute it. You can refer to our &lt;a href=&quot;https://realpython.com/installing-python/&quot;&gt;installing Python tutorial&lt;/a&gt; for help.&lt;/p&gt;
&lt;h3 id=&quot;executing-python-code&quot;&gt;Executing Python Code&lt;/h3&gt;
&lt;p&gt;If you are seeing the prompt, you&amp;rsquo;re off and running!  The next step is to execute the statement that displays &lt;code&gt;Hello, World!&lt;/code&gt; to the console:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ensure that the &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; prompt is displayed, and the cursor is positioned after it.&lt;/li&gt;
&lt;li&gt;Type the command &lt;code&gt;print(&quot;Hello, World!&quot;)&lt;/code&gt; exactly as shown.&lt;/li&gt;
&lt;li&gt;Press the &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt; key.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The interpreter&amp;rsquo;s response should appear on the next line.  You can tell it is console output because the &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; prompt is absent:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Hello, World!&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If your session looks like the above, then you have executed your first Python code!  Take a moment to celebrate.&lt;/p&gt;
&lt;figure class=&quot;figure mx-auto d-block&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/celebration.e98e35f3e140.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-25&quot; src=&quot;https://files.realpython.com/media/celebration.e98e35f3e140.png&quot; width=&quot;112&quot; height=&quot;112&quot; alt=&quot;Celebration&quot;/&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Congratulations!&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;Did something go wrong?  Perhaps you made one of these mistakes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;You forgot to enclose the string to be printed in quotation marks:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;World&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;World&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                      &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;invalid syntax&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You remembered the opening quotation mark but forgot the closing one:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!)&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!)&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;EOL while scanning string literal&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You used different opening and closing quotation marks:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!&amp;#39;)&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!&amp;#39;)&lt;/span&gt;
                         &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;EOL while scanning string literal&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You forgot the parentheses:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!&amp;quot;&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!&amp;quot;&lt;/span&gt;
                        &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;SyntaxError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;Missing parentheses in call to &amp;#39;print&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You entered extra whitespace characters before the command:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  File &lt;span class=&quot;nb&quot;&gt;&amp;quot;&amp;lt;stdin&amp;gt;&amp;quot;&lt;/span&gt;, line &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;
&lt;span class=&quot;gr&quot;&gt;IndentationError&lt;/span&gt;: &lt;span class=&quot;n&quot;&gt;unexpected indent&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;(You will see in an upcoming section why this matters.)&lt;/p&gt;
&lt;p&gt;If you got some sort of error message, go back and verify that you typed the command exactly as shown above.&lt;/p&gt;
&lt;h3 id=&quot;exiting-the-interpreter&quot;&gt;Exiting the Interpreter&lt;/h3&gt;
&lt;p&gt;When you are finished interacting with the interpreter, you can exit a REPL session in several ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Type &lt;code&gt;exit()&lt;/code&gt; and press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt;C:\Users\john&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Windows, type &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-z&quot;&gt;Z&lt;/kbd&gt;&lt;/span&gt; and press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Z&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;C:\Users\john&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In Linux or macOS, type &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-control&quot;&gt;Ctrl&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-d&quot;&gt;D&lt;/kbd&gt;&lt;/span&gt;.  The interpreter terminates immediately; pressing &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt; is not needed.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;If all else fails, you can simply close the interpreter window.  This isn&amp;rsquo;t the best way, but it will get the job done.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;running-a-python-script-from-the-command-line&quot;&gt;Running a Python Script from the Command Line&lt;/h2&gt;
&lt;p&gt;Entering commands to the Python interpreter interactively is great for quick testing and exploring features or functionality.&lt;/p&gt;
&lt;p&gt;Eventually though, as you create more complex applications, you will develop longer bodies of code that you will want to edit and run repeatedly.  You clearly don&amp;rsquo;t want to re-type the code into the interpreter every time!  This is where you will want to create a script file.&lt;/p&gt;
&lt;p&gt;A Python script is a reusable set of code.  It is essentially a Python program&amp;mdash;a sequence of Python instructions&amp;mdash;contained in a file.  You can run the program by specifying the name of the script file to the interpreter.&lt;/p&gt;
&lt;p&gt;Python scripts are just plain text, so you can edit them with any text editor.  If you &lt;a href=&quot;https://realpython.com/python-ides-code-editors-guide/&quot;&gt;have a favorite programmer&amp;rsquo;s editor&lt;/a&gt; that operates on text files, it should be fine to use.  If you don&amp;rsquo;t, the following are typically installed natively with their respective operating systems:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Windows:  Notepad&lt;/li&gt;
&lt;li&gt;Unix/Linux:  vi or vim&lt;/li&gt;
&lt;li&gt;macOS:  TextEdit&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using whatever editor you&amp;rsquo;ve chosen, create a script file called &lt;code&gt;hello.py&lt;/code&gt; containing the following:&lt;/p&gt;
&lt;div class=&quot;highlight python&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;Hello, World!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now save the file, keeping track of the directory or folder you chose to save into.&lt;/p&gt;
&lt;p&gt;Start a command prompt or terminal window.  If the current working directory is the same as the location in which you saved the file, you can simply specify the filename as a command-line argument to the Python interpreter: &lt;code&gt;python hello.py&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;For example, in Windows it would look like this:&lt;/p&gt;
&lt;div class=&quot;highlight doscon&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;C:\Users\john\Documents\test&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;dir&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; Volume in drive C is JFS&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt; Volume Serial Number is 1431-F891&lt;/span&gt;

&lt;span class=&quot;go&quot;&gt; Directory of C:\Users\john\Documents\test&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;05/20/2018  01:31 PM    &amp;lt;DIR&amp;gt;&lt;/span&gt;          .
&lt;span class=&quot;gp&quot;&gt;05/20/2018  01:31 PM    &amp;lt;DIR&amp;gt;&lt;/span&gt;          ..
&lt;span class=&quot;go&quot;&gt;05/20/2018  01:31 PM                24 hello.py&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;               1 File(s)             24 bytes&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;               2 Dir(s)  92,557,885,440 bytes free&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;C:\Users\john\Documents\test&amp;gt;&lt;/span&gt;python hello.py
&lt;span class=&quot;go&quot;&gt;Hello, World!&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the script is not in the current working directory, you can still run it.  You&amp;rsquo;ll just have to specify the path name to it:&lt;/p&gt;
&lt;div class=&quot;highlight doscon&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;C:\&amp;gt;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;cd&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;C:\&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;C:\&amp;gt;&lt;/span&gt;python c:\Users\john\Documents\test\hello.py
&lt;span class=&quot;go&quot;&gt;Hello, World!&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In Linux or macOS, your session may look more like this:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;jfs@jfs-xps:~$&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;pwd&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;/home/jfs&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;jfs@jfs-xps:~$&lt;/span&gt; ls
&lt;span class=&quot;go&quot;&gt;hello.py&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;jfs@jfs-xps:~$&lt;/span&gt; python hello.py
&lt;span class=&quot;go&quot;&gt;Hello, World!&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A script file is not required to have a &lt;code&gt;.py&lt;/code&gt; extension.  The Python interpreter will run the file no matter what it&amp;rsquo;s called, so long as you properly specify the file name on the command line:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;jfs@jfs-xps:~$&lt;/span&gt; ls
&lt;span class=&quot;go&quot;&gt;hello.foo&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;jfs@jfs-xps:~$&lt;/span&gt; cat hello.foo
&lt;span class=&quot;go&quot;&gt;print(&amp;quot;Hello, World!&amp;quot;)&lt;/span&gt;

&lt;span class=&quot;gp&quot;&gt;jfs@jfs-xps:~$&lt;/span&gt; python hello.foo
&lt;span class=&quot;go&quot;&gt;Hello, World!&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;But giving Python files a &lt;code&gt;.py&lt;/code&gt; extension is a useful convention because it makes them more easily identifiable.  In desktop-oriented folder/icon environments like Windows and macOS, this will also typically allow for setting up an appropriate file association, so that you can run the script just by clicking its icon.&lt;/p&gt;
&lt;h2 id=&quot;interacting-with-python-through-an-ide&quot;&gt;Interacting with Python through an IDE&lt;/h2&gt;
&lt;p&gt;An Integrated Development Environment (IDE) is an application that more or less combines all the functionality you have seen so far.  IDEs usually provide REPL capability as well as an editor with which you can create and modify code to then submit to the interpreter for execution.&lt;/p&gt;
&lt;p&gt;You may also find cool features such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Syntax highlighting&lt;/strong&gt;: IDEs often colorize different syntax elements in the code to make it easier to read.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Context-sensitive help&lt;/strong&gt;: Advanced IDEs can display related information from the Python documentation or even suggested fixes for common types of code errors.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Code-completion&lt;/strong&gt;: Some IDEs can complete partially typed pieces of code (like function names) for you&amp;mdash;a great time-saver and convenience feature.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Debugging&lt;/strong&gt;: A debugger allows you to run code step-by-step and inspect program data as you go.  This is invaluable when you are trying to determine why a program is behaving improperly, as will inevitably happen.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;idle&quot;&gt;IDLE&lt;/h3&gt;
&lt;p&gt;Most Python installations contain a rudimentary IDE called IDLE. The name ostensibly stands for Integrated Development and Learning Environment, but one member of the Monty Python troupe is named &lt;a href=&quot;https://en.wikipedia.org/wiki/Eric_Idle&quot;&gt;Eric Idle&lt;/a&gt;, which hardly seems like a coincidence.&lt;/p&gt;
&lt;p&gt;The procedure for running IDLE varies from one operating system to another.&lt;/p&gt;
&lt;h4 id=&quot;starting-idle-in-windows&quot;&gt;Starting IDLE in Windows&lt;/h4&gt;
&lt;p&gt;Go to the Start menu and select &lt;strong&gt;All Programs&lt;/strong&gt; or &lt;strong&gt;All Apps&lt;/strong&gt;.  There should be a program icon labeled &lt;strong&gt;IDLE (Python 3.x 32-bit)&lt;/strong&gt; or something similar.  This will vary slightly between Win 7, 8, and 10.  The IDLE icon may be in a program group folder named &lt;strong&gt;Python 3.x&lt;/strong&gt;.  You can also find the IDLE program icon by using the Windows search facility from the start menu and typing in &lt;code&gt;IDLE&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Click on the icon to start IDLE.&lt;/p&gt;
&lt;h4 id=&quot;starting-idle-in-macos&quot;&gt;Starting IDLE in macOS&lt;/h4&gt;
&lt;p&gt;Open Spotlight Search.  Typing &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-space&quot;&gt;Space&lt;/kbd&gt;&lt;/span&gt; is one of several ways to do this.  In the search box, type &lt;code&gt;terminal&lt;/code&gt; and press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;In the terminal window, type &lt;code&gt;idle3&lt;/code&gt; and press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;h4 id=&quot;starting-idle-in-linux&quot;&gt;Starting IDLE in Linux&lt;/h4&gt;
&lt;p&gt;IDLE is available with the Python 3 distribution but may not have been installed by default.  To find out whether it is, open a terminal window.  This varies depending on the Linux distribution, but you should be able to find it by using the desktop search function and searching for &lt;code&gt;terminal&lt;/code&gt;.  In the terminal window, type &lt;code&gt;idle3&lt;/code&gt; and press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;If you get an error saying &lt;code&gt;command not found&lt;/code&gt; or something to that effect, then IDLE is apparently not installed, so you&amp;rsquo;ll need to install it.&lt;/p&gt;
&lt;p&gt;The method for installing apps also varies from one Linux distribution to the next.  For example, with Ubuntu Linux, the command to install IDLE is &lt;code&gt;sudo apt-get install idle3&lt;/code&gt;. Many Linux distributions have GUI-based application managers that you can use to install apps as well.&lt;/p&gt;
&lt;p&gt;Follow whatever procedure is appropriate for your distribution to install IDLE.  Then, type &lt;code&gt;idle3&lt;/code&gt; in a terminal window and press &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt; to run it.  Your installation procedure may have also set up a program icon somewhere on the desktop to start IDLE as well.&lt;/p&gt;
&lt;p&gt;Whew!&lt;/p&gt;
&lt;h4 id=&quot;using-idle&quot;&gt;Using IDLE&lt;/h4&gt;
&lt;p&gt;Once IDLE is installed and you have started it successfully, you should see a window titled &lt;strong&gt;Python 3.x.x Shell&lt;/strong&gt;, where 3.x.x corresponds to your version of Python:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/idle-1.ad05cbe1e2f7.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/idle-1.ad05cbe1e2f7.png&quot; width=&quot;500&quot; height=&quot;555&quot; alt=&quot;IDLE screenshot 1&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; prompt should look familiar.  You can type REPL commands interactively, just like when you started the interpreter from a console window. Mindful of the &lt;em&gt;qi&lt;/em&gt; of the universe, display &lt;code&gt;Hello, World!&lt;/code&gt; again:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/idle-2.c0a65df087ef.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/idle-2.c0a65df087ef.png&quot; width=&quot;500&quot; height=&quot;555&quot; alt=&quot;IDLE screenshot 2&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The interpreter behaves more or less the same as when you ran it directly from the console. The IDLE interface adds the perk of displaying different syntactic elements in distinct colors to make things more readable.&lt;/p&gt;
&lt;p&gt;It also provides context-sensitive help.  For example, if you type &lt;code&gt;print(&lt;/code&gt; without typing any of the arguments to the print function or the closing parenthesis, then flyover text should appear specifying usage information for the &lt;code&gt;print()&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;One other feature IDLE provides is statement recall:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you have typed in several statements, you can recall them with &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-p&quot;&gt;P&lt;/kbd&gt;&lt;/span&gt; and &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-n&quot;&gt;N&lt;/kbd&gt;&lt;/span&gt; in Windows or Linux.&lt;/li&gt;
&lt;li&gt;&lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-p&quot;&gt;P&lt;/kbd&gt;&lt;/span&gt; cycles backward through previously executed statements; &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-alt&quot;&gt;Alt&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-n&quot;&gt;N&lt;/kbd&gt;&lt;/span&gt; cycles forward.&lt;/li&gt;
&lt;li&gt;Once a statement has been recalled, you can use editing keys on the keyboard to edit it and then execute it again.  The corresponding commands in macOS are &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-p&quot;&gt;P&lt;/kbd&gt;&lt;/span&gt; and &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-n&quot;&gt;N&lt;/kbd&gt;&lt;/span&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can also create script files and run them in IDLE.  From the Shell window menu, select &lt;strong&gt;File → New File&lt;/strong&gt;.  That should open an additional editing window.  Type in the code to be executed:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/idle-3.104282dbe280.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/idle-3.104282dbe280.png&quot; width=&quot;500&quot; height=&quot;594&quot; alt=&quot;IDLE screenshot 3&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;From the menu in that window, select &lt;strong&gt;File → Save&lt;/strong&gt; or &lt;strong&gt;File → Save As&amp;hellip;&lt;/strong&gt; and save the file to disk.  Then select &lt;strong&gt;Run → Run Module&lt;/strong&gt;.  The output should appear back in the interpreter Shell window:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/idle-4.4a4d4399093f.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/idle-4.4a4d4399093f.png&quot; width=&quot;500&quot; height=&quot;565&quot; alt=&quot;IDLE screenshot 4&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;OK, that&amp;rsquo;s probably enough &lt;code&gt;Hello, World!&lt;/code&gt;.  The &lt;em&gt;qi&lt;/em&gt; of the universe should be safe.&lt;/p&gt;
&lt;p&gt;Once both windows are open, you can switch back and forth, editing the code in one window, running it and displaying its output in the other.  In that way, IDLE provides a rudimentary Python development platform.&lt;/p&gt;
&lt;p&gt;Although it is somewhat basic, it supports quite a bit of additional functionality, including code completion, code formatting, and a debugger.  See the &lt;a href=&quot;https://docs.python.org/3/library/idle.html&quot;&gt;IDLE documentation&lt;/a&gt; for more details.&lt;/p&gt;
&lt;h3 id=&quot;thonny&quot;&gt;Thonny&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://thonny.org/&quot;&gt;Thonny&lt;/a&gt; is free Python IDE developed and maintained by the Institute of Computer Science at the University of Tartu, Estonia.  It is targeted at Python beginners specifically, so the interface is simple and uncluttered as well as easy to understand and get comfortable with quickly.&lt;/p&gt;
&lt;p&gt;Like IDLE, Thonny supports REPL interaction as well as script file editing and execution:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/thonny-REPL.ffb0d0a0d58d.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/thonny-REPL.ffb0d0a0d58d.png&quot; width=&quot;791&quot; height=&quot;672&quot; alt=&quot;Python Thonny REPL&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/thonny-editor.fc8d59bbcaa7.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/thonny-editor.fc8d59bbcaa7.png&quot; width=&quot;791&quot; height=&quot;672&quot; alt=&quot;Python Thonny editor&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thonny performs syntax highlighting and code completion in addition to providing a step-by-step debugger.  One feature that is particularly helpful to those learning Python is that the debugger displays values in expressions as they are evaluated while you are stepping through the code:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/thonny-expr.d833fc5e3562.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/thonny-expr.d833fc5e3562.png&quot; width=&quot;791&quot; height=&quot;779&quot; alt=&quot;Thonny expr evaluation&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thonny is especially easy to get started with because it comes with Python 3.6 built in.  So you only need to perform one install, and you&amp;rsquo;re ready to go!&lt;/p&gt;
&lt;p&gt;Versions are available for Windows, macOS, and Linux.  The &lt;a href=&quot;http://thonny.org/&quot;&gt;Thonny website&lt;/a&gt; has download and installation instructions.&lt;/p&gt;
&lt;p&gt;IDLE and Thonny are certainly not the only games going.  There are many other IDEs available for Python code editing and development.  See our &lt;a href=&quot;https://realpython.com/python-ides-code-editors-guide/&quot;&gt;Python IDEs and Code Editors Guide&lt;/a&gt; for additional suggestions.&lt;/p&gt;
&lt;h2 id=&quot;online-python-repl-sites&quot;&gt;Online Python REPL Sites&lt;/h2&gt;
&lt;p&gt;As you saw in the previous section, there are &lt;a href=&quot;https://realpython.com/installing-python/#online-python-interpreters&quot;&gt;websites available&lt;/a&gt; that can provide you with interactive access to a Python interpreter online without you having to install anything locally.&lt;/p&gt;
&lt;p&gt;This approach may be unsatisfactory for some of the more complicated or lengthy examples in this tutorial.  But for simple REPL sessions, it should work well.&lt;/p&gt;
&lt;p&gt;The Python Software Foundation provides an Interactive Shell on their website.  On the &lt;a href=&quot;https://www.python.org&quot;&gt;main page&lt;/a&gt;, click on the button that looks like one of these:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/psf-shell1.5e8e53654e7a.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/psf-shell1.5e8e53654e7a.png&quot; width=&quot;71&quot; height=&quot;70&quot; alt=&quot;Python Software Foundation Interactive Shell icon&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/psf-shell2.dea07e54567d.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/psf-shell2.dea07e54567d.png&quot; width=&quot;254&quot; height=&quot;76&quot; alt=&quot;Python Software Foundation Interactive Shell icon&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Or go directly to &lt;a href=&quot;https://www.python.org/shell&quot;&gt;https://www.python.org/shell&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You should get a page with a window that looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/psf-shell3.6e56026f9512.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/psf-shell3.6e56026f9512.png&quot; width=&quot;600&quot; height=&quot;294&quot; alt=&quot;Python Software Foundation Interactive Shell window&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The familiar &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; prompt shows you that you are talking to the Python interpreter.&lt;/p&gt;
&lt;p&gt;Here are a few other sites that provide Python REPL:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://pythonfiddle.com&quot;&gt;PythonFiddle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://repl.it&quot;&gt;repl.it&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://trinket.io&quot;&gt;Trinket&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Larger applications are typically contained in script files that are passed to the Python interpreter for execution.&lt;/p&gt;
&lt;p&gt;But one of the advantages of an interpreted language is that you can run the interpreter and execute commands interactively.  Python is easy to use in this manner, and it is a great way to get your feet wet learning how the language works.&lt;/p&gt;
&lt;p&gt;The examples throughout this tutorial have been produced by direct interaction with the Python interpreter, but if you choose to use IDLE or some other available IDE, the examples should still work just fine.&lt;/p&gt;
&lt;p&gt;Continue to the next section, where you will start to explore the elements of the Python language itself.&lt;/p&gt;
&lt;div class=&quot;container py-3 series-nav mb-3&quot;&gt;
  &lt;div class=&quot;row justify-content-between&quot;&gt;
    &lt;div class=&quot;col-12 col-md-3 text-left text-muted ml-1&quot;&gt;&lt;a href=&quot;https://realpython.com/installing-python/&quot;&gt; «&amp;nbsp;Installing Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-center text-muted&quot;&gt;&lt;a href=&quot;#&quot;&gt;Interacting with Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-right text-muted mr-1&quot;&gt;&lt;a href=&quot;https://realpython.com/python-data-types/&quot;&gt;Basic Data Types&amp;nbsp;»&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Python 3 Installation &amp; Setup Guide</title>
      <id>https://realpython.com/installing-python/</id>
      <link href="https://realpython.com/installing-python/"/>
      <updated>2018-05-23T14:00:00+00:00</updated>
      <summary>In this Python installation guide you&#39;ll see step by step how to get a working Python 3 distribution set up on Windows, macOS, Linux, iOS, and Android.</summary>
      <content type="html">
        &lt;p&gt;To get started working with Python 3, you&amp;rsquo;ll need to have access to the Python interpreter. There are several common ways to accomplish this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python can be obtained from the &lt;strong&gt;Python Software Foundation&lt;/strong&gt; website at &lt;a href=&quot;https://www.python.org&quot;&gt;python.org&lt;/a&gt;.  Typically, that involves downloading the appropriate &lt;strong&gt;installer&lt;/strong&gt; for your operating system and running it on your machine.&lt;/li&gt;
&lt;li&gt;Some operating systems, notably Linux, provide a &lt;strong&gt;package manager&lt;/strong&gt; that can be run to install Python.&lt;/li&gt;
&lt;li&gt;On macOS, the best way to install Python 3 involves installing a package manager called &lt;strong&gt;Homebrew&lt;/strong&gt;. You&amp;rsquo;ll see how to do this in the relevant section in the tutorial.&lt;/li&gt;
&lt;li&gt;On mobile operating systems like Android and iOS, you can install apps that provide a Python programming environment. This can be a great way to practice your coding skills on the go.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Alternatively, there are several websites that allow you to access a Python interpreter online without installing anything on your computer at all.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; There is a chance that Python may have been shipped with your operating system and is already installed. Even if that is the case, it may be that the installed version is outdated, in which case you will want to obtain the latest version anyhow.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;In this Python installation guide, you&amp;rsquo;ll see step by step how to set up a working Python 3 distribution on Windows, macOS, Linux, iOS, and Android. So let&amp;rsquo;s get started!&lt;/p&gt;
&lt;h2 id=&quot;windows&quot;&gt;Windows&lt;/h2&gt;
&lt;p&gt;It is highly unlikely that your Windows system shipped with Python already installed.  Windows systems typically do not.  Fortunately, installing does not involve much more than downloading the Python installer from the &lt;a href=&quot;https://www.python.org&quot;&gt;python.org website&lt;/a&gt; and running it. Let&amp;rsquo;s take a look at how to install Python 3 on Windows:&lt;/p&gt;
&lt;h3 id=&quot;step-1-download-the-python-3-installer&quot;&gt;Step 1: Download the Python 3 Installer&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Open a browser window and navigate to the &lt;a href=&quot;https://www.python.org/downloads/windows/&quot;&gt;Download page for Windows&lt;/a&gt; at &lt;a href=&quot;https://www.python.org/&quot;&gt;python.org&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Underneath the heading at the top that says &lt;strong&gt;Python Releases for Windows&lt;/strong&gt;, click on the link for the &lt;strong&gt;Latest Python 3 Release - Python 3.x.x&lt;/strong&gt;. (As of this writing, the latest is Python 3.6.5.)&lt;/li&gt;
&lt;li&gt;Scroll to the bottom and select either &lt;strong&gt;Windows x86-64 executable installer&lt;/strong&gt; for 64-bit or &lt;strong&gt;Windows x86 executable installer&lt;/strong&gt; for 32-bit. (See below.)&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;h4 id=&quot;sidebar-32-bit-or-64-bit-python&quot;&gt;Sidebar: 32-bit or 64-bit Python?&lt;/h4&gt;
&lt;p&gt;For Windows, you can choose either the 32-bit or 64-bit installer. Here&amp;rsquo;s what the difference between the two comes down to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If your system has a 32-bit processor, then you should choose the 32-bit installer.&lt;/li&gt;
&lt;li&gt;On a 64-bit system, either installer will actually work for most purposes. The 32-bit version will generally use less memory, but the 64-bit version performs better for applications with intensive computation.&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;re unsure which version to pick, go with the 64-bit version.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Remember that if you get this choice &amp;ldquo;wrong&amp;rdquo; and would like to switch to another version of Python, you can just uninstall Python and then re-install it by downloading another installer from &lt;a href=&quot;https://python.org&quot;&gt;python.org&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;step-2-run-the-installer&quot;&gt;Step 2: Run the Installer&lt;/h3&gt;
&lt;p&gt;Once you have chosen and downloaded an installer, simply run it by double-clicking on the downloaded file. A dialog should appear that looks something like this:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/win-install-dialog.40e3ded144b0.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-66&quot; src=&quot;https://files.realpython.com/media/win-install-dialog.40e3ded144b0.png&quot; width=&quot;549&quot; height=&quot;338&quot; alt=&quot;Windows installation dialog&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; You want to be sure to check the box that says &lt;strong&gt;Add Python 3.x to PATH&lt;/strong&gt; as shown to ensure that the interpreter will be placed in your execution path.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Then just click &lt;strong&gt;Install Now&lt;/strong&gt;. That should be all there is to it. A few minutes later you should have a working Python 3 installation on your system.&lt;/p&gt;
&lt;h2 id=&quot;windows-subsystem-for-linux-wsl&quot;&gt;Windows Subsystem for Linux (WSL)&lt;/h2&gt;
&lt;p&gt;If you are running Windows 10 Creators or Anniversary Update, you actually have another option for installing Python. These versions of Windows 10 include a feature called the &lt;strong&gt;Windows Subsystem for Linux,&lt;/strong&gt; which allows you to run a Linux environment directly in Windows, unmodified and without the overhead of a virtual machine.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For more information, see the &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/wsl/about&quot;&gt;Windows Subsystem for Linux Documentation&lt;/a&gt; article on the Microsoft website.&lt;/li&gt;
&lt;li&gt;For instructions on how to enable the subsystem in Windows 10 and install a Linux distribution, see the &lt;a href=&quot;https://docs.microsoft.com/en-us/windows/wsl/install-win10&quot;&gt;Windows 10 Installation Guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;You can also check out this presentation on YouTube by &lt;a href=&quot;https://www.youtube.com/watch?v=JZCPYWrTLTg&quot;&gt;Sarah Cooley&lt;/a&gt;, one of the members of the WSL development team.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once you have installed the Linux distribution of your choice, you can install Python 3 from a Bash console window, just as you would if you were running that Linux distribution natively. (See below.)&lt;/p&gt;
&lt;h2 id=&quot;linux&quot;&gt;Linux&lt;/h2&gt;
&lt;p&gt;There is a very good chance your Linux distribution has Python installed already, but it probably won&amp;rsquo;t be the latest version, and it may be Python 2 instead of Python 3.&lt;/p&gt;
&lt;p&gt;To find out what version(s) you have, open a terminal window and try the following commands:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;python --version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;python2 --version&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;python3 --version&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One or more of these commands should respond with a version, as below:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3 --version
&lt;span class=&quot;go&quot;&gt;Python 3.6.5&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If the version shown is Python 2.x.x or a version of Python 3 that is not the latest (3.6.5 as of this writing), then you will want to install the latest version.  The procedure for doing this will depend on the Linux distribution you are running.&lt;/p&gt;
&lt;h3 id=&quot;ubuntu&quot;&gt;Ubuntu&lt;/h3&gt;
&lt;p&gt;Depending on the version of the Ubuntu distribution you run, the Python install instructions vary. You can determine your local Ubuntu version by running the following command:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; lsb_release -a
&lt;span class=&quot;go&quot;&gt;No LSB modules are available.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Distributor ID: Ubuntu&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Description:    Ubuntu 16.04.4 LTS&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Release:        16.04&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Codename:       xenial&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Depending on the version number you see under &lt;code&gt;Release&lt;/code&gt; in the console output, follow the instructions below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ubuntu 17.10, Ubuntu 18.04&lt;/strong&gt; (and above) come with Python 3.6 by default. You should be able to invoke it with the command &lt;code&gt;python3&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Ubuntu 16.10 and 17.04&lt;/strong&gt; do not come with Python 3.6 by default, but it is in the Universe repository.  You should be able to install it with the following commands:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo apt-get update
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo apt-get install python3.6
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can then invoke it with the command &lt;code&gt;python3.6&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you are using &lt;strong&gt;Ubuntu 14.04 or 16.04&lt;/strong&gt;, Python 3.6 is not in the Universe repository, and you need to get it from a Personal Package Archive (PPA). For example, to install Python from the &lt;a href=&quot;https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa&quot;&gt;&amp;ldquo;deadsnakes&amp;rdquo; PPA&lt;/a&gt;, do the following:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo add-apt-repository ppa:deadsnakes/ppa
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo apt-get update
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo apt-get install python3.6
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;As above, invoke with the command &lt;code&gt;python3.6&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;linux-mint&quot;&gt;Linux Mint&lt;/h3&gt;
&lt;p&gt;Mint and Ubuntu use the same package management system, which frequently makes life easier. You can follow the instructions above for &lt;strong&gt;Ubuntu 14.04&lt;/strong&gt;. The &lt;a href=&quot;https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa&quot;&gt;&amp;ldquo;deadsnakes&amp;rdquo; PPA&lt;/a&gt; works with Mint.&lt;/p&gt;
&lt;h3 id=&quot;debian&quot;&gt;Debian&lt;/h3&gt;
&lt;p&gt;We found sources that indicated that the Ubuntu 16.10 method would work for Debian, but we never found a path to get it to work on Debian 9. Instead, we ended up making Python from source as listed below.&lt;/p&gt;
&lt;p&gt;One issue with Debian, however, is that it generally does not install the &lt;code&gt;sudo&lt;/code&gt; command by default. To install it, you&amp;rsquo;ll need to do the following before you carry out the &lt;a href=&quot;#compiling-python-from-source&quot;&gt;Compiling Python From Source&lt;/a&gt; instructions below:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; su
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; apt-get install sudo
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; vi /etc/sudoers
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;After that, open the &lt;code&gt;/etc/sudoers&lt;/code&gt; file using the &lt;code&gt;sudo vim&lt;/code&gt; command (or your favorite text editor.) Add the following line of text to the end of the file, replacing &lt;code&gt;your_username&lt;/code&gt; with your actual username:&lt;/p&gt;
&lt;div class=&quot;highlight text&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;your_username ALL=(ALL) ALL
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;opensuse&quot;&gt;openSUSE&lt;/h3&gt;
&lt;p&gt;We found several sites describing how to get &lt;code&gt;zypper&lt;/code&gt; to install the latest version of Python, but they seemed problematic or outdated. We did not manage to get any of them to work successfully, so we fell back to building Python from source. To do that, you will need to install the development tools, which can be done in &lt;code&gt;YaST&lt;/code&gt; (via the menus) or by using &lt;code&gt;zypper&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudu zypper install -t pattern devel_C_C++
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This step took a while and involved the installation of 154 packages, but once it was completed, we were able to build the source as shown in the &lt;a href=&quot;#compiling-python-from-source&quot;&gt;Compiling Python From Source&lt;/a&gt; section above.&lt;/p&gt;
&lt;h3 id=&quot;centos&quot;&gt;CentOS&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;https://ius.io/&quot;&gt;IUS Community&lt;/a&gt; does a nice job of providing newer versions of software for &amp;ldquo;Enterprise Linux&amp;rdquo; distros (i.e. Red Hat Enterprise and CentOS).   You can use their work to help you install Python 3.&lt;/p&gt;
&lt;p&gt;To install, you should first update your system with the &lt;a href=&quot;https://www.centos.org/docs/5/html/yum/&quot;&gt;yum package manager&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo yum update
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo yum install yum-utils
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can then install the CentOS IUS package which will get you up to date with their site:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo yum install https://centos7.iuscommunity.org/ius-release.rpm
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally you can then install Python and Pip:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo yum install python36u
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo yum install python36u-pip
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Thanks to Jani Karhunen for his &lt;a href=&quot;https://janikarhunen.fi/how-to-install-python-3-6-1-on-centos-7.html&quot;&gt;excellent writeup&lt;/a&gt; for CentOS 7.&lt;/p&gt;
&lt;h3 id=&quot;fedora&quot;&gt;Fedora&lt;/h3&gt;
&lt;p&gt;Fedora has a roadmap to switch to Python 3 as the default Python published &lt;a href=&quot;https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3&quot;&gt;here&lt;/a&gt;. It indicates that the current version and the next few versions will all ship with Python 2 as the default, but Python 3 will be installed. If the &lt;code&gt;python3&lt;/code&gt; installed on your version is not 3.6, you  can use the following command to install it:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo dnf install python36
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;arch-linux&quot;&gt;Arch Linux&lt;/h3&gt;
&lt;p&gt;Arch Linux is fairly aggressive about keeping up with Python releases. It is likely you already have the latest version. If not, you can use this command:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; packman -S python
&lt;/pre&gt;&lt;/div&gt;

&lt;h3 id=&quot;compiling-python-from-source&quot;&gt;Compiling Python From Source&lt;/h3&gt;
&lt;p&gt;Sometimes your Linux distribution will not have the latest version of Python, or maybe you just want to be able to build the latest, greatest version yourself. Here are the steps you need to take to build Python from source:&lt;/p&gt;
&lt;h4 id=&quot;step-1-download-the-source-code&quot;&gt;Step 1: Download the Source Code&lt;/h4&gt;
&lt;p&gt;To start, you need to get the Python source code. Python.org makes this fairly easy.  If you go to the &lt;a href=&quot;https://www.python.org/downloads/source/&quot;&gt;Downloads&lt;/a&gt; page, you will see the latest source for Python 3 at the top. (Make sure you don&amp;rsquo;t grab Legacy Python, Python 2.)&lt;/p&gt;
&lt;p&gt;When you select the version, at the bottom of the page there is a &lt;strong&gt;Files&lt;/strong&gt; section. Select the &lt;strong&gt;Gzipped source tarball&lt;/strong&gt; and download it to your machine. If you prefer a command line method, you can easily use &lt;code&gt;wget&lt;/code&gt; to download it to your current directory:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz
&lt;/pre&gt;&lt;/div&gt;

&lt;h4 id=&quot;step-2-prepare-your-system&quot;&gt;Step 2: Prepare Your System&lt;/h4&gt;
&lt;p&gt;There are a few distro-specific steps involved in building Python from scratch. The goal of each step is the same on all distros, but you might need to translate to your distribution if it does not use &lt;code&gt;apt-get&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The first step you should take when doing an operation like this is to update the system packages on your machine before you start. On Debian, this is what that looks like:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo apt-get update
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo apt-get upgrade
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Next, we want to make sure the system has the tools needed to build Python. There are a bunch of them and you might already have some, but that&amp;rsquo;s fine. I&amp;rsquo;ve listed them all in one command line, but you can break the list into shorter commands by just repeating the &lt;code&gt;sudo apt-get install -y&lt;/code&gt; portion:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;# For apt-based systems (like Debian, Ubuntu, and Mint)&lt;/span&gt;
$ sudo apt-get install -y make build-essential libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev  libncursesw5-dev xz-utils tk-dev

&lt;span class=&quot;c1&quot;&gt;# For yum-based systems (like CentOS)&lt;/span&gt;
$ sudo yum -y groupinstall development
$ sudo yum -y install zlib-devel
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;step-3-build-python&quot;&gt;Step 3: Build Python&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Once you have the prerequisites and the tar file, you can unpack the source into a directory. Note that the following command will create a new directory called &lt;code&gt;Python-3.6.5&lt;/code&gt; under the one you are in:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; tar xvf Python-3.6.5.tgz
&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; Python-3.6.5
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Now you need to run the &lt;code&gt;./configure&lt;/code&gt; tool to prepare the build:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; ./configure --enable-optimizations --with-ensurepip&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;install
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Next, you build the Python programs using &lt;code&gt;make&lt;/code&gt;. The &lt;code&gt;-j&lt;/code&gt; option simply tells &lt;code&gt;make&lt;/code&gt; to split the building into parallel steps to speed up the compilation. Even with the parallel builds, this step can take a several minutes:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; make -j &lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Then, you&amp;rsquo;ll want to install your new version of Python. You&amp;rsquo;ll use the &lt;code&gt;altinstall&lt;/code&gt; target here in order to &lt;strong&gt;not&lt;/strong&gt;  overwrite the system&amp;rsquo;s version of Python.   Since you&amp;rsquo;re installing Python into &lt;code&gt;/usr/bin&lt;/code&gt;, you&amp;rsquo;ll need to run as root:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; sudo make altinstall
&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;:  Please only use the &lt;code&gt;altinstall&lt;/code&gt; target on &lt;code&gt;make&lt;/code&gt;. Using the &lt;code&gt;install&lt;/code&gt; target  will overwrite the &lt;code&gt;python&lt;/code&gt; binary. While this seems like it would be cool, there are big portions of the system that rely on the pre-installed version of Python.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;step-4-verify-your-python-install&quot;&gt;Step 4: Verify Your Python Install&lt;/h4&gt;
&lt;p&gt;Finally, you can test out your new Python version:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; python3.6 -V
&lt;span class=&quot;go&quot;&gt;Python 3.6.5&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2 id=&quot;macos-mac-os-x&quot;&gt;macOS / Mac OS X&lt;/h2&gt;
&lt;p&gt;While current versions of macOS (previously known as &amp;ldquo;Mac OS X&amp;rdquo;) include a version of Python 2, it is likely out of date by a few months. Also, this tutorial series uses Python 3, so let&amp;rsquo;s get you upgraded to that.&lt;/p&gt;
&lt;p&gt;The best way we found to install Python 3 on macOS is through the &lt;a href=&quot;https://brew.sh&quot;&gt;Homebrew package manager&lt;/a&gt;. This approach is also recommended by community guides like &lt;a href=&quot;http://docs.python-guide.org/en/latest/starting/install3/osx/&quot;&gt;The Hitchhiker&amp;rsquo;s Guide to Python&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;step-1-install-homebrew-part-1&quot;&gt;Step 1: Install Homebrew (Part 1)&lt;/h3&gt;
&lt;p&gt;To get started, you first want to install Homebrew:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open a browser and navigate to &lt;a href=&quot;http://brew.sh/&quot;&gt;http://brew.sh/&lt;/a&gt;. After the page has finished loading, &lt;strong&gt;select the Homebrew bootstrap code under &amp;ldquo;Install Homebrew&amp;rdquo;&lt;/strong&gt;. Then hit &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-command&quot;&gt;Cmd&lt;/kbd&gt;&lt;span&gt;+&lt;/span&gt;&lt;kbd class=&quot;key-c&quot;&gt;C&lt;/kbd&gt;&lt;/span&gt; to copy it to the clipboard. Make sure you&amp;rsquo;ve captured the text of the complete command because otherwise the installation will fail.&lt;/li&gt;
&lt;li&gt;Now you need to &lt;strong&gt;open a Terminal.app window, paste the Homebrew bootstrap code, and then hit&lt;/strong&gt; &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt;. This will begin the Homebrew installation.&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;re doing this on a fresh install of macOS, you may get a pop up alert &lt;strong&gt;asking you to install Apple&amp;rsquo;s &amp;ldquo;command line developer tools&amp;rdquo;&lt;/strong&gt;. You&amp;rsquo;ll need those to continue with the installation, so please &lt;strong&gt;confirm the dialog box by clicking on &amp;ldquo;Install&amp;rdquo;&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;At this point, you&amp;rsquo;re likely waiting for the command line developer tools to finish installing, and that&amp;rsquo;s going to take a few minutes. Time to grab a coffee or tea!&lt;/p&gt;
&lt;h3 id=&quot;step-2-install-homebrew-part-2&quot;&gt;Step 2: Install Homebrew (Part 2)&lt;/h3&gt;
&lt;p&gt;You can continue installing Homebrew and then Python after the command line developer tools installation is complete:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Confirm the &amp;ldquo;The software was installed&amp;rdquo; dialog from the developer tools installer.&lt;/li&gt;
&lt;li&gt;Back in the terminal, hit &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt; to continue with the Homebrew installation.&lt;/li&gt;
&lt;li&gt;Homebrew asks you to enter your password so it can finalize the installation. &lt;strong&gt;Enter your user account password and hit&lt;/strong&gt; &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt; to continue.&lt;/li&gt;
&lt;li&gt;Depending on your internet connection, Homebrew will take a few minutes to download its required files. Once the installation is complete, you&amp;rsquo;ll end up back at the command prompt in your terminal window.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Whew! Now that the Homebrew package manager is set up, let&amp;rsquo;s continue on with installing Python 3 on your system.&lt;/p&gt;
&lt;h3 id=&quot;step-3-install-python&quot;&gt;Step 3: Install Python&lt;/h3&gt;
&lt;p&gt;Once Homebrew has finished installing, &lt;strong&gt;return to your terminal and run the following command&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight sh&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class=&quot;gp&quot;&gt;$&lt;/span&gt; brew install python3
&lt;/pre&gt;&lt;/div&gt;

&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; When you copy this command, be sure you don&amp;rsquo;t include the &lt;code&gt;$&lt;/code&gt; character at the beginning. That&amp;rsquo;s just an indicator that this is a console command.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;This will download and install the latest version of Python. After the Homebrew &lt;code&gt;brew install&lt;/code&gt; command finishes, Python 3 should be installed on your system.&lt;/p&gt;
&lt;p&gt;You can make sure everything went correctly by testing if Python can be accessed from the terminal:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Open the terminal by launching &lt;strong&gt;Terminal.app&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Type &lt;code&gt;pip3&lt;/code&gt; and hit &lt;span class=&quot;keys&quot;&gt;&lt;kbd class=&quot;key-enter&quot;&gt;Enter&lt;/kbd&gt;&lt;/span&gt;.&lt;/li&gt;
&lt;li&gt;You should see the help text from Python&amp;rsquo;s &amp;ldquo;Pip&amp;rdquo; package manager. If you get an error message running &lt;code&gt;pip3&lt;/code&gt;, go through the Python install steps again to make sure you have a working Python installation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Assuming everything went well and you saw the output from Pip in your command prompt window&amp;hellip;congratulations! You just installed Python on your system, and you&amp;rsquo;re all set to continue with the next section in this tutorial.&lt;/p&gt;
&lt;h2 id=&quot;ios-iphone-ipad&quot;&gt;iOS (iPhone / iPad)&lt;/h2&gt;
&lt;p&gt;The &lt;a href=&quot;http://omz-software.com/pythonista/&quot;&gt;Pythonista app&lt;/a&gt; for iOS is a full-fledged Python development environment that you can run on your iPhone or iPad. It&amp;rsquo;s basically a combination of a Python editor, documentation, and interpreter rolled into one single app.&lt;/p&gt;
&lt;p&gt;Pythonista is surprisingly fun to use. It&amp;rsquo;s a great little tool when you&amp;rsquo;re stuck without a laptop and want to work on your Python skills on the go. It comes with the complete Python 3 standard library and even includes full documentation you can browse offline.&lt;/p&gt;
&lt;p&gt;To install and set up Pythonista you need to &lt;a href=&quot;https://geo.itunes.apple.com/us/app/pythonista-3/id1085978097?ls=1&amp;amp;mt=8&amp;amp;at=1000lqsw&quot;&gt;download it from the iOS app store&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;android-phones-tablets&quot;&gt;Android (Phones &amp;amp; Tablets)&lt;/h2&gt;
&lt;p&gt;If you have an Android tablet or phone and want to practice Python on the go, there are a several options available. The one that we found most reliably supports Python 3.6 is &lt;a href=&quot;https://play.google.com/store/apps/details?id=ru.iiec.pydroid3&quot;&gt;Pydroid 3&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pydroid 3 features an interpreter you can use for REPL sessions, and it also provides the ability to edit, save, and execute Python code:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://files.realpython.com/media/pydroid3-editor.e249ee239a85.png&quot; target=&quot;_blank&quot;&gt;&lt;img class=&quot;img-fluid mx-auto d-block w-50&quot; src=&quot;https://files.realpython.com/media/pydroid3-editor.e249ee239a85.png&quot; width=&quot;620&quot; height=&quot;480&quot; alt=&quot;Pydroid 3 editor&quot;/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://play.google.com/store/apps/details?id=ru.iiec.pydroid3&quot;&gt;download and install Pydroid 3 from the Google Play store&lt;/a&gt;. There is a free version and also a paid Premium version which supports code prediction and code analysis.&lt;/p&gt;
&lt;h2 id=&quot;online-python-interpreters&quot;&gt;Online Python Interpreters&lt;/h2&gt;
&lt;p&gt;If you want to try out the examples in this tutorial without installing Python on your machine, there are several web sites available where you can interact with a Python interpreter online:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python.org Online Console: &lt;a href=&quot;https://www.python.org/shell&quot;&gt;www.python.org/shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Python Fiddle: &lt;a href=&quot;http://pythonfiddle.com&quot;&gt;pythonfiddle.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Repl.it: &lt;a href=&quot;https://repl.it&quot;&gt;repl.it&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Trinket: &lt;a href=&quot;https://trinket.io&quot;&gt;trinket.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Python Anywhere: &lt;a href=&quot;https://www.pythonanywhere.com/&quot;&gt;www.pythonanywhere.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These cloud-based Python interpreters may not be able to execute some of the more complex examples in this tutorial, but they will be adequate for running most of the simpler ones and may be a nice way to get you started.  More information on using these sites is presented in the next section.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This section provided you with the information you need to gain access to a Python 3 interpreter. You are now ready to head to the next section and begin interacting with Python!&lt;/p&gt;
&lt;div class=&quot;container py-3 series-nav mb-3&quot;&gt;
  &lt;div class=&quot;row justify-content-between&quot;&gt;
    &lt;div class=&quot;col-12 col-md-3 text-left text-muted ml-1&quot;&gt;&lt;a href=&quot;https://realpython.com/python-introduction/&quot;&gt; «&amp;nbsp;Introduction to Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-center text-muted&quot;&gt;&lt;a href=&quot;#&quot;&gt;Installing Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-right text-muted mr-1&quot;&gt;&lt;a href=&quot;https://realpython.com/interacting-with-python/&quot;&gt;Interacting with Python&amp;nbsp;»&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Introduction to Python 3</title>
      <id>https://realpython.com/python-introduction/</id>
      <link href="https://realpython.com/python-introduction/"/>
      <updated>2018-05-21T14:00:00+00:00</updated>
      <summary>An overview of the Python programming language, including a brief history of the development of Python
and reasons why you might select Python as your language of choice.</summary>
      <content type="html">
        &lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt; is a high-level, interpreted scripting language developed in the late 1980s by Guido van Rossum at the National Research Institute for Mathematics and Computer Science in the Netherlands.  The initial version was published at the alt.sources &lt;a href=&quot;https://en.wikipedia.org/wiki/Usenet&quot;&gt;newsgroup&lt;/a&gt; in 1991, and version 1.0 was released in 1994.&lt;/p&gt;
&lt;p&gt;Python 2.0 was released in 2000, and the 2.x versions were the prevalent releases until December 2008.  At that time, the development team made the decision to release version 3.0, which contained a few relatively small but significant changes that were not backward compatible with the 2.x versions.  Python 2 and 3 are very similar, and some features of Python 3 have been backported to Python 2.  But in general, they remain not quite compatible.&lt;/p&gt;
&lt;p&gt;Both Python 2 and 3 have continued to be maintained and developed, with periodic release updates for both.  As of this writing, the most recent versions available are 2.7.15 and 3.6.5.  However, an official &lt;a href=&quot;https://pythonclock.org&quot;&gt;End Of Life date of January 1, 2020&lt;/a&gt; has been established for Python 2, after which time it will no longer be maintained.  If you are a newcomer to Python, it is recommended that you focus on Python 3, as this tutorial will do.&lt;/p&gt;
&lt;p&gt;Python is still maintained by a core development team at the Institute, and Guido is still in charge, having been given the title of BDFL (Benevolent Dictator For Life) by the Python community.  The name Python, by the way, derives not from the snake, but from the British comedy troupe &lt;a href=&quot;https://en.wikipedia.org/wiki/Monty_Python%27s_Flying_Circus&quot;&gt;Monty Python&amp;rsquo;s Flying Circus&lt;/a&gt;, of which Guido was, and presumably still is, a fan.  It is common to find references to Monty Python sketches and movies scattered throughout the Python documentation.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;&lt;p&gt;&lt;strong&gt;Free PDF Download:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/optins/view/python-cheat-sheet-short/&quot; class=&quot;alert-link&quot; data-toggle=&quot;modal&quot; data-target=&quot;#modal-python-cheat-sheet-short&quot; data-focus=&quot;false&quot;&gt;Python 3 Cheat Sheet&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;

&lt;h2 id=&quot;why-choose-python&quot;&gt;Why Choose Python?&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re going to write programs, there are literally dozens of commonly used languages to choose from.  Why choose Python?  Here are some of the features that make Python an appealing choice.&lt;/p&gt;
&lt;h3 id=&quot;python-is-popular&quot;&gt;Python is Popular&lt;/h3&gt;
&lt;p&gt;Python has been growing in popularity over the last few years. The 2018 &lt;a href=&quot;https://insights.stackoverflow.com/survey/2018&quot;&gt;Stack Overflow Developer Survey&lt;/a&gt; ranked Python as the 7th most popular and the number one most wanted technology of the year. &lt;a href=&quot;https://realpython.com/world-class-companies-using-python/&quot;&gt;World-class software development countries around the globe use Python every single day.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;According to &lt;a href=&quot;https://insights.dice.com/2016/02/01/whats-hot-and-not-in-tech-skills/&quot;&gt;research by Dice&lt;/a&gt; Python is also one of the hottest skills to have and the  most popular programming language in the world based on the &lt;a href=&quot;https://pypl.github.io/PYPL.html&quot;&gt;Popularity of Programming Language Index&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Due to the popularity and widespread use of Python as a programming language, Python developers are sought after and paid well. If you&amp;rsquo;d like to dig deeper into &lt;a href=&quot;https://dbader.org/blog/why-learn-python&quot;&gt;Python salary statistics and job opportunities, you can do so here&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;python-is-interpreted&quot;&gt;Python is Interpreted&lt;/h3&gt;
&lt;p&gt;Many languages are compiled, meaning the source code you create needs to be translated into machine code, the language of your computer&amp;rsquo;s processor, before it can be run.  Programs written in an interpreted language are passed straight to an interpreter that runs them directly.&lt;/p&gt;
&lt;p&gt;This makes for a quicker development cycle because you just type in your code and run it, without the intermediate compilation step.&lt;/p&gt;
&lt;p&gt;One potential downside to interpreted languages is execution speed.  Programs that are compiled into the native language of the computer processor tend to run more quickly than interpreted programs.  For some applications that are particularly computationally intensive, like graphics processing or intense number crunching, this can be limiting.&lt;/p&gt;
&lt;p&gt;In practice, however, for most programs, the difference in execution speed is measured in milliseconds, or seconds at most, and not appreciably noticeable to a human user.  The expediency of coding in an interpreted language is typically worth it for most applications.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Further reading:&lt;/strong&gt; See &lt;a href=&quot;https://en.wikipedia.org/wiki/Interpreted_language&quot;&gt;this Wikipedia page&lt;/a&gt; to read more about the differences between interpreted and compiled languages.&lt;/p&gt;
&lt;/div&gt;
&lt;h3 id=&quot;python-is-free&quot;&gt;Python is Free&lt;/h3&gt;
&lt;p&gt;The Python interpreter is developed under an OSI-approved open-source license, making it free to install, use, and distribute, even for commercial purposes.&lt;/p&gt;
&lt;p&gt;A version of the interpreter is available for virtually any platform there is, including all flavors of Unix, Windows, macOS, smartphones and tablets, and probably anything else you ever heard of.  A version even exists for the half dozen people remaining who use OS/2.&lt;/p&gt;
&lt;h3 id=&quot;python-is-portable&quot;&gt;Python is Portable&lt;/h3&gt;
&lt;p&gt;Because Python code is interpreted and not compiled into native machine instructions, code written for one platform will work on any other platform that has the Python interpreter installed.  (This is true of any interpreted language, not just Python.)&lt;/p&gt;
&lt;h3 id=&quot;python-is-simple&quot;&gt;Python is Simple&lt;/h3&gt;
&lt;p&gt;As programming languages go, Python is relatively uncluttered, and the developers have deliberately kept it that way.  &lt;/p&gt;
&lt;p&gt;A rough estimate of the complexity of a language can be gleaned from the number of keywords or reserved words in the language.  These are words that are reserved for special meaning by the compiler or interpreter because they designate specific built-in functionality of the language. &lt;/p&gt;
&lt;p&gt;Python 3 has 33 keywords, and Python 2 has 31.  By contrast, C++ has 62, Java has 53, and Visual Basic has more than 120, though these latter examples probably vary somewhat by implementation or dialect.&lt;/p&gt;
&lt;p&gt;Python code has a simple and clean structure that is easy to learn and easy to read.  In fact, as you will see, the language definition enforces code structure that is easy to read.&lt;/p&gt;
&lt;h3 id=&quot;but-its-not-that-simple&quot;&gt;But It&amp;rsquo;s Not That Simple&lt;/h3&gt;
&lt;p&gt;For all its syntactical simplicity, Python supports most constructs that would be expected in a very high-level language, including complex dynamic data types, structured and functional programming, and &lt;a href=&quot;https://realpython.com/python3-object-oriented-programming/&quot;&gt;object-oriented programming&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Additionally, a very extensive library of classes and functions is available that provides capability well beyond what is built into the language, such as database manipulation or GUI programming.&lt;/p&gt;
&lt;p&gt;Python accomplishes what many programming languages don&amp;rsquo;t: the language itself is simply designed, but it is very versatile in terms of what you can accomplish with it.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This section gave an overview of the &lt;strong&gt;Python&lt;/strong&gt; programming language, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A brief history of the development of Python&lt;/li&gt;
&lt;li&gt;Some reasons why you might select Python as your language of choice&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Python is a great option, whether you are a beginning programmer looking to learn the basics, an experienced programmer designing a large application, or anywhere in between.  The basics of Python are easily grasped, and yet its capabilities are vast.&lt;/p&gt;
&lt;p&gt;Proceed to the next section to learn how to acquire and install Python on your computer.&lt;/p&gt;
&lt;div class=&quot;container py-3 series-nav mb-3&quot;&gt;
  &lt;div class=&quot;row justify-content-between&quot;&gt;
    &lt;div class=&quot;col-12 col-md-3 text-left text-muted ml-1&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-center text-muted&quot;&gt;&lt;a href=&quot;#&quot;&gt;Introduction to Python&lt;/a&gt;&lt;/div&gt;
    &lt;div class=&quot;col-12 col-md-3 text-right text-muted mr-1&quot;&gt;&lt;a href=&quot;https://realpython.com/installing-python/&quot;&gt;Installing Python&amp;nbsp;»&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  

</feed>
