diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..fd4c7d6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,108 @@ +# How to Contribute to CS-Tutorial + +## Working on a new feature or fixing a bug + +If you would like to add a new feature or fix an existing bug, we prefer that you open a new issue on the CS-Tutorial repository before creating a pull request. + +It’s important to note that when opening an issue, you should first do a quick search of existing issues to make sure your suggestion hasn’t already been added as an issue. + +**To open a Github issue, go to the CS-Tutorial repository, select “Issues”, “New Issue” then “Feature Request” or “Bug Report” and fill out the template.** + +The CS-Tutorial team will then get in touch with you to discuss if the proposed feature aligns with the roadmap, and we will guide you along the way in shaping the proposed feature so that it could be merged to the CS-Tutorial codebase. + +## What is a Pull Request (PR)? + +This is how the GitHub team defines a PR: + +> “Pull requests let you tell others about changes you’ve pushed to a branch in a repository on GitHub. Once a pull request is opened, you can discuss and review the potential changes with collaborators and add follow-up commits before your changes are merged into the base branch.” + +This process is used by both CS-Tutorial team members and CS-Tutorial contributors to make changes and improvements to CS-Tutorial. + +## What to know before opening a PR + +### Draft PRs + +If you're ready to get some quick initial feedback from the CS-Tutorial team, you can create a draft pull request. + +### PRs should be a reasonable length + +If your PR is greater than 500 lines, please consider splitting it into multiple smaller contributions. + + +## How to open a PR and contribute code to CS-Tutorial Open Source + +### 1. Forking the CS-Tutorial Repository + +Head to CS-Tutorial repository and click ‘Fork’. Forking a repository creates you a copy of the project which you can edit and use to propose changes to the original project. + +Once you fork it, a copy of the CS-Tutorial repository will appear inside your GitHub repository list. + +### 2. Cloning the Forked Repository Locally + +To make changes to your copy of the CS-Tutorial repository, clone the repository on your local machine. To do that, run the following command in your terminal: + +``` +git clone https://github.com/hejazizo/CS-Tutorial.git +``` + +The link to the repository can be found after clicking Clone or download button as shown in the image below: + +Note: this assumes you have git installed on your local machine. If not, check out the [following guide](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) to learn how to install it. + +### 3. Update your Forked Repository + +Before you make any changes to your cloned repository, make sure you have the latest version of the original https://github.com/hejazizo/CS-Tutorial.git repository. To do that, run the following commands in your terminal: + +``` +cd CS-Tutorial +git remote add upstream https://github.com/hejazizo/CS-Tutorial.git +git pull upstream main +``` + +This will update the local copy of the CS-Tutorial repository to the latest version. + +### 4. Implement your code contribution + +At this point, you are good to make changes to the files in the local directory of your project. + +Alternatively, you can create a new branch which will contain the implementation of your contribution. To do that, run: + +``` +git checkout -b name-of-your-new-branch +``` + +### 5. Push changes to your forked repository on GitHub + +Once you are happy with the changes you made in the local files, push them to the forked repository on GitHub. To do that, run the following commands: + +``` +git add . +git commit -m ‘fixed a bug’ +git push origin name-of-your-new-branch +``` + +This will create a new branch on your forked CS-Tutorial repository, and now you’re ready to create a Pull Request with your proposed changes! + +### 6. Opening the Pull Request on CS-Tutorial + +Head to the forked repository and click on a _Compare & pull_ request button. + +This will open a window where you can choose the repository and branch you would like to propose your changes to, as well as specific details of your contribution. In the top panel menu choose the following details: + +- Base repository: `hejazizo/cs-tutorial` +- Base branch: `main` +- Head repository: `your-github-username/cs-tutorial` +- Head branch: `name-of-your-new-branch` + +Once you are happy with everything, click the _Create pull request_ button. This will create a Pull Request with your proposed changes. + +### 8. Merging your PR and the final steps of your contribution + +Once you open a PR, a member from the CS-Tutorial team will get in touch with you with the feedback on your contribution. In some cases, contributions are accepted right away, but often, you may be asked to make some edits/improvements. Don’t worry if you are asked to change something - it’s a completely normal part of software development. + +If you have been requested to make changes to your contribution, head back to the local copy of your repository on your machine, implement the changes and push them to your contribution branch by repeating instructions from step 5. Your pull request will automatically be updated with the changes you pushed. Once you've implemented all of the suggested changes, tag the person who first reviewed your contribution by mentioning them in the comments of your PR to ask them to take another look. +Finally, if your contribution is accepted, the CS-Tutorial team member will merge it to the CS-Tutorial codebase. + +### 10. Non-code contributions + +Contributing doesn’t start and end with code. You can support the project by planning community events, creating tutorials, helping fellow community members find answers to their questions or translating documentation and news. Every contribution matters! diff --git a/python/01. Basics/00 Introduction.ipynb b/Python/01. Basics/01 Introduction.ipynb similarity index 75% rename from python/01. Basics/00 Introduction.ipynb rename to Python/01. Basics/01 Introduction.ipynb index dd798b6..3279a57 100755 --- a/python/01. Basics/00 Introduction.ipynb +++ b/Python/01. Basics/01 Introduction.ipynb @@ -4,7 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Introduction\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Introduction \n", "\n", "- Python was created in 1990 by [Guido van Rossum](https://en.wikipedia.org/wiki/Guido_van_Rossum).\n", "- Python 3 released in 2008.\n", @@ -12,6 +19,27 @@ "- High focus on readability of code." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents\n", + "\n", + "\n", + "* [Why Choose Python](#why_choose_python)\n", + " * [Python is Popular](#python_is_popular)\n", + " * [Python is Interpreted](#python_is_interpreted)\n", + " * [Python is Free](#python_is_free)\n", + " * [Python is Portable](#python_is_portable)\n", + " * [Python is Simple](#python_is_simple)\n", + " * [But It’s Not That Simple](#but_it’s_not_that_simple)\n", + "* [What can you do with python?](#what_can_you_do_with_python?)\n", + "* [ Conclusion](#conclusion)\n", + "\n", + "---" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -44,7 +72,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Why Choose Python\n", + "\n", + "## Why Choose Python [](#table_of_contents)\n", "\n", "If you’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." ] @@ -53,7 +82,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Python is Popular\n", + "# \n", + "### Python is Popular [](#table_of_contents)\n", + "\n", "Python has been growing in popularity over the last few years. The [2018 Stack Overflow Developer Survey](https://insights.stackoverflow.com/survey/2018) ranked Python as the 7th most popular and the number one most wanted technology of the year. [World-class software development companies around the globe use Python every single day](https://realpython.com/world-class-companies-using-python/).\n", "\n", "According to [research by Dice](https://insights.dice.com/2016/02/01/whats-hot-and-not-in-tech-skills/) Python is also one of the hottest skills to have and the most popular programming language in the world based on the [Popularity of Programming Language Index](https://pypl.github.io/PYPL.html).\n", @@ -65,7 +96,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Python is Interpreted\n", + "\n", + "### Python is Interpreted [](#table_of_contents)\n", + "\n", "Many languages are compiled, meaning the source code you create needs to be translated into machine code, the language of your computer’s processor, before it can be run. Programs written in an interpreted language are passed straight to an interpreter that runs them directly.\n", "\n", "This makes for a quicker development cycle because you just type in your code and run it, without the intermediate compilation step.\n", @@ -86,7 +119,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Python is Free\n", + "\n", + "### Python is Free [](#table_of_contents)\n", + "\n", "The Python interpreter is developed under an OSI-approved open-source license, making it free to install, use, and distribute, even for commercial purposes.\n", "\n", "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." @@ -96,7 +131,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Python is Portable\n", + "\n", + "### Python is Portable [](#table_of_contents)\n", + "\n", "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.)" ] }, @@ -104,7 +141,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Python is Simple\n", + "\n", + "### Python is Simple [](#table_of_contents)\n", + "\n", "As programming languages go, Python is relatively uncluttered, and the developers have deliberately kept it that way.\n", "\n", "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.\n", @@ -118,7 +157,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### But It’s Not That Simple\n", + "\n", + "### But It’s Not That Simple [](#table_of_contents)\n", + "\n", "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 [object-oriented programming](https://realpython.com/python3-object-oriented-programming/).\n", "\n", "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.\n", @@ -130,7 +171,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## What can you do with python?\n", + "\n", + "## What can you do with python? [](#table_of_contents)\n", + "\n", "- Automate Simple tasks.\n", " * Searching for file and editing them.\n", " * Scraping information from a website.\n", @@ -152,13 +195,22 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Conclusion\n", + "\n", + "## Conclusion [](#table_of_contents)\n", + "\n", "This section gave an overview of the Python programming language, including:\n", "\n", "A brief history of the development of Python\n", "Some reasons why you might select Python as your language of choice\n", "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." ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -177,7 +229,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/python/01. Basics/02 Conda Environments.ipynb b/Python/01. Basics/02 Conda Environments.ipynb similarity index 90% rename from python/01. Basics/02 Conda Environments.ipynb rename to Python/01. Basics/02 Conda Environments.ipynb index 1ff6137..31388fb 100755 --- a/python/01. Basics/02 Conda Environments.ipynb +++ b/Python/01. Basics/02 Conda Environments.ipynb @@ -2,38 +2,46 @@ "cells": [ { "cell_type": "markdown", - "id": "d4a95e9d", "metadata": {}, "source": [ - "# Conda Environments" + "" ] }, { "cell_type": "markdown", - "id": "scheduled-witness", "metadata": {}, "source": [ + "# Conda Environments \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", "## Table of Contents\n", - "* [1. Understanding Conda Environments](#u-conda-environments)\n", - "* [2. Understanding Basic Package Management With Conda](#basic-package-management)\n", - " * [2.1 Searching and Installing Packages](#search-install-packager)\n", - " * [2.2 Updating and Removing Packages](#u-r-packages)\n", - "* [3. Cheat Sheet](#cheat-sheet)\n", - "* [4. Read More](#read-more)" + "\n", + "\n", + "* [Understanding Conda Environments](#understanding_conda_environments)\n", + "* [Understanding Basic Package Management With Conda](#understanding_basic_package_management_with_conda)\n", + " * [Searching and Installing Packages](#searching_and_installing_packages)\n", + " * [Updating and Removing Packages](#updating_and_removing_packages)\n", + "* [Cheat Sheet](#cheat_sheet)\n", + "* [ Read More](#read_more)\n", + "\n", + "---" ] }, { "cell_type": "markdown", - "id": "successful-abortion", "metadata": {}, "source": [ - " \n", - "## Understanding Conda Environments" + "\n", + "## Understanding Conda Environments [](#table_of_contents)" ] }, { "cell_type": "markdown", - "id": "reported-recovery", "metadata": {}, "source": [ "When you start developing a project from scratch, it’s recommended that you use the latest versions of the libraries you need. However, when working with someone else’s project, such as when running an example from [Kaggle](https://www.kaggle.com/) or [Github](https://github.com/), you may need to install specific versions of packages or even another version of Python due to compatibility issues." @@ -41,7 +49,6 @@ }, { "cell_type": "markdown", - "id": "critical-tenant", "metadata": {}, "source": [ "This problem may also occur when you try to run an application you’ve developed long ago, which uses a particular library version that does not work with your application anymore due to updates." @@ -49,7 +56,6 @@ }, { "cell_type": "markdown", - "id": "lovely-korea", "metadata": {}, "source": [ "Virtual environments are a solution to this kind of problem. By using them, it is possible to create multiple environments, each one with different versions of packages. A typical Python set up includes [Virtualenv](https://virtualenv.pypa.io/en/stable/#), a tool to create isolated Python virtual environments, widely used in the Python community." @@ -57,7 +63,6 @@ }, { "cell_type": "markdown", - "id": "frozen-pavilion", "metadata": {}, "source": [ "Conda includes its own environment manager and presents some advantages over Virtualenv, especially concerning numerical applications, such as the ability to manage non-Python dependencies and the ability to manage different versions of Python, which is not possible with Virtualenv. Besides that, Conda environments are entirely compatible with default [Python packages](https://realpython.com/python-modules-packages/) that may be installed using pip." @@ -65,7 +70,6 @@ }, { "cell_type": "markdown", - "id": "latter-bankruptcy", "metadata": {}, "source": [ "Miniconda installation provides Conda and a root environment with a version of Python and some basic packages installed. Besides this root environment, it is possible to set up additional environments including different versions of Python and packages." @@ -73,9 +77,9 @@ }, { "cell_type": "markdown", - "id": "inner-allowance", "metadata": {}, "source": [ + "\n", "Using the Anaconda prompt, it is possible to check the available Conda environments by running `conda env list`:\n", "\n", "```bash\n", @@ -90,9 +94,9 @@ }, { "cell_type": "markdown", - "id": "lasting-prevention", "metadata": {}, "source": [ + "\n", "This base environment is the root environment, created by the Miniconda installer. It is possible to create another environment, named `otherenv`, by running `conda create --name otherenv`:\n", "\n", "\n", @@ -123,7 +127,6 @@ }, { "cell_type": "markdown", - "id": "limited-persian", "metadata": {}, "source": [ "As notified after the environment creation process is finished, it is possible to activate the otherenv environment by running `conda activate otherenv`. You’ll notice the environment has changed by the indication between parentheses in the beginning of the prompt:\n", @@ -136,7 +139,6 @@ }, { "cell_type": "markdown", - "id": "roman-multimedia", "metadata": {}, "source": [ "You can open the Python interpreter within this environment by running `python`:\n", @@ -152,7 +154,6 @@ }, { "cell_type": "markdown", - "id": "hired-knife", "metadata": {}, "source": [ "The environment includes Python 3.7.0, the same version included in the root base environment. To exit the Python interpreter, just run `quit()`:\n", @@ -166,7 +167,6 @@ }, { "cell_type": "markdown", - "id": "fatal-lunch", "metadata": {}, "source": [ "To deactivate the otherenv environment and go back to the root base environment, you should run `deactivate`:\n", @@ -180,9 +180,9 @@ }, { "cell_type": "markdown", - "id": "textile-integrity", "metadata": {}, "source": [ + "\n", "As mentioned earlier, Conda allows you to easily create environments with different versions of Python, which is not straightforward with Virtualenv. To include a different Python version within an environment, you have to specify it by using `python=` when running conda create. For example, to create an environment named `py2` with `Python 2.7`, you have to run `conda create --name py2 python=2.7`:\n", "\n", "\n", @@ -229,7 +229,6 @@ }, { "cell_type": "markdown", - "id": "labeled-november", "metadata": {}, "source": [ "As shown by the output of `conda create`, this time some new packages were installed, since the new environment uses Python 2. You can check the new environment indeed uses Python 2 by activating it and running the Python interpreter:\n", @@ -241,9 +240,9 @@ }, { "cell_type": "markdown", - "id": "obvious-cycle", "metadata": {}, "source": [ + "\n", "Now, if you run `conda env list`, you should see the two environments that were created, besides the root base environment:\n", "\n", "```bash\n", @@ -261,9 +260,9 @@ }, { "cell_type": "markdown", - "id": "known-timothy", "metadata": {}, "source": [ + "\n", "In the list, the asterisk indicates the activated environment. It is possible to remove an environment by running `conda remove --name --all`. Since it is not possible to remove an activated environment, you should first deactivate the `py2` environment, to remove it:\n", "\n", "```bash\n", @@ -298,7 +297,6 @@ }, { "cell_type": "markdown", - "id": "widespread-mixture", "metadata": {}, "source": [ "Now that you’ve covered the basics of managing environments with Conda, let’s see how to manage packages within the environments." @@ -306,20 +304,19 @@ }, { "cell_type": "markdown", - "id": "diagnostic-fisher", "metadata": {}, "source": [ - " \n", - "## Understanding Basic Package Management With Conda\n", + "\n", + "## Understanding Basic Package Management With Conda [](#table_of_contents)\n", "\n", "Within each environment, packages of software can be installed using the Conda package manager. The root base environment created by the Miniconda installer includes some packages by default that are not part of Python standard library." ] }, { "cell_type": "markdown", - "id": "enabling-bolivia", "metadata": {}, "source": [ + "\n", "The default installation includes the minimum packages necessary to use Conda. To check the list of installed packages in an environment, you just have to make sure it is activated and run `conda list`. In the root environment, the following packages are installed by default:\n", "\n", "```bash\n", @@ -362,7 +359,6 @@ }, { "cell_type": "markdown", - "id": "indoor-savannah", "metadata": {}, "source": [ "To manage the packages, you should also use Conda. Next, let’s see how to search, install, update, and remove packages using Conda." @@ -370,11 +366,10 @@ }, { "cell_type": "markdown", - "id": "coral-governor", "metadata": {}, "source": [ - " \n", - "### Searching and Installing Packages\n", + "\n", + "### Searching and Installing Packages [](#table_of_contents)\n", "\n", "Packages are installed from repositories called **channels** by Conda, and some default channels are configured by the installer. To search for a specific package, you can run `conda search `. For example, this is how you search for the `keras` package (a machine learning library):\n", "\n", @@ -395,7 +390,6 @@ }, { "cell_type": "markdown", - "id": "cardiovascular-zimbabwe", "metadata": {}, "source": [ "According to the previous output, there are different versions of the package and different builds for each version, such as for Python 3.5 and 3.6." @@ -403,9 +397,9 @@ }, { "cell_type": "markdown", - "id": "mighty-impact", "metadata": {}, "source": [ + "\n", "The previous search shows only exact matches for packages named `keras`. To perform a broader search, including all packages containing `keras` in their names, you should use the wildcard `*`. For example, when you run conda search `*keras*`, you get the following:\n", "\n", "```bash\n", @@ -436,7 +430,6 @@ }, { "cell_type": "markdown", - "id": "simplified-freedom", "metadata": {}, "source": [ "As the previous output shows, there are some other keras related packages in the default channels." @@ -444,9 +437,9 @@ }, { "cell_type": "markdown", - "id": "promising-digest", "metadata": {}, "source": [ + "\n", "To install a package, you should run `conda install `. By default, the newest version of the package will be installed in the active environment. So, let’s install the package `keras` in the environment `otherenv` that you’ve already created:\n", "\n", "```bash\n", @@ -514,7 +507,6 @@ }, { "cell_type": "markdown", - "id": "elementary-milan", "metadata": {}, "source": [ "Conda manages the necessary dependencies for a package when it is installed. Since the package keras has a lot of dependencies, when you install it, Conda manages to install this big list of packages." @@ -522,7 +514,6 @@ }, { "cell_type": "markdown", - "id": "appreciated-australia", "metadata": {}, "source": [ "> **Note:** The paragraph below may not happen when you run it as newer versions of `keras` may be available that use python 3.7.\n", @@ -532,7 +523,6 @@ }, { "cell_type": "markdown", - "id": "seven-filename", "metadata": {}, "source": [ "Sometimes, you don’t want packages to be downgraded, and it would be better to just create a new environment with the necessary version of Python. To check the list of new packages, updates, and downgrades necessary for a package without installing it, you should use the parameter `--dry-run`. For example, to check the packages that will be changed by the installation of the package keras, you should run the following:\n", @@ -544,9 +534,9 @@ }, { "cell_type": "markdown", - "id": "ordinary-member", "metadata": {}, "source": [ + "\n", "However, if necessary, it is possible to change the default Python of a Conda environment by installing a specific version of the package python. To demonstrate that, let’s create a new environment called envpython:\n", "\n", "```bash\n", @@ -576,7 +566,6 @@ }, { "cell_type": "markdown", - "id": "blind-samba", "metadata": {}, "source": [ "As you saw before, since the root base environment uses Python 3.7, envpython is created including this same version of Python:\n", @@ -592,9 +581,9 @@ }, { "cell_type": "markdown", - "id": "dependent-norwegian", "metadata": {}, "source": [ + "\n", "To install a specific version of a package, you can run `conda install =`. For example, this is how you install Python 3.6 in the envpython environment:\n", "\n", "```bash\n", @@ -626,9 +615,9 @@ }, { "cell_type": "markdown", - "id": "infinite-western", "metadata": {}, "source": [ + "\n", "In case you need to install more than one package in an environment, it is possible to run conda install only once, passing the names of the packages. To illustrate that, let’s install `numpy`, `scipy`, and `matplotlib`, basic packages for numerical computation:\n", "\n", "```bash\n", @@ -708,7 +697,6 @@ }, { "cell_type": "markdown", - "id": "impossible-intent", "metadata": {}, "source": [ "Now that you’ve covered how to search and install packages, let’s see how to update and remove them using Conda." @@ -716,20 +704,19 @@ }, { "cell_type": "markdown", - "id": "acting-brief", "metadata": {}, "source": [ - " \n", - "### Updating and Removing Packages\n", + "\n", + "### Updating and Removing Packages [](#table_of_contents)\n", "\n", "Sometimes, when new packages are released, you need to update them. To do so, you may run `conda update `. In case you wish to update all the packages within one environment, you should activate the environment and run `conda update --all`." ] }, { "cell_type": "markdown", - "id": "listed-seeking", "metadata": {}, "source": [ + "\n", "To remove a package, you can run `conda remove `. For example, this is how you remove numpy from the root base environment:\n", "\n", "```bash\n", @@ -758,7 +745,6 @@ }, { "cell_type": "markdown", - "id": "metropolitan-helping", "metadata": {}, "source": [ "> **Note:** It’s worth noting that when you remove a package, all packages that depend on it are also removed." @@ -766,27 +752,24 @@ }, { "cell_type": "markdown", - "id": "satisfactory-fourth", "metadata": {}, "source": [ - " \n", - "## Cheat Sheet\n", + "\n", + "## Cheat Sheet [](#table_of_contents)\n", "\n", "[Click here to get access to a Conda cheat sheet](https://static.realpython.com/conda-cheatsheet.pdf) with handy usage examples for managing your Python environment and packages." ] }, { "cell_type": "markdown", - "id": "confident-dynamics", "metadata": {}, "source": [ - " \n", - "## Read More" + "\n", + "## Read More [](#table_of_contents)\n" ] }, { "cell_type": "markdown", - "id": "silent-hawaii", "metadata": {}, "source": [ "Also, if you’d like a deeper understanding of Anaconda and Conda, check out the following links:\n", @@ -812,7 +795,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/python/01. Basics/03 Interacting with Python.ipynb b/Python/01. Basics/03 Interacting with Python.ipynb similarity index 82% rename from python/01. Basics/03 Interacting with Python.ipynb rename to Python/01. Basics/03 Interacting with Python.ipynb index e8cb5e2..478941d 100755 --- a/python/01. Basics/03 Interacting with Python.ipynb +++ b/Python/01. Basics/03 Interacting with Python.ipynb @@ -4,25 +4,40 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Interacting with Python" + "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ + "# Interacting with Python \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", "## Table of Contents\n", - "* [Hello World!](#hello-world)\n", - "* [Different Ways to Execute Python Code](#execute-python)\n", - " * [1. Using the Python Interpreter Interactively](#python-interpreter)\n", - " * [2. IPython](#ipython)\n", - " * [3. Notebook](#notebook)\n", - " * [4. Online Python REPL Sites](#online-repl)\n", - " * [5. Running a Python Script from the Command Line](#command-line)\n", - " * [6. Interacting with Python through an IDE](#ide)\n", - " * [7. Text Editors](#text-editors)\n", - "* [Conclusion](#conclusion)\n", - "* [FAQ](#faq)" + "\n", + "\n", + "* [Hello, World!](#hello,_world!)\n", + "* [Different Ways to Execute Python Code](#different_ways_to_execute_python_code)\n", + " * [1. Using the Python Interpreter Interactively](#1._using_the_python_interpreter_interactively)\n", + " * [Starting the Interpreter](#starting_the_interpreter)\n", + " * [Executing Python Code](#executing_python_code)\n", + " * [Exiting the Interpreter](#exiting_the_interpreter)\n", + " * [2. IPython](#2._ipython)\n", + " * [3. Notebook](#3._notebook)\n", + " * [4. Online Python REPL Sites](#4._online_python_repl_sites)\n", + " * [5. Running a Python Script from the Command Line](#5._running_a_python_script_from_the_command_line)\n", + " * [6. Interacting with Python through an IDE](#6._interacting_with_python_through_an_ide)\n", + " * [7. Text Editors](#7._text_editors)\n", + "* [ Conclusion](#conclusion)\n", + "* [FAQ](#faq)\n", + "\n", + "---" ] }, { @@ -36,7 +51,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "- There are several ways to run Python code.\n", + "There are several ways to run Python code.\n", "- First let's discuss the various options for development environments. There are 3 main types of environments:\n", " * Text Editors\n", " * Full IDEs\n", @@ -50,8 +65,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "## Hello, World!\n", + "\n", + "## Hello, World! [](#table_of_contents)\n", "\n", "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 Hello, World! to the console." ] @@ -80,16 +95,16 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "## Different Ways to Execute Python Code" + "\n", + "## Different Ways to Execute Python Code [](#table_of_contents)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "### 1. Using the Python Interpreter Interactively\n", + "\n", + "### 1. Using the Python Interpreter Interactively [](#table_of_contents)\n", "\n", "The most straightforward way to start talking to Python is in an interactive [Read-Eval-Print Loop (REPL)](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) environment. That simply means starting up the interpreter and typing commands to it directly. The interpreter:\n", "\n", @@ -105,7 +120,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Starting the Interpreter\n", + "\n", + "#### Starting the Interpreter [](#table_of_contents)\n", "\n", "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’re using:\n", "\n", @@ -147,7 +163,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Executing Python Code\n", + "\n", + "#### Executing Python Code [](#table_of_contents)\n", "\n", "If you are seeing the prompt, you’re off and running! The next step is to execute the statement that displays `Hello, World!` to the console:\n", "\n", @@ -186,7 +203,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Exiting the Interpreter\n", + "\n", + "#### Exiting the Interpreter [](#table_of_contents)\n", + "\n", "When you are finished interacting with the interpreter, you can exit a REPL session in several ways:\n", "\n", "- Type `exit()` and press Enter:\n", @@ -212,8 +231,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "### 2. IPython\n", + "\n", + "### 2. IPython [](#table_of_contents)\n", "\n", "[IPython](https://ipython.org/install.html) is an upgraded Python [read-eval-print loop (REPL)](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop) that makes editing code in a live interpreter session more straightforward and prettier. Here’s what an IPython REPL session looks like:\n", "\n", @@ -258,8 +277,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "### 3. Notebook\n", + "\n", + "### 3. Notebook [](#table_of_contents)\n", "\n", "A slightly more featureful alternative to a REPL is a **notebook**. Notebooks are a slightly different style of writing Python than standard scripts, though. Instead of a traditional Python file, they give you a series of mini-scripts called **cells** that you can run and re-run in whatever order you want, all in the same Python memory session." ] @@ -327,8 +346,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "### 4. Online Python REPL Sites\n", + "\n", + "### 4. Online Python REPL Sites [](#table_of_contents)\n", "\n", "There are [websites available](https://realpython.com/installing-python/#online-python-interpreters) that can provide you with interactive access to a Python interpreter online without you having to install anything locally." ] @@ -371,8 +390,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "### 5. Running a Python Script from the Command Line" + "\n", + "### 5. Running a Python Script from the Command Line [](#table_of_contents)" ] }, { @@ -462,8 +481,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "### 6. Interacting with Python through an IDE\n", + "\n", + "### 6. Interacting with Python through an IDE [](#table_of_contents)\n", "\n", "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." ] @@ -484,8 +503,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "### 7. Text Editors\n", + "\n", + "### 7. Text Editors [](#table_of_contents)\n", "\n", "- General editors for any text files.\n", "- Work with a variety of file types.\n", @@ -523,7 +542,8 @@ "metadata": {}, "source": [ "\n", - "## Conclusion\n", + "## Conclusion [](#table_of_contents)\n", + "\n", "Larger applications are typically contained in script files that are passed to the Python interpreter for execution." ] }, @@ -553,7 +573,7 @@ "metadata": {}, "source": [ "\n", - "## FAQ" + "## FAQ [](#table_of_contents)" ] }, { @@ -602,7 +622,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/python/01. Basics/04 Basic Data Types.ipynb b/Python/01. Basics/04 Basic Data Types.ipynb similarity index 85% rename from python/01. Basics/04 Basic Data Types.ipynb rename to Python/01. Basics/04 Basic Data Types.ipynb index 448b2ea..cf65f8a 100755 --- a/python/01. Basics/04 Basic Data Types.ipynb +++ b/Python/01. Basics/04 Basic Data Types.ipynb @@ -4,29 +4,61 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Basic Data Types" + "" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Now you know how to interact with the Python interpreter and execute Python code. It’s time to dig into the Python language. First up is a discussion of the basic data types that are built into Python." + "# Basic Data Types \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents\n", + "\n", + "* [Integers](#integers)\n", + "* [Floating-Point Numbers](#floating-point_numbers)\n", + "* [Complex Numbers](#complex_numbers)\n", + " * [FAQ](#faq)\n", + "* [Strings](#strings)\n", + " * [Escape Sequences in Strings](#escape_sequences_in_strings)\n", + " * [Suppressing Special Character Meaning](#suppressing_special_character_meaning)\n", + " * [Applying Special Meaning to Characters](#applying_special_meaning_to_characters)\n", + " * [Raw Strings](#raw_strings)\n", + " * [Triple-Quoted Strings](#triple-quoted_strings)\n", + "* [Boolean Type, Boolean Context, and “Truthiness”](#boolean_type,_boolean_context,_and_“truthiness”)\n", + "* [Built-In Functions](#built-in_functions)\n", + " * [Math](#math)\n", + " * [Type Conversion](#type_conversion)\n", + " * [Iterables and Iterators](#iterables_and_iterators)\n", + " * [Composite Data Type](#composite_data_type)\n", + " * [Classes, Attributes, and Inheritance](#classes,_attributes,_and_inheritance)\n", + " * [Input/Output](#input/output)\n", + " * [Variables, References, and Scope](#variables,_references,_and_scope)\n", + " * [Miscellaneous](#miscellaneous)\n", + "* [ Conclusion](#conclusion)\n", + "\n", + "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "## Basic Data Types" + "Now you know how to interact with the Python interpreter and execute Python code. It’s time to dig into the Python language. First up is a discussion of the basic data types that are built into Python." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Integers" + "\n", + "## Integers [](#table_of_contents)\n" ] }, { @@ -270,7 +302,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Floating-Point Numbers\n", + "\n", + "## Floating-Point Numbers [](#table_of_contents)\n", "\n", "The float type in Python designates a floating-point number. `float` values are specified with a decimal point. Optionally, the character `e` or `E` followed by a positive or negative integer may be appended to specify [scientific notation](https://en.wikipedia.org/wiki/Scientific_notation):" ] @@ -453,23 +486,24 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Complex Numbers\n", + "\n", + "## Complex Numbers [](#table_of_contents)\n", "\n", "Complex numbers are specified as `+j`. For example:" ] }, { "cell_type": "code", - "execution_count": 88, + "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "(2+3j)" + "complex" ] }, - "execution_count": 88, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -502,7 +536,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### FAQ\n", + "\n", + "#### FAQ [](#table_of_contents)\n", "\n", "1. What's the difference between floating point and an integer?\n", "\n", @@ -538,7 +573,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Strings\n", + "\n", + "## Strings [](#table_of_contents)\n", "\n", "Strings are sequences of character data. The string type in Python is called `str`." ] @@ -728,7 +764,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Escape Sequences in Strings\n", + "\n", + "### Escape Sequences in Strings [](#table_of_contents)\n", + "\n", + "\n", "Sometimes, you want Python to interpret a character or sequence of characters within a string differently. This may occur in one of two ways:\n", "- You may want to suppress the special interpretation that certain characters are usually given within a string.\n", "- You may want to apply special interpretation to characters in a string which would normally be taken literally." @@ -752,7 +791,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Suppressing Special Character Meaning\n" + "\n", + "#### Suppressing Special Character Meaning [](#table_of_contents)\n", + "\n" ] }, { @@ -960,7 +1001,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Applying Special Meaning to Characters\n", + "\n", + "### Applying Special Meaning to Characters [](#table_of_contents)\n", + "\n", "\n", "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:\n", "\n", @@ -1131,7 +1174,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Raw Strings\n", + "\n", + "### Raw Strings [](#table_of_contents)\n", + "\n", "\n", "A raw string literal is preceded by r or R, which specifies that escape sequences in the associated string are not translated. The backslash character is left in the string:" ] @@ -1209,7 +1254,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Triple-Quoted Strings\n", + "\n", + "### Triple-Quoted Strings [](#table_of_contents)\n", + "\n", "\n", "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:" ] @@ -1265,7 +1312,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Boolean Type, Boolean Context, and “Truthiness”" + "\n", + "## Boolean Type, Boolean Context, and “Truthiness” [](#table_of_contents)" ] }, { @@ -1340,7 +1388,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Built-In Functions\n", + "\n", + "## Built-In Functions [](#table_of_contents)\n", + "\n", "\n", "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." ] @@ -1356,7 +1406,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Math\n", + "\n", + "### Math [](#table_of_contents)\n", + "\n", "\n", "|Function | Description |\n", "|:--|:--|\n", @@ -1373,7 +1425,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Type Conversion\n", + "\n", + "### Type Conversion [](#table_of_contents)\n", + "\n", "\n", "| Function | Description |\n", "|:--|:--|\n", @@ -1396,7 +1450,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Iterables and Iterators\n", + "\n", + "### Iterables and Iterators [](#table_of_contents)\n", + "\n", + "\n", "|Function | Description|\n", "|:--|:--|\n", "|`all()`| Returns True if all elements of an iterable are true|\n", @@ -1418,7 +1475,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Composite Data Type\n", + "\n", + "### Composite Data Type [](#table_of_contents)\n", + "\n", + "\n", "|Function | Description|\n", "|:--|:--|\n", "| `bytearray()` | \tCreates and returns an object of the bytearray class |\n", @@ -1435,7 +1495,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Classes, Attributes, and Inheritance\n", + "\n", + "### Classes, Attributes, and Inheritance [](#table_of_contents)\n", + "\n", + "\n", "|Function | Description|\n", "|:--|:--|\n", "| `classmethod()` |\tReturns a class method for a function |\n", @@ -1453,7 +1516,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Input/Output\n", + "\n", + "### Input/Output [](#table_of_contents)\n", + "\n", + "\n", "|Function | Description|\n", "|:--|:--|\n", "|`format()` |\tConverts a value to a formatted representation |\n", @@ -1466,7 +1532,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Variables, References, and Scope\n", + "\n", + "### Variables, References, and Scope [](#table_of_contents)\n", + "\n", + "\n", "|Function | Description|\n", "|:--|:--|\n", "|`dir()` | Returns a list of names in current local scope or a list of object attributes |\n", @@ -1480,7 +1549,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Miscellaneous\n", + "\n", + "### Miscellaneous [](#table_of_contents)\n", + "\n", + "\n", "|Function | Description|\n", "|:--|:--|\n", "|`callable()` | Returns True if object appears callable |\n", @@ -1498,13 +1570,23 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Conclusion\n", + "\n", + "## Conclusion [](#table_of_contents)\n", + "\n", + "\n", "In this section, you learned about the built-in data types and functions Python provides.\n", "\n", "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.\n", "\n", "Head to the next section to learn about Python variables." ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -1523,7 +1605,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/python/01. Basics/05 Variables.ipynb b/Python/01. Basics/05 Variables.ipynb similarity index 88% rename from python/01. Basics/05 Variables.ipynb rename to Python/01. Basics/05 Variables.ipynb index 6a6dbc1..3d6bd3b 100755 --- a/python/01. Basics/05 Variables.ipynb +++ b/Python/01. Basics/05 Variables.ipynb @@ -2,18 +2,42 @@ "cells": [ { "cell_type": "markdown", - "id": "a55f4b8f", "metadata": {}, "source": [ - "# Variables in Python\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Variables in Python \n", "\n", "In the previous tutorial on Basic Data Types in Python, 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:" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents\n", + "\n", + "\n", + "* [Variable Assignment](#variable_assignment)\n", + "* [Variable Types in Python](#variable_types_in_python)\n", + "* [Object References](#object_references)\n", + "* [Object Identity](#object_identity)\n", + "* [Variable Names](#variable_names)\n", + "* [Reserved Words (Keywords)](#reserved_words_(keywords))\n", + "* [ Conclusion](#conclusion)\n", + "\n", + "---" + ] + }, { "cell_type": "code", "execution_count": 1, - "id": "73ada819", "metadata": {}, "outputs": [ { @@ -30,7 +54,6 @@ }, { "cell_type": "markdown", - "id": "a369bcd2", "metadata": {}, "source": [ "If you’re writing more complex code, your program will need data that can change as program execution proceeds." @@ -38,10 +61,11 @@ }, { "cell_type": "markdown", - "id": "90e3c3d7", "metadata": {}, "source": [ - "## Variable Assignment\n", + "\n", + "## Variable Assignment [](#table_of_contents)\n", + "\n", "\n", "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 (`=`):" ] @@ -49,7 +73,6 @@ { "cell_type": "code", "execution_count": 4, - "id": "b6f94fff", "metadata": {}, "outputs": [], "source": [ @@ -58,7 +81,6 @@ }, { "cell_type": "markdown", - "id": "e4f4f1fa", "metadata": {}, "source": [ "This is read or interpreted as “n is assigned the value 300.” Once this is done, n can be used in a statement or expression, and its value will be substituted:" @@ -67,7 +89,6 @@ { "cell_type": "code", "execution_count": 6, - "id": "659a5389", "metadata": {}, "outputs": [ { @@ -84,7 +105,6 @@ }, { "cell_type": "markdown", - "id": "5f17dad1", "metadata": {}, "source": [ "Just as a literal value can be displayed directly from the interpreter prompt in a REPL session without the need for `print()`, so can a variable:" @@ -93,7 +113,6 @@ { "cell_type": "code", "execution_count": 4, - "id": "2a6a7f6d", "metadata": {}, "outputs": [ { @@ -113,7 +132,6 @@ }, { "cell_type": "markdown", - "id": "9d6c6a97", "metadata": {}, "source": [ "Later, if you change the value of `n` and use it again, the new value will be substituted instead:" @@ -122,7 +140,6 @@ { "cell_type": "code", "execution_count": 5, - "id": "6bd9d37e", "metadata": {}, "outputs": [], "source": [ @@ -132,7 +149,6 @@ { "cell_type": "code", "execution_count": 6, - "id": "1aa1a866", "metadata": {}, "outputs": [ { @@ -150,7 +166,6 @@ { "cell_type": "code", "execution_count": 7, - "id": "4556ebb9", "metadata": {}, "outputs": [ { @@ -170,7 +185,6 @@ }, { "cell_type": "markdown", - "id": "62a2e72c", "metadata": {}, "source": [ "Python also allows chained assignment, which makes it possible to assign the same value to several variables simultaneously:" @@ -179,7 +193,6 @@ { "cell_type": "code", "execution_count": 15, - "id": "9bc7a297", "metadata": {}, "outputs": [], "source": [ @@ -189,7 +202,6 @@ { "cell_type": "code", "execution_count": 16, - "id": "410b6037", "metadata": {}, "outputs": [ { @@ -206,7 +218,6 @@ }, { "cell_type": "markdown", - "id": "e502bf9e", "metadata": {}, "source": [ "The chained assignment above assigns 300 to the variables `a`, `b`, and `c` simultaneously." @@ -214,17 +225,17 @@ }, { "cell_type": "markdown", - "id": "1b58f80f", "metadata": {}, "source": [ - "## Variable Types in Python\n", + "\n", + "## Variable Types in Python [](#table_of_contents)\n", + "\n", "\n", "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." ] }, { "cell_type": "markdown", - "id": "ef366d10", "metadata": {}, "source": [ "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:" @@ -233,7 +244,6 @@ { "cell_type": "code", "execution_count": 17, - "id": "62406cb7", "metadata": {}, "outputs": [], "source": [ @@ -243,7 +253,6 @@ { "cell_type": "code", "execution_count": 18, - "id": "98a95bde", "metadata": {}, "outputs": [ { @@ -264,7 +273,6 @@ { "cell_type": "code", "execution_count": 18, - "id": "f60605cf", "metadata": {}, "outputs": [ { @@ -282,7 +290,6 @@ { "cell_type": "code", "execution_count": 19, - "id": "0fa521ba", "metadata": {}, "outputs": [], "source": [ @@ -292,7 +299,6 @@ { "cell_type": "code", "execution_count": 20, - "id": "f3e7bb1e", "metadata": {}, "outputs": [ { @@ -309,17 +315,17 @@ }, { "cell_type": "markdown", - "id": "62f69cdc", "metadata": {}, "source": [ - "## Object References\n", + "\n", + "## Object References [](#table_of_contents)\n", + "\n", "\n", "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’d find in many other programming languages." ] }, { "cell_type": "markdown", - "id": "685bda63", "metadata": {}, "source": [ "Python is a highly [object-oriented language](https://realpython.com/python3-object-oriented-programming/). 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.)" @@ -327,7 +333,6 @@ }, { "cell_type": "markdown", - "id": "59dca951", "metadata": {}, "source": [ "Consider this code:" @@ -336,7 +341,6 @@ { "cell_type": "code", "execution_count": 5, - "id": "c4762544", "metadata": {}, "outputs": [ { @@ -353,7 +357,6 @@ }, { "cell_type": "markdown", - "id": "728f46fa", "metadata": {}, "source": [ "When presented with the statement `print(300)`, the interpreter does the following:\n", @@ -365,7 +368,6 @@ }, { "cell_type": "markdown", - "id": "16e1ea59", "metadata": {}, "source": [ "You can see that an integer object is created using the built-in `type()` function:" @@ -374,7 +376,6 @@ { "cell_type": "code", "execution_count": 22, - "id": "c707a7dd", "metadata": {}, "outputs": [ { @@ -394,7 +395,6 @@ }, { "cell_type": "markdown", - "id": "f13f3e7f", "metadata": {}, "source": [ "A Python variable is a symbolic name that is a reference or [pointer](https://realpython.com/pointers-in-python/) 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." @@ -402,7 +402,6 @@ }, { "cell_type": "markdown", - "id": "ada11109", "metadata": {}, "source": [ "For example:" @@ -411,7 +410,6 @@ { "cell_type": "code", "execution_count": 40, - "id": "0a722e9e", "metadata": {}, "outputs": [], "source": [ @@ -420,7 +418,6 @@ }, { "cell_type": "markdown", - "id": "b8ca1dee", "metadata": {}, "source": [ "This assignment creates an integer object with the value `300` and assigns the variable `n` to point to that object." @@ -428,7 +425,6 @@ }, { "cell_type": "markdown", - "id": "95705a19", "metadata": {}, "source": [ "\"int-pointer\"" @@ -436,7 +432,6 @@ }, { "cell_type": "markdown", - "id": "22951859", "metadata": {}, "source": [ "The following code verifies that `n` points to an integer object:" @@ -445,7 +440,6 @@ { "cell_type": "code", "execution_count": 23, - "id": "46ec7241", "metadata": {}, "outputs": [ { @@ -465,7 +459,6 @@ }, { "cell_type": "markdown", - "id": "c7cda3d9", "metadata": {}, "source": [ "Now consider the following statement:" @@ -474,7 +467,6 @@ { "cell_type": "code", "execution_count": 26, - "id": "1a189f08", "metadata": {}, "outputs": [], "source": [ @@ -483,7 +475,6 @@ }, { "cell_type": "markdown", - "id": "027e3b78", "metadata": {}, "source": [ "What happens when it is executed? Python does not create another object. It simply creates a new symbolic name or reference, `m`, which points to the same object that `n` points to." @@ -491,7 +482,6 @@ }, { "cell_type": "markdown", - "id": "31b5337d", "metadata": {}, "source": [ "\"int-pointer\"" @@ -499,7 +489,6 @@ }, { "cell_type": "markdown", - "id": "9a115aed", "metadata": {}, "source": [ "Next, suppose you do this:" @@ -508,7 +497,6 @@ { "cell_type": "code", "execution_count": 27, - "id": "a71ed9aa", "metadata": {}, "outputs": [], "source": [ @@ -517,7 +505,6 @@ }, { "cell_type": "markdown", - "id": "3e709f8a", "metadata": {}, "source": [ "Now Python creates a new integer object with the value 400, and m becomes a reference to it." @@ -525,7 +512,6 @@ }, { "cell_type": "markdown", - "id": "ae298100", "metadata": {}, "source": [ "\"int-pointer-m-n.png\"" @@ -533,7 +519,6 @@ }, { "cell_type": "markdown", - "id": "4c76d609", "metadata": {}, "source": [ "Lastly, suppose this statement is executed next:" @@ -542,7 +527,6 @@ { "cell_type": "code", "execution_count": 75, - "id": "6d83f4dc", "metadata": {}, "outputs": [], "source": [ @@ -551,7 +535,6 @@ }, { "cell_type": "markdown", - "id": "84361b93", "metadata": {}, "source": [ "Now Python creates a string object with the value `\"foo\"` and makes `n` reference that." @@ -559,7 +542,6 @@ }, { "cell_type": "markdown", - "id": "a2fae845", "metadata": {}, "source": [ "\"int-string-pointer.png\"" @@ -567,7 +549,6 @@ }, { "cell_type": "markdown", - "id": "3b740cee", "metadata": {}, "source": [ "There is no longer any reference to the integer object 300. It is orphaned, and there is no way to access it." @@ -575,7 +556,6 @@ }, { "cell_type": "markdown", - "id": "f0fc675b", "metadata": {}, "source": [ "Tutorials in this series will occasionally refer to the lifetime of an object. An object’s life begins when it is created, at which time at least one reference to it is created. During an object’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." @@ -583,7 +563,6 @@ }, { "cell_type": "markdown", - "id": "86c07d02", "metadata": {}, "source": [ "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 [garbage collection](https://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29)." @@ -591,18 +570,18 @@ }, { "cell_type": "markdown", - "id": "d9cc212c", "metadata": {}, "source": [ - "## Object Identity\n", + "\n", + "## Object Identity [](#table_of_contents)\n", + "\n", "\n", "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’s reference count drops to zero and it is garbage collected, as happened to the `300` object above, then its identifying number becomes available and may be used again." ] }, { "cell_type": "code", - "execution_count": 41, - "id": "e02aa413", + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -611,7 +590,6 @@ }, { "cell_type": "markdown", - "id": "efe835b7", "metadata": {}, "source": [ "The built-in Python function `id()` returns an object’s integer identifier. Using the `id()` function, you can verify that two variables indeed point to the same object:" @@ -619,8 +597,7 @@ }, { "cell_type": "code", - "execution_count": 26, - "id": "aee3dbe1", + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -630,17 +607,16 @@ }, { "cell_type": "code", - "execution_count": 27, - "id": "c1d721b9", + "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "139989024260592" + "140238739082320" ] }, - "execution_count": 27, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -651,17 +627,65 @@ }, { "cell_type": "code", - "execution_count": 28, - "id": "f5457fa1", + "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "139989024260592" + "140238739082320" ] }, - "execution_count": 28, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "id(m)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "m is n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "m = 300" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "140238472208624" + ] + }, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -673,7 +697,6 @@ { "cell_type": "code", "execution_count": 30, - "id": "dad48b6d", "metadata": {}, "outputs": [], "source": [ @@ -683,7 +706,6 @@ { "cell_type": "code", "execution_count": 31, - "id": "467b9feb", "metadata": {}, "outputs": [ { @@ -703,7 +725,6 @@ }, { "cell_type": "markdown", - "id": "182c51cd", "metadata": {}, "source": [ "After the assignment `m = n`, m and n both point to the same object, confirmed by the fact that `id(m)` and `id(n)` return the same number. Once `m` is reassigned to `400`, `m` and `n` point to different objects with different identities." @@ -711,7 +732,6 @@ }, { "cell_type": "markdown", - "id": "4beb1faa", "metadata": {}, "source": [ "> **Deep Dive: Caching Small Integer Values**\n", @@ -746,17 +766,17 @@ }, { "cell_type": "markdown", - "id": "554ec3b2", "metadata": {}, "source": [ - "## Variable Names\n", + "\n", + "## Variable Names [](#table_of_contents)\n", + "\n", "\n", "The examples you have seen so far have used short, terse variable names like `m` and `n`. 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." ] }, { "cell_type": "markdown", - "id": "e82b25ba", "metadata": {}, "source": [ "Officially, variable names in Python can be any length and can consist of uppercase and lowercase letters (`A-Z, a-z`), digits (`0-9`), and the underscore character (`_`). An additional restriction is that, although a variable name can contain digits, the first character of a variable name cannot be a digit." @@ -764,7 +784,6 @@ }, { "cell_type": "markdown", - "id": "0613da94", "metadata": {}, "source": [ "For example, all of the following are valid variable names:" @@ -773,7 +792,6 @@ { "cell_type": "code", "execution_count": 124, - "id": "71ff48d3", "metadata": {}, "outputs": [], "source": [ @@ -785,7 +803,6 @@ { "cell_type": "code", "execution_count": 125, - "id": "9262196a", "metadata": {}, "outputs": [ { @@ -802,7 +819,6 @@ }, { "cell_type": "markdown", - "id": "b6186f85", "metadata": {}, "source": [ "But this one is not, because a variable name can’t begin with a digit:" @@ -811,7 +827,6 @@ { "cell_type": "code", "execution_count": 64, - "id": "b8f5a16d", "metadata": {}, "outputs": [ { @@ -829,7 +844,6 @@ }, { "cell_type": "markdown", - "id": "357c83fe", "metadata": {}, "source": [ "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:" @@ -838,7 +852,6 @@ { "cell_type": "code", "execution_count": 132, - "id": "30bd1c5e", "metadata": {}, "outputs": [], "source": [ @@ -855,7 +868,6 @@ { "cell_type": "code", "execution_count": 133, - "id": "73d8b415", "metadata": {}, "outputs": [ { @@ -872,7 +884,6 @@ }, { "cell_type": "markdown", - "id": "5705d917", "metadata": {}, "source": [ "There is nothing stopping you from creating two different variables in the same program called `age` and `Age`, or for that matter `agE`. 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’d been away from it awhile." @@ -880,7 +891,6 @@ }, { "cell_type": "markdown", - "id": "75073119", "metadata": {}, "source": [ "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:" @@ -889,7 +899,6 @@ { "cell_type": "code", "execution_count": 37, - "id": "0410fffa", "metadata": {}, "outputs": [], "source": [ @@ -903,7 +912,6 @@ { "cell_type": "code", "execution_count": 38, - "id": "e5ccd23e", "metadata": {}, "outputs": [ { @@ -922,7 +930,6 @@ }, { "cell_type": "markdown", - "id": "c15edc69", "metadata": {}, "source": [ "All of them are probably better choices than n, or ncg, or the like. At least you can tell from the name what the value of the variable is supposed to represent." @@ -930,7 +937,6 @@ }, { "cell_type": "markdown", - "id": "c088f09d", "metadata": {}, "source": [ "On the other hand, they aren’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:\n", @@ -946,7 +952,6 @@ }, { "cell_type": "markdown", - "id": "7c3741c2", "metadata": {}, "source": [ "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." @@ -954,7 +959,6 @@ }, { "cell_type": "markdown", - "id": "b23e6fa7", "metadata": {}, "source": [ "You will see later that variables aren’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." @@ -962,7 +966,6 @@ }, { "cell_type": "markdown", - "id": "5ef84fed", "metadata": {}, "source": [ "The [Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/), also known as [PEP 8](https://www.python.org/dev/peps/pep-0008/#naming-conventions), contains Naming Conventions that list suggested standards for names of different object types. PEP 8 includes the following recommendations:\n", @@ -973,16 +976,17 @@ }, { "cell_type": "markdown", - "id": "2e62149e", "metadata": {}, "source": [ - "## Reserved Words (Keywords)\n", + "\n", + "## Reserved Words (Keywords) [](#table_of_contents)\n", + "\n", + "\n", "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." ] }, { "cell_type": "markdown", - "id": "7fc64770", "metadata": {}, "source": [ "In Python 3.6, there are 33 reserved keywords:" @@ -990,7 +994,6 @@ }, { "cell_type": "markdown", - "id": "e27da392", "metadata": {}, "source": [ "| Python Keywords| | | |\n", @@ -1008,7 +1011,6 @@ }, { "cell_type": "markdown", - "id": "4c47d2ef", "metadata": {}, "source": [ "You can see this list any time by typing `help(\"keywords\")` to the Python interpreter. Reserved words are case-sensitive and must be used exactly as shown. They are all entirely lowercase, except for `False`, `None`, and `True`." @@ -1017,7 +1019,6 @@ { "cell_type": "code", "execution_count": 140, - "id": "f2512ced", "metadata": {}, "outputs": [ { @@ -1046,7 +1047,6 @@ }, { "cell_type": "markdown", - "id": "aee81202", "metadata": {}, "source": [ "Trying to create a variable with the same name as any reserved word results in an error:" @@ -1055,7 +1055,6 @@ { "cell_type": "code", "execution_count": 103, - "id": "bef74b45", "metadata": {}, "outputs": [ { @@ -1073,17 +1072,17 @@ }, { "cell_type": "markdown", - "id": "273d69e2", "metadata": {}, "source": [ - "## Conclusion\n", + "\n", + "## Conclusion [](#table_of_contents)\n", + "\n", "\n", "This section covered the basics of Python **variables**, including object references and identity, and naming of Python identifiers." ] }, { "cell_type": "markdown", - "id": "e5278d8f", "metadata": {}, "source": [ "You now have a good understanding of some of Python’s data types and know how to create variables that reference objects of those types." @@ -1091,7 +1090,6 @@ }, { "cell_type": "markdown", - "id": "05f507d5", "metadata": {}, "source": [ "Next, you will see how to combine data objects into **expressions** involving various **operations**." @@ -1114,7 +1112,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/python/01. Basics/06 Operators and Expressions.ipynb b/Python/01. Basics/06 Operators and Expressions.ipynb similarity index 86% rename from python/01. Basics/06 Operators and Expressions.ipynb rename to Python/01. Basics/06 Operators and Expressions.ipynb index e89c745..70afee7 100755 --- a/python/01. Basics/06 Operators and Expressions.ipynb +++ b/Python/01. Basics/06 Operators and Expressions.ipynb @@ -2,17 +2,48 @@ "cells": [ { "cell_type": "markdown", - "id": "f8651a61", "metadata": {}, "source": [ - "# Operators and Expressions\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Operators and Expressions \n", "\n", "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 **operands**." ] }, { "cell_type": "markdown", - "id": "b78854e4", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents\n", + "\n", + "\n", + "* [Arithmetic Operators](#arithmetic_operators)\n", + "* [Comparison Operators](#comparison_operators)\n", + " * [Equality Comparison on Floating-Point Values](#equality_comparison_on_floating-point_values)\n", + "* [Logical Operators](#logical_operators)\n", + " * [Logical Expressions Involving Boolean Operands](#logical_expressions_involving_boolean_operands)\n", + " * [Evaluation of Non-Boolean Values in Boolean Context](#evaluation_of_non-boolean_values_in_boolean_context)\n", + " * [Numeric Value](#numeric_value)\n", + " * [String](#string)\n", + " * [Built-In Composite Data Object](#built-in_composite_data_object)\n", + " * [The `None` Keyword](#the_`none`_keyword)\n", + "* [Bitwise Operators](#bitwise_operators)\n", + "* [Identity Operators](#identity_operators)\n", + "* [Augmented Assignment Operators](#augmented_assignment_operators)\n", + "* [ Conclusion](#conclusion)\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", "metadata": {}, "source": [ "Here is an example:" @@ -21,7 +52,6 @@ { "cell_type": "code", "execution_count": 2, - "id": "5512030a", "metadata": {}, "outputs": [], "source": [ @@ -32,7 +62,6 @@ { "cell_type": "code", "execution_count": 3, - "id": "f44b233c", "metadata": {}, "outputs": [ { @@ -52,7 +81,6 @@ }, { "cell_type": "markdown", - "id": "03565296", "metadata": {}, "source": [ "In this case, the `+` operator adds the operands `a` and `b` together. An operand can be either a literal value or a variable that references an object:" @@ -61,7 +89,6 @@ { "cell_type": "code", "execution_count": 4, - "id": "e24a4145", "metadata": {}, "outputs": [], "source": [ @@ -72,7 +99,6 @@ { "cell_type": "code", "execution_count": 5, - "id": "9078d73c", "metadata": {}, "outputs": [ { @@ -92,7 +118,6 @@ }, { "cell_type": "markdown", - "id": "22b29bb5", "metadata": {}, "source": [ "A sequence of operands and operators, like `a + b - 5`, is called an **expression**. Python supports many operators for combining data objects into expressions. These are explored below." @@ -100,15 +125,15 @@ }, { "cell_type": "markdown", - "id": "303a9ee7", "metadata": {}, "source": [ - "## Arithmetic Operators" + "\n", + "## Arithmetic Operators [](#table_of_contents)\n", + "\n" ] }, { "cell_type": "markdown", - "id": "04837e1a", "metadata": {}, "source": [ "The following table lists the arithmetic operators supported by Python:\n", @@ -129,7 +154,6 @@ }, { "cell_type": "markdown", - "id": "375a058e", "metadata": {}, "source": [ "Here are some examples of these operators in use:" @@ -138,7 +162,6 @@ { "cell_type": "code", "execution_count": 104, - "id": "a4de71c8", "metadata": {}, "outputs": [], "source": [ @@ -149,7 +172,6 @@ { "cell_type": "code", "execution_count": 105, - "id": "5f5d03cd", "metadata": {}, "outputs": [ { @@ -170,7 +192,6 @@ { "cell_type": "code", "execution_count": 8, - "id": "65c205ce", "metadata": {}, "outputs": [ { @@ -191,7 +212,6 @@ { "cell_type": "code", "execution_count": 9, - "id": "9b0cbbd3", "metadata": {}, "outputs": [ { @@ -212,7 +232,6 @@ { "cell_type": "code", "execution_count": 10, - "id": "246ae037", "metadata": {}, "outputs": [ { @@ -233,7 +252,6 @@ { "cell_type": "code", "execution_count": 11, - "id": "00f73585", "metadata": {}, "outputs": [ { @@ -254,7 +272,6 @@ { "cell_type": "code", "execution_count": 12, - "id": "b6e7f296", "metadata": {}, "outputs": [ { @@ -275,7 +292,6 @@ { "cell_type": "code", "execution_count": 13, - "id": "7382b6dd", "metadata": {}, "outputs": [ { @@ -296,7 +312,6 @@ { "cell_type": "code", "execution_count": 14, - "id": "388d3e91", "metadata": {}, "outputs": [ { @@ -316,7 +331,6 @@ }, { "cell_type": "markdown", - "id": "83dbcf0b", "metadata": {}, "source": [ "The result of standard division (`/`) is always a `float`, even if the dividend is evenly divisible by the divisor:" @@ -325,7 +339,6 @@ { "cell_type": "code", "execution_count": 15, - "id": "624752ff", "metadata": {}, "outputs": [ { @@ -346,7 +359,6 @@ { "cell_type": "code", "execution_count": 16, - "id": "e004f456", "metadata": {}, "outputs": [ { @@ -366,7 +378,6 @@ }, { "cell_type": "markdown", - "id": "a173be58", "metadata": {}, "source": [ "When the result of floor division (`//`) 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:" @@ -375,7 +386,6 @@ { "cell_type": "code", "execution_count": 17, - "id": "b700d679", "metadata": {}, "outputs": [ { @@ -396,7 +406,6 @@ { "cell_type": "code", "execution_count": 18, - "id": "0b6ca1e8", "metadata": {}, "outputs": [ { @@ -417,7 +426,6 @@ { "cell_type": "code", "execution_count": 19, - "id": "c0f3863a", "metadata": {}, "outputs": [ { @@ -438,7 +446,6 @@ { "cell_type": "code", "execution_count": 20, - "id": "9a6f1503", "metadata": {}, "outputs": [ { @@ -459,7 +466,6 @@ { "cell_type": "code", "execution_count": 21, - "id": "d48fb428", "metadata": {}, "outputs": [ { @@ -479,10 +485,12 @@ }, { "cell_type": "markdown", - "id": "2fef3c6c", "metadata": {}, "source": [ - "## Comparison Operators\n", + "\n", + "## Comparison Operators [](#table_of_contents)\n", + "\n", + "\n", "\n", "|Operator |\tExample |\tMeaning |\tResult |\n", "|:--|:--|:--|:--|\n", @@ -496,7 +504,6 @@ }, { "cell_type": "markdown", - "id": "fc3710b3", "metadata": {}, "source": [ "Here are examples of the comparison operators in use:" @@ -505,7 +512,6 @@ { "cell_type": "code", "execution_count": 23, - "id": "b3f2f9f3", "metadata": {}, "outputs": [], "source": [ @@ -516,7 +522,6 @@ { "cell_type": "code", "execution_count": 24, - "id": "56dc7d50", "metadata": {}, "outputs": [ { @@ -537,7 +542,6 @@ { "cell_type": "code", "execution_count": 25, - "id": "76a974d8", "metadata": {}, "outputs": [ { @@ -558,7 +562,6 @@ { "cell_type": "code", "execution_count": 26, - "id": "61605dab", "metadata": {}, "outputs": [ { @@ -579,7 +582,6 @@ { "cell_type": "code", "execution_count": 27, - "id": "891c5f7d", "metadata": {}, "outputs": [ { @@ -600,7 +602,6 @@ { "cell_type": "code", "execution_count": 28, - "id": "1cb729fa", "metadata": {}, "outputs": [], "source": [ @@ -611,7 +612,6 @@ { "cell_type": "code", "execution_count": 29, - "id": "ffd289cd", "metadata": {}, "outputs": [ { @@ -632,7 +632,6 @@ { "cell_type": "code", "execution_count": 30, - "id": "695a4c00", "metadata": {}, "outputs": [ { @@ -653,7 +652,6 @@ { "cell_type": "code", "execution_count": 31, - "id": "2047b30a", "metadata": {}, "outputs": [ { @@ -673,7 +671,6 @@ }, { "cell_type": "markdown", - "id": "aa8f7c1f", "metadata": {}, "source": [ "Comparison operators are typically used in Boolean contexts like conditional and loop statements to direct program flow, as you will see later." @@ -681,18 +678,19 @@ }, { "cell_type": "markdown", - "id": "737dd052", "metadata": {}, "source": [ - "### Equality Comparison on Floating-Point Values\n", + "\n", + "### Equality Comparison on Floating-Point Values [](#table_of_contents)\n", + "\n", + "\n", "\n", "Recall from the earlier discussion of floating-point numbers that the value stored internally for a float object may not be precisely what you’d think it would be. For that reason, it is poor practice to compare floating-point values for exact equality. Consider this example:" ] }, { "cell_type": "code", - "execution_count": 45, - "id": "f9a93596", + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -701,7 +699,7 @@ "False" ] }, - "execution_count": 45, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -713,7 +711,6 @@ }, { "cell_type": "markdown", - "id": "b228ea16", "metadata": {}, "source": [ "Yikes! The internal representations of the addition operands are not exactly equal to `1.1` and `2.2`, so you cannot rely on x to compare exactly to `3.3`." @@ -721,7 +718,6 @@ }, { "cell_type": "markdown", - "id": "47dc1cee", "metadata": {}, "source": [ "The preferred way to determine whether two floating-point values are “equal” is to compute whether they are close to one another, given some tolerance. Take a look at this example:" @@ -730,7 +726,6 @@ { "cell_type": "code", "execution_count": 127, - "id": "7390ff8f", "metadata": {}, "outputs": [], "source": [ @@ -740,7 +735,6 @@ { "cell_type": "code", "execution_count": 128, - "id": "0fd7b119", "metadata": {}, "outputs": [ { @@ -760,7 +754,6 @@ }, { "cell_type": "markdown", - "id": "fb041d2e", "metadata": {}, "source": [ "`abs()` 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." @@ -768,20 +761,22 @@ }, { "cell_type": "markdown", - "id": "497e4d2a", "metadata": {}, "source": [ - "## Logical Operators\n", + "\n", + "## Logical Operators [](#table_of_contents)\n", + "\n", "\n", "The logical operators `not`, `or`, `and` and modify and join together expressions evaluated in Boolean context to create more complex conditions." ] }, { "cell_type": "markdown", - "id": "cba77d31", "metadata": {}, "source": [ - "### Logical Expressions Involving Boolean Operands\n", + "\n", + "### Logical Expressions Involving Boolean Operands [](#table_of_contents)\n", + "\n", "\n", "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 `True` or `False`." ] @@ -789,7 +784,6 @@ { "cell_type": "code", "execution_count": 35, - "id": "aabf38a1", "metadata": {}, "outputs": [ { @@ -811,7 +805,6 @@ { "cell_type": "code", "execution_count": 41, - "id": "4d2afeb9", "metadata": {}, "outputs": [ { @@ -831,7 +824,6 @@ }, { "cell_type": "markdown", - "id": "86fab03a", "metadata": {}, "source": [ "|Operator |\tExample\t |Meaning |\n", @@ -843,7 +835,6 @@ }, { "cell_type": "markdown", - "id": "4febd04c", "metadata": {}, "source": [ "Take a look at how they work in practice below." @@ -852,7 +843,6 @@ { "cell_type": "code", "execution_count": 137, - "id": "b41c32a6", "metadata": {}, "outputs": [], "source": [ @@ -862,7 +852,6 @@ { "cell_type": "code", "execution_count": 138, - "id": "a1c405d3", "metadata": {}, "outputs": [ { @@ -883,7 +872,6 @@ { "cell_type": "code", "execution_count": 139, - "id": "704e8a42", "metadata": {}, "outputs": [], "source": [ @@ -893,7 +881,6 @@ { "cell_type": "code", "execution_count": 140, - "id": "9f3f352a", "metadata": {}, "outputs": [ { @@ -914,7 +901,6 @@ { "cell_type": "code", "execution_count": 58, - "id": "689e5edb", "metadata": {}, "outputs": [ { @@ -934,17 +920,17 @@ }, { "cell_type": "markdown", - "id": "c2e4557d", "metadata": {}, "source": [ - "### Evaluation of Non-Boolean Values in Boolean Context\n", + "\n", + "### Evaluation of Non-Boolean Values in Boolean Context [](#table_of_contents)\n", + "\n", "\n", "Many objects and expressions are not equal to True or False. Nonetheless, they may still be evaluated in Boolean context and determined to be “truthy” or “falsy.”" ] }, { "cell_type": "markdown", - "id": "6681ab29", "metadata": {}, "source": [ "So what is true and what isn’t? As a philosophical question, that is outside the scope of this tutorial!" @@ -952,7 +938,6 @@ }, { "cell_type": "markdown", - "id": "7c1bddeb", "metadata": {}, "source": [ "But in Python, it is well-defined. All the following are considered false when evaluated in Boolean context:\n", @@ -965,7 +950,6 @@ }, { "cell_type": "markdown", - "id": "ef2285d4", "metadata": {}, "source": [ "Virtually any other object built into Python is regarded as `True`." @@ -973,7 +957,6 @@ }, { "cell_type": "markdown", - "id": "c3933c47", "metadata": {}, "source": [ "You can determine the “truthiness” of an object or expression with the built-in `bool()` function. `bool()` returns `True` if its argument is truthy and `False` if it is falsy." @@ -981,10 +964,12 @@ }, { "cell_type": "markdown", - "id": "3950c626", "metadata": {}, "source": [ - "#### Numeric Value\n", + "\n", + "#### Numeric Value [](#table_of_contents)\n", + "\n", + "\n", "- A zero value is false.\n", "- A non-zero value is true." ] @@ -992,7 +977,6 @@ { "cell_type": "code", "execution_count": 154, - "id": "e9050915", "metadata": {}, "outputs": [ { @@ -1010,7 +994,6 @@ { "cell_type": "code", "execution_count": 155, - "id": "96c8a566", "metadata": {}, "outputs": [ { @@ -1027,10 +1010,12 @@ }, { "cell_type": "markdown", - "id": "0c37818b", "metadata": {}, "source": [ - "#### String\n", + "\n", + "#### String [](#table_of_contents)\n", + "\n", + "\n", "- An empty string is false.\n", "- A non-empty string is true." ] @@ -1038,7 +1023,6 @@ { "cell_type": "code", "execution_count": 156, - "id": "8f27bdff", "metadata": {}, "outputs": [ { @@ -1056,7 +1040,6 @@ { "cell_type": "code", "execution_count": 157, - "id": "c348a752", "metadata": {}, "outputs": [ { @@ -1073,10 +1056,12 @@ }, { "cell_type": "markdown", - "id": "0a36f504", "metadata": {}, "source": [ - "#### Built-In Composite Data Object\n", + "\n", + "#### Built-In Composite Data Object [](#table_of_contents)\n", + "\n", + "\n", "> Python provides built-in composite data types called `list`, `tuple`, `dict`, and `set` (and some more). These are “container” 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.\n", ">\n", ">The examples below demonstrate this for the list type. (Lists are defined in Python with square brackets.)\n", @@ -1087,7 +1072,6 @@ { "cell_type": "code", "execution_count": 158, - "id": "d99a9d30", "metadata": {}, "outputs": [ { @@ -1108,7 +1092,6 @@ { "cell_type": "code", "execution_count": 159, - "id": "70bafc98", "metadata": {}, "outputs": [ { @@ -1129,7 +1112,6 @@ { "cell_type": "code", "execution_count": 160, - "id": "1ba859a9", "metadata": {}, "outputs": [ { @@ -1150,7 +1132,6 @@ { "cell_type": "code", "execution_count": 161, - "id": "c27e0e0c", "metadata": {}, "outputs": [ { @@ -1170,17 +1151,18 @@ }, { "cell_type": "markdown", - "id": "b3317357", "metadata": {}, "source": [ - "#### The `None` Keyword\n", + "\n", + "#### The `None` Keyword [](#table_of_contents)\n", + "\n", + "\n", "- `None` is always false:" ] }, { "cell_type": "code", "execution_count": 162, - "id": "0eb097aa", "metadata": {}, "outputs": [ { @@ -1200,27 +1182,28 @@ }, { "cell_type": "markdown", - "id": "b31651f2", "metadata": {}, "source": [ - "## Bitwise Operators\n", + "\n", + "## Bitwise Operators [](#table_of_contents)\n", + "\n", "\n", "Bitwise operators treat operands as sequences of binary digits and operate on them bit by bit. Bitwise operators will be addressed fully later." ] }, { "cell_type": "markdown", - "id": "ba596fec", "metadata": {}, "source": [ - "## Identity Operators\n", + "\n", + "## Identity Operators [](#table_of_contents)\n", + "\n", "\n", "Python provides two operators, `is` and `is not`, that determine whether the given operands have the same identity—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." ] }, { "cell_type": "markdown", - "id": "70c352df", "metadata": {}, "source": [ "Here is an example of two object that are equal but not identical:" @@ -1229,7 +1212,6 @@ { "cell_type": "code", "execution_count": 64, - "id": "9ed4cf85", "metadata": {}, "outputs": [], "source": [ @@ -1240,7 +1222,6 @@ { "cell_type": "code", "execution_count": 65, - "id": "beae0879", "metadata": {}, "outputs": [ { @@ -1258,7 +1239,6 @@ { "cell_type": "code", "execution_count": 66, - "id": "19ba7b74", "metadata": {}, "outputs": [ { @@ -1279,7 +1259,6 @@ { "cell_type": "code", "execution_count": 4, - "id": "58c101e2", "metadata": {}, "outputs": [], "source": [ @@ -1288,7 +1267,6 @@ }, { "cell_type": "markdown", - "id": "e70e17e7", "metadata": {}, "source": [ "Here, `x` and `y` both refer to objects whose value is `1001`. They are equal. But they do not reference the same object, as you can verify:" @@ -1297,7 +1275,6 @@ { "cell_type": "code", "execution_count": 68, - "id": "79b3bffa", "metadata": {}, "outputs": [ { @@ -1318,7 +1295,6 @@ { "cell_type": "code", "execution_count": 69, - "id": "116ea605", "metadata": {}, "outputs": [ { @@ -1338,7 +1314,6 @@ }, { "cell_type": "markdown", - "id": "b3743e65", "metadata": {}, "source": [ "`x` and `y` do not have the same identity, and `x` is `y` returns `False`." @@ -1346,7 +1321,6 @@ }, { "cell_type": "markdown", - "id": "7a85a8a4", "metadata": {}, "source": [ "You saw previously that when you make an assignment like `x = y`, Python merely creates a second reference to the same object, and that you could confirm that fact with the `id()` function. You can also confirm it using the `is` operator:" @@ -1355,7 +1329,6 @@ { "cell_type": "code", "execution_count": 112, - "id": "7248d4c3", "metadata": {}, "outputs": [], "source": [ @@ -1366,7 +1339,6 @@ { "cell_type": "code", "execution_count": 113, - "id": "eab98ef9", "metadata": {}, "outputs": [ { @@ -1387,7 +1359,6 @@ { "cell_type": "code", "execution_count": 114, - "id": "697bee23", "metadata": {}, "outputs": [ { @@ -1408,7 +1379,6 @@ { "cell_type": "code", "execution_count": 115, - "id": "c9e1462a", "metadata": {}, "outputs": [ { @@ -1429,7 +1399,6 @@ { "cell_type": "code", "execution_count": 123, - "id": "53c450a3", "metadata": {}, "outputs": [ { @@ -1449,7 +1418,6 @@ }, { "cell_type": "markdown", - "id": "584a8306", "metadata": {}, "source": [ "In this case, since `a` and `b` reference the same object, it stands to reason that `a` and `b` would be equal as well." @@ -1457,7 +1425,6 @@ }, { "cell_type": "markdown", - "id": "df20743f", "metadata": {}, "source": [ "Unsurprisingly, the opposite of `is` is `is not`:" @@ -1466,7 +1433,6 @@ { "cell_type": "code", "execution_count": 75, - "id": "f71d6191", "metadata": {}, "outputs": [], "source": [ @@ -1477,7 +1443,6 @@ { "cell_type": "code", "execution_count": 126, - "id": "15356c11", "metadata": {}, "outputs": [ { @@ -1497,10 +1462,11 @@ }, { "cell_type": "markdown", - "id": "2a1251df", "metadata": {}, "source": [ - "## Augmented Assignment Operators\n", + "\n", + "## Augmented Assignment Operators [](#table_of_contents)\n", + "\n", "\n", "You have seen that a single equal sign (`=`) 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:" ] @@ -1508,7 +1474,6 @@ { "cell_type": "code", "execution_count": 186, - "id": "70d83a70", "metadata": {}, "outputs": [], "source": [ @@ -1520,7 +1485,6 @@ { "cell_type": "code", "execution_count": 187, - "id": "1446ee97", "metadata": {}, "outputs": [ { @@ -1540,7 +1504,6 @@ }, { "cell_type": "markdown", - "id": "7d2b4c96", "metadata": {}, "source": [ "In fact, the expression to the right of the assignment can include references to the variable that is being assigned to:" @@ -1548,7 +1511,6 @@ }, { "cell_type": "markdown", - "id": "29e02ba0", "metadata": {}, "source": [ "Python supports a shorthand augmented assignment notation for these arithmetic and bitwise operators:\n", @@ -1566,7 +1528,6 @@ }, { "cell_type": "markdown", - "id": "608cd54a", "metadata": {}, "source": [ "For these operators, the following are equivalent:\n", @@ -1579,7 +1540,6 @@ }, { "cell_type": "markdown", - "id": "81bb46ce", "metadata": {}, "source": [ "Take a look at these examples:\n", @@ -1593,16 +1553,17 @@ }, { "cell_type": "markdown", - "id": "47b56763", "metadata": {}, "source": [ - "## Conclusion\n", + "\n", + "## Conclusion [](#table_of_contents)\n", + "\n", + "\n", "In this section, you learned about the diverse **operators** Python supports to combine objects into **expressions**." ] }, { "cell_type": "markdown", - "id": "30d6c1eb", "metadata": {}, "source": [ "Most of the examples you have seen so far have involved only simple atomic data, but you saw a brief introduction to the **string** data type. The next tutorial will explore **string** objects in much more detail." @@ -1625,7 +1586,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/python/01. Basics/07 Strings.ipynb b/Python/01. Basics/07 Strings.ipynb similarity index 90% rename from python/01. Basics/07 Strings.ipynb rename to Python/01. Basics/07 Strings.ipynb index 875ebe7..a0d86c1 100755 --- a/python/01. Basics/07 Strings.ipynb +++ b/Python/01. Basics/07 Strings.ipynb @@ -2,30 +2,65 @@ "cells": [ { "cell_type": "markdown", - "id": "23184e8c", "metadata": {}, "source": [ - "# Strings\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Strings \n", "\n", "In the section on Basic Data Types in Python, you learned how to define **strings**: objects that contain sequences of character data. Processing character data is integral to programming. It is a rare application that doesn’t need to manipulate strings at least to some extent." ] }, { "cell_type": "markdown", - "id": "fa10c681", "metadata": {}, "source": [ - "## String Manipulation\n", + "\n", + "## Table of Contents\n", + "\n", + "\n", + "* [String Manipulation](#string_manipulation)\n", + " * [String Operators](#string_operators)\n", + " * [The * Operator](#the_*_operator)\n", + " * [The in Operator](#the_in_operator)\n", + " * [Built-in String Functions](#built-in_string_functions)\n", + " * [`ord(c)`](#`ord(c)`)\n", + " * [`chr(n)`](#`chr(n)`)\n", + " * [len(s)](#len(s))\n", + " * [`str(obj)`](#`str(obj)`)\n", + "* [String Indexing](#string_indexing)\n", + "* [String Slicing](#string_slicing)\n", + " * [Specifying a Stride in a String Slice](#specifying_a_stride_in_a_string_slice)\n", + " * [Interpolating Variables Into a String](#interpolating_variables_into_a_string)\n", + " * [Modifying Strings](#modifying_strings)\n", + "* [ Conclusion](#conclusion)\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## String Manipulation [](#table_of_contents)\n", + "\n", "\n", "The sections below highlight the operators, methods, and functions that are available for working with strings." ] }, { "cell_type": "markdown", - "id": "5f662515", "metadata": {}, "source": [ - "### String Operators\n", + "\n", + "### String Operators [](#table_of_contents)\n", + "\n", "\n", "You have already seen the operators `+` and `*` applied to numeric operands in the section on Operators and Expressions in Python. These two operators can be applied to strings as well." ] @@ -33,7 +68,6 @@ { "cell_type": "code", "execution_count": 13, - "id": "304f586c", "metadata": {}, "outputs": [], "source": [ @@ -45,7 +79,6 @@ { "cell_type": "code", "execution_count": 14, - "id": "c19e1260", "metadata": {}, "outputs": [ { @@ -66,7 +99,6 @@ { "cell_type": "code", "execution_count": 15, - "id": "390915d3", "metadata": {}, "outputs": [ { @@ -87,7 +119,6 @@ { "cell_type": "code", "execution_count": 16, - "id": "4f7187bc", "metadata": {}, "outputs": [ { @@ -104,10 +135,11 @@ }, { "cell_type": "markdown", - "id": "9ae0c9fd", "metadata": {}, "source": [ - "### The * Operator\n", + "\n", + "### The * Operator [](#table_of_contents)\n", + "\n", "\n", "The `*` operator creates multiple copies of a string. If `s` is a string and `n` is an integer, either of the following expressions returns a string consisting of `n` concatenated copies of `s`:\n", "\n", @@ -119,7 +151,6 @@ }, { "cell_type": "markdown", - "id": "35fcc197", "metadata": {}, "source": [ "Here are examples of both forms:" @@ -128,7 +159,6 @@ { "cell_type": "code", "execution_count": 1, - "id": "5fee7681", "metadata": {}, "outputs": [], "source": [ @@ -138,7 +168,6 @@ { "cell_type": "code", "execution_count": 2, - "id": "a91d4e2c", "metadata": {}, "outputs": [ { @@ -159,7 +188,6 @@ { "cell_type": "code", "execution_count": 109, - "id": "29b880af", "metadata": {}, "outputs": [ { @@ -179,7 +207,6 @@ }, { "cell_type": "markdown", - "id": "aa601859", "metadata": {}, "source": [ "The multiplier operand `n` must be an integer. You’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:" @@ -188,7 +215,6 @@ { "cell_type": "code", "execution_count": 19, - "id": "eb8f0829", "metadata": {}, "outputs": [ { @@ -208,7 +234,6 @@ }, { "cell_type": "markdown", - "id": "94f37fc7", "metadata": {}, "source": [ "If you were to create a string variable and initialize it to the empty string by assigning it the value `'foo' * -8`, anyone would rightly think you were a bit daft. But it would work." @@ -216,10 +241,11 @@ }, { "cell_type": "markdown", - "id": "6c2dec9a", "metadata": {}, "source": [ - "### The in Operator\n", + "\n", + "### The in Operator [](#table_of_contents)\n", + "\n", "\n", "Python also provides a membership operator that can be used with strings. The in operator returns `True` if the first operand is contained within the second, and `False` otherwise:" ] @@ -227,7 +253,6 @@ { "cell_type": "code", "execution_count": 10, - "id": "aa92d506", "metadata": {}, "outputs": [], "source": [ @@ -237,7 +262,6 @@ { "cell_type": "code", "execution_count": 11, - "id": "e9590c4e", "metadata": {}, "outputs": [ { @@ -258,7 +282,6 @@ { "cell_type": "code", "execution_count": 12, - "id": "7fd79b34", "metadata": {}, "outputs": [ { @@ -278,7 +301,6 @@ }, { "cell_type": "markdown", - "id": "c46218b6", "metadata": {}, "source": [ "There is also a `not in` operator, which does the opposite:" @@ -287,7 +309,6 @@ { "cell_type": "code", "execution_count": 119, - "id": "4b61a741", "metadata": {}, "outputs": [ { @@ -308,7 +329,6 @@ { "cell_type": "code", "execution_count": 34, - "id": "bb36289f", "metadata": {}, "outputs": [ { @@ -328,10 +348,11 @@ }, { "cell_type": "markdown", - "id": "99da370e", "metadata": {}, "source": [ - "### Built-in String Functions\n", + "\n", + "### Built-in String Functions [](#table_of_contents)\n", + "\n", "\n", "As you saw in the tutorial on Basic Data Types in Python, Python provides many functions that are built-in to the interpreter and always available. Here are a few that work with strings:\n", "\n", @@ -346,7 +367,6 @@ }, { "cell_type": "markdown", - "id": "9c16daa2", "metadata": {}, "source": [ "These are explored more fully below." @@ -355,7 +375,6 @@ { "cell_type": "code", "execution_count": 126, - "id": "065a5ffa", "metadata": {}, "outputs": [ { @@ -375,16 +394,17 @@ }, { "cell_type": "markdown", - "id": "144abae1", "metadata": {}, "source": [ - "#### `ord(c)`\n", + "\n", + "#### `ord(c)` [](#table_of_contents)\n", + "\n", + "\n", "> Returns an integer value for the given character." ] }, { "cell_type": "markdown", - "id": "258d19cb", "metadata": {}, "source": [ "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." @@ -392,7 +412,6 @@ }, { "cell_type": "markdown", - "id": "e5aade2b", "metadata": {}, "source": [ "The simplest scheme in common use is called [ASCII](https://en.wikipedia.org/wiki/ASCII). It covers the common Latin characters you are probably most accustomed to working with. For these characters, ord(c) returns the ASCII value for character c:" @@ -401,7 +420,6 @@ { "cell_type": "code", "execution_count": 15, - "id": "c27fbf59", "metadata": {}, "outputs": [ { @@ -422,7 +440,6 @@ { "cell_type": "code", "execution_count": 16, - "id": "3a02c7cc", "metadata": {}, "outputs": [ { @@ -442,7 +459,6 @@ }, { "cell_type": "markdown", - "id": "7e8e3c5f", "metadata": {}, "source": [ "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." @@ -450,7 +466,6 @@ }, { "cell_type": "markdown", - "id": "b04c4073", "metadata": {}, "source": [ "[Unicode](http://www.unicode.org/standard/WhatIsUnicode.html) 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." @@ -458,7 +473,6 @@ }, { "cell_type": "markdown", - "id": "4de6aad9", "metadata": {}, "source": [ "As long as you stay in the domain of the common characters, there is little practical difference between ASCII and Unicode. But the `ord()` function will return numeric values for [Unicode characters](https://realpython.com/courses/python-unicode/) as well:" @@ -467,7 +481,6 @@ { "cell_type": "code", "execution_count": 127, - "id": "0cd71268", "metadata": {}, "outputs": [ { @@ -488,7 +501,6 @@ { "cell_type": "code", "execution_count": 128, - "id": "c6b714d9", "metadata": {}, "outputs": [ { @@ -508,17 +520,17 @@ }, { "cell_type": "markdown", - "id": "e408ba9e", "metadata": {}, "source": [ - "#### `chr(n)`\n", + "\n", + "#### `chr(n)` [](#table_of_contents)\n", + "\n", "\n", "> Returns a character value for the given integer." ] }, { "cell_type": "markdown", - "id": "334fa1cf", "metadata": {}, "source": [ "`chr()` does the reverse of `ord()`. Given a numeric value `n`, `chr(n)` returns a string representing the character that corresponds to `n`:" @@ -527,7 +539,6 @@ { "cell_type": "code", "execution_count": 133, - "id": "ef2c4a45", "metadata": {}, "outputs": [ { @@ -548,7 +559,6 @@ { "cell_type": "code", "execution_count": 134, - "id": "ada4d5f7", "metadata": {}, "outputs": [ { @@ -568,7 +578,6 @@ }, { "cell_type": "markdown", - "id": "3f7c454d", "metadata": {}, "source": [ "`chr()` handles Unicode characters as well:" @@ -577,7 +586,6 @@ { "cell_type": "code", "execution_count": 135, - "id": "d80a064b", "metadata": {}, "outputs": [ { @@ -598,7 +606,6 @@ { "cell_type": "code", "execution_count": 136, - "id": "80200ecb", "metadata": {}, "outputs": [ { @@ -618,10 +625,11 @@ }, { "cell_type": "markdown", - "id": "eb12b3f4", "metadata": {}, "source": [ - "#### len(s)\n", + "\n", + "#### len(s) [](#table_of_contents)\n", + "\n", "\n", "With `len()`, you can check Python string length. `len(s)` returns the number of characters in `s`:" ] @@ -629,7 +637,6 @@ { "cell_type": "code", "execution_count": 28, - "id": "37161877", "metadata": {}, "outputs": [ { @@ -650,10 +657,11 @@ }, { "cell_type": "markdown", - "id": "0cb9afd4", "metadata": {}, "source": [ - "#### `str(obj)`\n", + "\n", + "#### `str(obj)` [](#table_of_contents)\n", + "\n", "\n", "> Returns a string representation of an object." ] @@ -661,7 +669,6 @@ { "cell_type": "code", "execution_count": 30, - "id": "d2ba5dc5", "metadata": {}, "outputs": [ { @@ -681,7 +688,6 @@ }, { "cell_type": "markdown", - "id": "a45eae4a", "metadata": {}, "source": [ "Virtually any object in Python can be rendered as a string. `str(obj)` returns the string representation of object obj:" @@ -690,7 +696,6 @@ { "cell_type": "code", "execution_count": 24, - "id": "8e7ba22f", "metadata": {}, "outputs": [ { @@ -711,7 +716,6 @@ { "cell_type": "code", "execution_count": 25, - "id": "f9d91ce6", "metadata": {}, "outputs": [ { @@ -732,7 +736,6 @@ { "cell_type": "code", "execution_count": 26, - "id": "427eb452", "metadata": {}, "outputs": [ { @@ -753,7 +756,6 @@ { "cell_type": "code", "execution_count": 146, - "id": "7f80df9f", "metadata": {}, "outputs": [ { @@ -773,17 +775,17 @@ }, { "cell_type": "markdown", - "id": "0b114fd4", "metadata": {}, "source": [ - "## String Indexing\n", + "\n", + "## String Indexing [](#table_of_contents)\n", + "\n", "\n", "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." ] }, { "cell_type": "markdown", - "id": "d3318f34", "metadata": {}, "source": [ "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 (`[]`)." @@ -791,7 +793,6 @@ }, { "cell_type": "markdown", - "id": "62417aa5", "metadata": {}, "source": [ "String indexing in Python is zero-based: the first character in the string has index 0, the next has index 1, and so on. The index of the last character will be the length of the string minus one." @@ -799,7 +800,6 @@ }, { "cell_type": "markdown", - "id": "8572a66d", "metadata": {}, "source": [ "For example, a schematic diagram of the indices of the string 'foobar' would look like this:" @@ -807,7 +807,6 @@ }, { "cell_type": "markdown", - "id": "19f6db4d", "metadata": {}, "source": [ "\"string" @@ -815,7 +814,6 @@ }, { "cell_type": "markdown", - "id": "0a8f26d4", "metadata": {}, "source": [ "The individual characters can be accessed by index as follows:" @@ -824,7 +822,6 @@ { "cell_type": "code", "execution_count": 28, - "id": "eaf4fef3", "metadata": {}, "outputs": [], "source": [ @@ -834,7 +831,6 @@ { "cell_type": "code", "execution_count": 29, - "id": "dbd0ce02", "metadata": {}, "outputs": [ { @@ -855,7 +851,6 @@ { "cell_type": "code", "execution_count": 30, - "id": "c62afc05", "metadata": {}, "outputs": [ { @@ -876,7 +871,6 @@ { "cell_type": "code", "execution_count": 31, - "id": "fb34188f", "metadata": {}, "outputs": [ { @@ -897,7 +891,6 @@ { "cell_type": "code", "execution_count": 32, - "id": "67c96720", "metadata": {}, "outputs": [ { @@ -918,7 +911,6 @@ { "cell_type": "code", "execution_count": 33, - "id": "964f4c3d", "metadata": {}, "outputs": [ { @@ -938,7 +930,6 @@ }, { "cell_type": "markdown", - "id": "d84b6e53", "metadata": {}, "source": [ "Attempting to index beyond the end of the string results in an error:" @@ -947,7 +938,6 @@ { "cell_type": "code", "execution_count": 65, - "id": "29394047", "metadata": {}, "outputs": [ { @@ -968,7 +958,6 @@ }, { "cell_type": "markdown", - "id": "7c3045a1", "metadata": {}, "source": [ "String indices can also be specified with negative numbers, in which case indexing occurs from the end of the string backward: `-1` refers to the last character, `-2` the second-to-last character, and so on. Here is the same diagram showing both the positive and negative indices into the string `'foobar'`:\n", @@ -978,7 +967,6 @@ }, { "cell_type": "markdown", - "id": "fa634d72", "metadata": {}, "source": [ "Here are some examples of negative indexing:" @@ -987,7 +975,6 @@ { "cell_type": "code", "execution_count": 36, - "id": "b926b461", "metadata": {}, "outputs": [], "source": [ @@ -997,7 +984,6 @@ { "cell_type": "code", "execution_count": 37, - "id": "0dad316d", "metadata": {}, "outputs": [ { @@ -1018,7 +1004,6 @@ { "cell_type": "code", "execution_count": 38, - "id": "a0fc50e7", "metadata": {}, "outputs": [ { @@ -1039,7 +1024,6 @@ { "cell_type": "code", "execution_count": 39, - "id": "e33e707a", "metadata": {}, "outputs": [ { @@ -1060,7 +1044,6 @@ { "cell_type": "code", "execution_count": 40, - "id": "4e774bd8", "metadata": {}, "outputs": [ { @@ -1080,7 +1063,6 @@ }, { "cell_type": "markdown", - "id": "e88d687d", "metadata": {}, "source": [ "Attempting to index with negative numbers beyond the start of the string results in an error:" @@ -1089,7 +1071,6 @@ { "cell_type": "code", "execution_count": 42, - "id": "7b114e51", "metadata": {}, "outputs": [ { @@ -1110,7 +1091,6 @@ }, { "cell_type": "markdown", - "id": "fe12ee7a", "metadata": {}, "source": [ "For any non-empty string `s`, `s[len(s)-1]` and `s[-1]` both return the last character. There isn’t any index that makes sense for an empty string." @@ -1118,10 +1098,11 @@ }, { "cell_type": "markdown", - "id": "1d844f12", "metadata": {}, "source": [ - "## String Slicing\n", + "\n", + "## String Slicing [](#table_of_contents)\n", + "\n", "\n", "Python also allows a form of indexing syntax that extracts substrings from a string, known as string slicing. If `s` is a string, an expression of the form `s[m:n]` returns the portion of `s` starting with position `m`, and up to but not including position `n`:" ] @@ -1129,7 +1110,6 @@ { "cell_type": "code", "execution_count": 43, - "id": "dc1c8c8d", "metadata": {}, "outputs": [], "source": [ @@ -1139,7 +1119,6 @@ { "cell_type": "code", "execution_count": 44, - "id": "9caac50f", "metadata": {}, "outputs": [ { @@ -1159,7 +1138,6 @@ }, { "cell_type": "markdown", - "id": "3c460a46", "metadata": {}, "source": [ "> **Remember:** String indices are zero-based. The first character in a string has index `0`. This applies to both standard indexing and slicing." @@ -1167,7 +1145,6 @@ }, { "cell_type": "markdown", - "id": "6bc29431", "metadata": {}, "source": [ "Again, the second index specifies the first character that is not included in the result—the character `'r'` (`s[5]`) in the example above. That may seem slightly unintuitive, but it produces this result which makes sense: the expression `s[m:n]` will return a substring that is `n - m` characters in length, in this case, `5 - 2 = 3`." @@ -1175,7 +1152,6 @@ }, { "cell_type": "markdown", - "id": "3c19e834", "metadata": {}, "source": [ "If you omit the first index, the slice starts at the beginning of the string. Thus, `s[:m]` and `s[0:m]` are equivalent:" @@ -1184,7 +1160,6 @@ { "cell_type": "code", "execution_count": 45, - "id": "65e54921", "metadata": {}, "outputs": [], "source": [ @@ -1194,7 +1169,6 @@ { "cell_type": "code", "execution_count": 46, - "id": "6a476644", "metadata": {}, "outputs": [ { @@ -1215,7 +1189,6 @@ { "cell_type": "code", "execution_count": 47, - "id": "7ec12414", "metadata": {}, "outputs": [ { @@ -1235,7 +1208,6 @@ }, { "cell_type": "markdown", - "id": "4bb9b797", "metadata": {}, "source": [ "Similarly, if you omit the second index as in `s[n:]`, the slice extends from the first index through the end of the string. This is a nice, concise alternative to the more cumbersome `s[n:len(s)]`:" @@ -1244,7 +1216,6 @@ { "cell_type": "code", "execution_count": 48, - "id": "72ef55f9", "metadata": {}, "outputs": [], "source": [ @@ -1254,7 +1225,6 @@ { "cell_type": "code", "execution_count": 49, - "id": "be68a664", "metadata": {}, "outputs": [ { @@ -1275,7 +1245,6 @@ { "cell_type": "code", "execution_count": 50, - "id": "a38390ee", "metadata": {}, "outputs": [ { @@ -1295,7 +1264,6 @@ }, { "cell_type": "markdown", - "id": "e02f081a", "metadata": {}, "source": [ "For any string `s` and any integer `n` (`0 ≤ n ≤ len(s)`), `s[:n]` + `s[n:]` will be equal to `s`:" @@ -1304,7 +1272,6 @@ { "cell_type": "code", "execution_count": 51, - "id": "c783d1ba", "metadata": {}, "outputs": [], "source": [ @@ -1314,7 +1281,6 @@ { "cell_type": "code", "execution_count": 52, - "id": "3a8bda17", "metadata": {}, "outputs": [ { @@ -1335,7 +1301,6 @@ { "cell_type": "code", "execution_count": 53, - "id": "4287977f", "metadata": {}, "outputs": [ { @@ -1355,7 +1320,6 @@ }, { "cell_type": "markdown", - "id": "3d1c6c3b", "metadata": {}, "source": [ "Omitting both indices returns the original string, in its entirety. Literally. It’s not a copy, it’s a reference to the original string:" @@ -1364,7 +1328,6 @@ { "cell_type": "code", "execution_count": 139, - "id": "99526ddd", "metadata": {}, "outputs": [], "source": [ @@ -1375,7 +1338,6 @@ { "cell_type": "code", "execution_count": 140, - "id": "5935f149", "metadata": {}, "outputs": [ { @@ -1396,7 +1358,6 @@ { "cell_type": "code", "execution_count": 141, - "id": "9f89d290", "metadata": {}, "outputs": [ { @@ -1417,7 +1378,6 @@ { "cell_type": "code", "execution_count": 122, - "id": "f6b7252c", "metadata": {}, "outputs": [ { @@ -1437,7 +1397,6 @@ }, { "cell_type": "markdown", - "id": "1e2b086f", "metadata": {}, "source": [ "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:" @@ -1446,7 +1405,6 @@ { "cell_type": "code", "execution_count": 123, - "id": "2bd7e4d5", "metadata": {}, "outputs": [ { @@ -1467,7 +1425,6 @@ { "cell_type": "code", "execution_count": 124, - "id": "416cac6b", "metadata": {}, "outputs": [ { @@ -1487,7 +1444,6 @@ }, { "cell_type": "markdown", - "id": "a4cfee25", "metadata": {}, "source": [ "Negative indices can be used with slicing as well. `-1` refers to the last character, `-2` the second-to-last, and so on, just as with simple indexing. The diagram below shows how to slice the substring `'oob'` from the string `'foobar'` using both positive and negative indices:" @@ -1495,7 +1451,6 @@ }, { "cell_type": "markdown", - "id": "e6534e11", "metadata": {}, "source": [ "\"negative" @@ -1503,7 +1458,6 @@ }, { "cell_type": "markdown", - "id": "a5f795f0", "metadata": {}, "source": [ "Here is the corresponding Python code:" @@ -1512,7 +1466,6 @@ { "cell_type": "code", "execution_count": 97, - "id": "ed873371", "metadata": {}, "outputs": [], "source": [ @@ -1522,7 +1475,6 @@ { "cell_type": "code", "execution_count": 98, - "id": "8bada5f2", "metadata": {}, "outputs": [ { @@ -1543,7 +1495,6 @@ { "cell_type": "code", "execution_count": 99, - "id": "bc825852", "metadata": {}, "outputs": [ { @@ -1564,7 +1515,6 @@ { "cell_type": "code", "execution_count": 100, - "id": "da0b7858", "metadata": {}, "outputs": [ { @@ -1584,17 +1534,17 @@ }, { "cell_type": "markdown", - "id": "5d217458", "metadata": {}, "source": [ - "### Specifying a Stride in a String Slice\n", + "\n", + "### Specifying a Stride in a String Slice [](#table_of_contents)\n", + "\n", "\n", "There is one more variant of the slicing syntax to discuss. Adding an additional : 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." ] }, { "cell_type": "markdown", - "id": "131003a6", "metadata": {}, "source": [ "For example, for the string `'foobar'`, the slice `0:6:2` 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:" @@ -1602,7 +1552,6 @@ }, { "cell_type": "markdown", - "id": "5d1f9376", "metadata": {}, "source": [ "\"negative" @@ -1610,7 +1559,6 @@ }, { "cell_type": "markdown", - "id": "cc84ca16", "metadata": {}, "source": [ "Similarly, `1:6:2` specifies a slice starting with the second character (index 1) and ending with the last character, and again the stride value 2 causes every other character to be skipped:" @@ -1618,7 +1566,6 @@ }, { "cell_type": "markdown", - "id": "74269e50", "metadata": {}, "source": [ "\"negative" @@ -1626,7 +1573,6 @@ }, { "cell_type": "markdown", - "id": "5a71519e", "metadata": {}, "source": [ "The illustrative REPL code is shown here:" @@ -1635,7 +1581,6 @@ { "cell_type": "code", "execution_count": 3, - "id": "d081aefb", "metadata": {}, "outputs": [], "source": [ @@ -1645,7 +1590,6 @@ { "cell_type": "code", "execution_count": 4, - "id": "fac11ecc", "metadata": {}, "outputs": [ { @@ -1666,7 +1610,6 @@ { "cell_type": "code", "execution_count": 150, - "id": "511dfc17", "metadata": {}, "outputs": [ { @@ -1686,7 +1629,6 @@ }, { "cell_type": "markdown", - "id": "8eb3fb70", "metadata": {}, "source": [ "As with any slicing, the first and second indices can be omitted, and default to the first and last characters respectively:" @@ -1695,7 +1637,6 @@ { "cell_type": "code", "execution_count": 69, - "id": "9d29edff", "metadata": {}, "outputs": [ { @@ -1717,7 +1658,6 @@ { "cell_type": "code", "execution_count": 70, - "id": "0ecd60d3", "metadata": {}, "outputs": [ { @@ -1738,7 +1678,6 @@ { "cell_type": "code", "execution_count": 71, - "id": "bf177775", "metadata": {}, "outputs": [ { @@ -1758,7 +1697,6 @@ }, { "cell_type": "markdown", - "id": "8840ec22", "metadata": {}, "source": [ "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:" @@ -1767,7 +1705,6 @@ { "cell_type": "code", "execution_count": 73, - "id": "33b0d776", "metadata": {}, "outputs": [], "source": [ @@ -1777,7 +1714,6 @@ { "cell_type": "code", "execution_count": 74, - "id": "8369d371", "metadata": {}, "outputs": [ { @@ -1797,7 +1733,6 @@ }, { "cell_type": "markdown", - "id": "29eb0e9c", "metadata": {}, "source": [ "In the above example, `5:0:-2` means “start at the last character and step backward by 2, up to but not including the first character.”" @@ -1805,7 +1740,6 @@ }, { "cell_type": "markdown", - "id": "f4881569", "metadata": {}, "source": [ "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:" @@ -1814,7 +1748,6 @@ { "cell_type": "code", "execution_count": 79, - "id": "2695ac21", "metadata": {}, "outputs": [ { @@ -1836,7 +1769,6 @@ { "cell_type": "code", "execution_count": 80, - "id": "c61e970d", "metadata": {}, "outputs": [ { @@ -1856,7 +1788,6 @@ }, { "cell_type": "markdown", - "id": "a693b6e0", "metadata": {}, "source": [ "This is a common paradigm for reversing a string:" @@ -1865,7 +1796,6 @@ { "cell_type": "code", "execution_count": 81, - "id": "60613308", "metadata": {}, "outputs": [ { @@ -1886,17 +1816,17 @@ }, { "cell_type": "markdown", - "id": "79e56be3", "metadata": {}, "source": [ - "### Interpolating Variables Into a String\n", + "\n", + "### Interpolating Variables Into a String [](#table_of_contents)\n", + "\n", "\n", "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 **f-string**." ] }, { "cell_type": "markdown", - "id": "77adf220", "metadata": {}, "source": [ "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." @@ -1904,7 +1834,6 @@ }, { "cell_type": "markdown", - "id": "38ca79f3", "metadata": {}, "source": [ "For example, suppose you want to display the result of an arithmetic calculation. You can do this with a straightforward `print()` statement, separating numeric values and string literals by commas:" @@ -1913,7 +1842,6 @@ { "cell_type": "code", "execution_count": 173, - "id": "4ef35286", "metadata": {}, "outputs": [], "source": [ @@ -1925,7 +1853,6 @@ { "cell_type": "code", "execution_count": 174, - "id": "0e7c2ac3", "metadata": {}, "outputs": [ { @@ -1942,7 +1869,6 @@ }, { "cell_type": "markdown", - "id": "b9400efe", "metadata": {}, "source": [ "But this is cumbersome. To accomplish the same thing using an f-string:\n", @@ -1953,7 +1879,6 @@ }, { "cell_type": "markdown", - "id": "a300882d", "metadata": {}, "source": [ "Recast using an f-string, the above example looks much cleaner:" @@ -1962,7 +1887,6 @@ { "cell_type": "code", "execution_count": 182, - "id": "1476ff7f", "metadata": {}, "outputs": [], "source": [ @@ -1974,7 +1898,6 @@ { "cell_type": "code", "execution_count": 181, - "id": "8981e5fd", "metadata": {}, "outputs": [ { @@ -1991,7 +1914,6 @@ }, { "cell_type": "markdown", - "id": "2a58dedc", "metadata": {}, "source": [ "Any of Python’s three quoting mechanisms can be used to define an f-string:" @@ -2000,7 +1922,6 @@ { "cell_type": "code", "execution_count": 131, - "id": "a622099d", "metadata": {}, "outputs": [], "source": [ @@ -2010,7 +1931,6 @@ { "cell_type": "code", "execution_count": 132, - "id": "a6b78d81", "metadata": {}, "outputs": [ { @@ -2028,7 +1948,6 @@ { "cell_type": "code", "execution_count": 133, - "id": "85026c41", "metadata": {}, "outputs": [ { @@ -2046,7 +1965,6 @@ { "cell_type": "code", "execution_count": 134, - "id": "086a85df", "metadata": {}, "outputs": [ { @@ -2063,17 +1981,17 @@ }, { "cell_type": "markdown", - "id": "ddd555bf", "metadata": {}, "source": [ - "### Modifying Strings\n", + "\n", + "### Modifying Strings [](#table_of_contents)\n", + "\n", "\n", "In a nutshell, you can’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.)" ] }, { "cell_type": "markdown", - "id": "b4be2765", "metadata": {}, "source": [ "A statement like this will cause an error:" @@ -2082,7 +2000,6 @@ { "cell_type": "code", "execution_count": 191, - "id": "9f475df5", "metadata": {}, "outputs": [], "source": [ @@ -2092,7 +2009,6 @@ { "cell_type": "code", "execution_count": 193, - "id": "3df90174", "metadata": {}, "outputs": [ { @@ -2113,7 +2029,6 @@ }, { "cell_type": "markdown", - "id": "857cda55", "metadata": {}, "source": [ "In truth, there really isn’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:" @@ -2122,7 +2037,6 @@ { "cell_type": "code", "execution_count": 93, - "id": "066fbc51", "metadata": {}, "outputs": [], "source": [ @@ -2132,7 +2046,6 @@ { "cell_type": "code", "execution_count": 94, - "id": "78dd04d6", "metadata": {}, "outputs": [ { @@ -2152,16 +2065,17 @@ }, { "cell_type": "markdown", - "id": "2b2f1422", "metadata": {}, "source": [ - "## Conclusion\n", + "\n", + "## Conclusion [](#table_of_contents)\n", + "\n", + "\n", "This tutorial provided an in-depth look at the many different mechanisms Python provides for string handling, including string operators, built-in functions, indexing, slicing, and built-in methods. You also were introduced to the bytes and bytearray types." ] }, { "cell_type": "markdown", - "id": "04c7a670", "metadata": {}, "source": [ "These types are the first types you have examined that are composite—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: `lists` and `tuples`." @@ -2184,7 +2098,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb b/Python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb similarity index 92% rename from python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb rename to Python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb index 2bd8ae5..20a26a9 100755 --- a/python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb +++ b/Python/01. Basics/08 Composite Data Types: Lists and Tuples.ipynb @@ -2,11 +2,48 @@ "cells": [ { "cell_type": "markdown", - "id": "5731f133", "metadata": {}, "source": [ - "# Lists and Tuples in Python\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Lists and Tuples in Python \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents\n", + "\n", + "\n", + "* [Python Lists](#python_lists)\n", + " * [1. Lists Are Ordered](#1._lists_are_ordered)\n", + " * [2. Lists Can Contain Arbitrary Objects](#2._lists_can_contain_arbitrary_objects)\n", + " * [3. List Elements Can Be Accessed by Index](#3._list_elements_can_be_accessed_by_index)\n", + " * [4. Lists Can Be Nested](#4._lists_can_be_nested)\n", + " * [5. Lists Are Mutable](#5._lists_are_mutable)\n", + " * [Modifying a Single List Value](#modifying_a_single_list_value)\n", + " * [Modifying Multiple List Values](#modifying_multiple_list_values)\n", + " * [Prepending or Appending Items to a List](#prepending_or_appending_items_to_a_list)\n", + " * [6. Lists Are Dynamic](#6._lists_are_dynamic)\n", + "* [Python Tuples](#python_tuples)\n", + " * [Defining and Using Tuples](#defining_and_using_tuples)\n", + " * [Tuple Assignment, Packing, and Unpacking](#tuple_assignment,_packing,_and_unpacking)\n", + "* [ Conclusion](#conclusion)\n", "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ "Lists and tuples are arguably Python’s most versatile, useful data types. You will find them in virtually every nontrivial Python program.\n", "\n", "* [Python Lists](#lists)\n", @@ -15,18 +52,18 @@ }, { "cell_type": "markdown", - "id": "f28d785b", "metadata": {}, "source": [ - "\n", - "## Python Lists\n", + "\n", + "## Python Lists [](#table_of_contents)\n", + "\n", + "\n", "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 (`[]`), as shown below:" ] }, { "cell_type": "code", "execution_count": 3, - "id": "224fa3d1", "metadata": {}, "outputs": [], "source": [ @@ -36,7 +73,6 @@ { "cell_type": "code", "execution_count": 9, - "id": "944b8e8e", "metadata": {}, "outputs": [ { @@ -56,7 +92,6 @@ }, { "cell_type": "markdown", - "id": "9a664dba", "metadata": {}, "source": [ "The important characteristics of Python lists are as follows:\n", @@ -73,10 +108,11 @@ }, { "cell_type": "markdown", - "id": "8fcc63ff", "metadata": {}, "source": [ - "### 1. Lists Are Ordered\n", + "\n", + "### 1. Lists Are Ordered [](#table_of_contents)\n", + "\n", "\n", "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’s lifetime. (You will see a Python data type that is not ordered in the next tutorial on dictionaries.)" ] @@ -84,7 +120,6 @@ { "cell_type": "code", "execution_count": 22, - "id": "53905c3b", "metadata": {}, "outputs": [ { @@ -107,7 +142,6 @@ { "cell_type": "code", "execution_count": 23, - "id": "f39383c3", "metadata": {}, "outputs": [ { @@ -130,7 +164,6 @@ { "cell_type": "code", "execution_count": 24, - "id": "781d0d7f", "metadata": {}, "outputs": [ { @@ -152,7 +185,6 @@ }, { "cell_type": "markdown", - "id": "edef844e", "metadata": {}, "source": [ "Lists that have the same elements in a different order are not the same:" @@ -161,7 +193,6 @@ { "cell_type": "code", "execution_count": 4, - "id": "72304bd7", "metadata": {}, "outputs": [ { @@ -184,7 +215,6 @@ { "cell_type": "code", "execution_count": 5, - "id": "3260c4af", "metadata": {}, "outputs": [ { @@ -205,7 +235,6 @@ { "cell_type": "code", "execution_count": 6, - "id": "e15600e5", "metadata": {}, "outputs": [ { @@ -225,10 +254,11 @@ }, { "cell_type": "markdown", - "id": "0730d1ba", "metadata": {}, "source": [ - "### 2. Lists Can Contain Arbitrary Objects\n", + "\n", + "### 2. Lists Can Contain Arbitrary Objects [](#table_of_contents)\n", + "\n", "\n", "A list can contain any assortment of objects. The elements of a list can all be the same type:" ] @@ -236,7 +266,6 @@ { "cell_type": "code", "execution_count": 7, - "id": "ecb1aea3", "metadata": {}, "outputs": [], "source": [ @@ -245,7 +274,6 @@ }, { "cell_type": "markdown", - "id": "b649d22a", "metadata": {}, "source": [ "Or the elements can be of varying types:" @@ -254,7 +282,6 @@ { "cell_type": "code", "execution_count": 9, - "id": "bc2d44ac", "metadata": {}, "outputs": [], "source": [ @@ -263,7 +290,6 @@ }, { "cell_type": "markdown", - "id": "c3dea005", "metadata": {}, "source": [ "Lists can even contain complex objects, like functions, classes, and modules, which you will learn about in upcoming sections:" @@ -272,7 +298,6 @@ { "cell_type": "code", "execution_count": 10, - "id": "163b0ecc", "metadata": {}, "outputs": [ { @@ -293,7 +318,6 @@ { "cell_type": "code", "execution_count": 11, - "id": "e60eef24", "metadata": {}, "outputs": [ { @@ -314,7 +338,6 @@ { "cell_type": "code", "execution_count": 12, - "id": "0aff05d4", "metadata": {}, "outputs": [], "source": [ @@ -325,7 +348,6 @@ { "cell_type": "code", "execution_count": 13, - "id": "3cea8915", "metadata": {}, "outputs": [ { @@ -346,7 +368,6 @@ { "cell_type": "code", "execution_count": 14, - "id": "4eb83630", "metadata": {}, "outputs": [ { @@ -368,7 +389,6 @@ { "cell_type": "code", "execution_count": 16, - "id": "3e5e59ca", "metadata": {}, "outputs": [], "source": [ @@ -378,7 +398,6 @@ { "cell_type": "code", "execution_count": 17, - "id": "128d97e1", "metadata": {}, "outputs": [ { @@ -401,7 +420,6 @@ }, { "cell_type": "markdown", - "id": "778f7f8e", "metadata": {}, "source": [ "A list can contain any number of objects, from zero to as many as your computer’s memory will allow:" @@ -410,7 +428,6 @@ { "cell_type": "code", "execution_count": 18, - "id": "084b9669", "metadata": {}, "outputs": [ { @@ -432,7 +449,6 @@ { "cell_type": "code", "execution_count": 19, - "id": "8f6f663e", "metadata": {}, "outputs": [ { @@ -454,7 +470,6 @@ { "cell_type": "code", "execution_count": 21, - "id": "afd84114", "metadata": {}, "outputs": [], "source": [ @@ -467,7 +482,6 @@ }, { "cell_type": "markdown", - "id": "fbd823f5", "metadata": {}, "source": [ "> A list with a single object is sometimes referred to as a singleton list." @@ -475,7 +489,6 @@ }, { "cell_type": "markdown", - "id": "83ed1c59", "metadata": {}, "source": [ "List objects needn’t be unique. A given object can appear in a list multiple times:\n", @@ -485,7 +498,6 @@ { "cell_type": "code", "execution_count": 42, - "id": "1e372e7d", "metadata": {}, "outputs": [], "source": [ @@ -494,17 +506,17 @@ }, { "cell_type": "markdown", - "id": "f363f673", "metadata": {}, "source": [ - "### 3. List Elements Can Be Accessed by Index\n", + "\n", + "### 3. List Elements Can Be Accessed by Index [](#table_of_contents)\n", + "\n", "\n", "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." ] }, { "cell_type": "markdown", - "id": "75516647", "metadata": {}, "source": [ "Consider the following list:" @@ -513,7 +525,6 @@ { "cell_type": "code", "execution_count": 43, - "id": "1238b74b", "metadata": {}, "outputs": [], "source": [ @@ -522,7 +533,6 @@ }, { "cell_type": "markdown", - "id": "68b1c05e", "metadata": {}, "source": [ "The indices for the elements in a are shown below:" @@ -530,7 +540,6 @@ }, { "cell_type": "markdown", - "id": "76be95f6", "metadata": {}, "source": [ "\"string" @@ -538,7 +547,6 @@ }, { "cell_type": "markdown", - "id": "daa07526", "metadata": {}, "source": [ "Here is Python code to access some elements of a:" @@ -547,7 +555,6 @@ { "cell_type": "code", "execution_count": 44, - "id": "448bffb0", "metadata": {}, "outputs": [ { @@ -568,7 +575,6 @@ { "cell_type": "code", "execution_count": 45, - "id": "ca66f33a", "metadata": {}, "outputs": [ { @@ -589,7 +595,6 @@ { "cell_type": "code", "execution_count": 46, - "id": "ce6610ee", "metadata": {}, "outputs": [ { @@ -609,7 +614,6 @@ }, { "cell_type": "markdown", - "id": "5806ee80", "metadata": {}, "source": [ "Virtually everything about string indexing works similarly for lists. For example, a negative list index counts from the end of the list:" @@ -617,7 +621,6 @@ }, { "cell_type": "markdown", - "id": "f4e80df9", "metadata": {}, "source": [ "\"string" @@ -626,7 +629,6 @@ { "cell_type": "code", "execution_count": 47, - "id": "f471f429", "metadata": {}, "outputs": [ { @@ -647,7 +649,6 @@ { "cell_type": "code", "execution_count": 48, - "id": "d71d5047", "metadata": {}, "outputs": [ { @@ -668,7 +669,6 @@ { "cell_type": "code", "execution_count": 49, - "id": "9a9c8dc6", "metadata": {}, "outputs": [ { @@ -688,7 +688,6 @@ }, { "cell_type": "markdown", - "id": "24e25038", "metadata": {}, "source": [ "Slicing also works. If a is a list, the expression `a[m:n]` returns the portion of a from index `m` to, but not including, index `n`:" @@ -697,7 +696,6 @@ { "cell_type": "code", "execution_count": 50, - "id": "2470be05", "metadata": {}, "outputs": [], "source": [ @@ -707,7 +705,6 @@ { "cell_type": "code", "execution_count": 51, - "id": "ec76a7a8", "metadata": {}, "outputs": [ { @@ -727,7 +724,6 @@ }, { "cell_type": "markdown", - "id": "92e8b2b7", "metadata": {}, "source": [ "Other features of string slicing work analogously for list slicing as well:\n", @@ -738,7 +734,6 @@ { "cell_type": "code", "execution_count": 52, - "id": "186bff88", "metadata": {}, "outputs": [ { @@ -759,7 +754,6 @@ { "cell_type": "code", "execution_count": 53, - "id": "2be72101", "metadata": {}, "outputs": [ { @@ -780,7 +774,6 @@ { "cell_type": "code", "execution_count": 26, - "id": "3271375e", "metadata": {}, "outputs": [ { @@ -800,7 +793,6 @@ }, { "cell_type": "markdown", - "id": "e4ec255c", "metadata": {}, "source": [ "- 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:" @@ -809,7 +801,6 @@ { "cell_type": "code", "execution_count": 29, - "id": "f0245a1e", "metadata": {}, "outputs": [ { @@ -830,7 +821,6 @@ { "cell_type": "code", "execution_count": 17, - "id": "be388ba4", "metadata": {}, "outputs": [ { @@ -851,7 +841,6 @@ { "cell_type": "code", "execution_count": 18, - "id": "ca046fc9", "metadata": {}, "outputs": [ { @@ -872,7 +861,6 @@ { "cell_type": "code", "execution_count": 19, - "id": "49b8dc08", "metadata": {}, "outputs": [ { @@ -892,7 +880,6 @@ }, { "cell_type": "markdown", - "id": "6e2815b6", "metadata": {}, "source": [ "- You can specify a stride—either positive or negative:" @@ -901,7 +888,6 @@ { "cell_type": "code", "execution_count": 20, - "id": "29c7bfe1", "metadata": {}, "outputs": [ { @@ -922,7 +908,6 @@ { "cell_type": "code", "execution_count": 21, - "id": "079d8938", "metadata": {}, "outputs": [ { @@ -943,7 +928,6 @@ { "cell_type": "code", "execution_count": 22, - "id": "b9dbfed7", "metadata": {}, "outputs": [ { @@ -963,7 +947,6 @@ }, { "cell_type": "markdown", - "id": "bb2d086b", "metadata": {}, "source": [ "- The syntax for reversing a list works the same way it does for strings:" @@ -972,7 +955,6 @@ { "cell_type": "code", "execution_count": 23, - "id": "ea5539a8", "metadata": {}, "outputs": [ { @@ -992,7 +974,6 @@ }, { "cell_type": "markdown", - "id": "2a2024a9", "metadata": {}, "source": [ "The `[:]` 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." @@ -1001,7 +982,6 @@ { "cell_type": "code", "execution_count": 61, - "id": "67e73393", "metadata": {}, "outputs": [], "source": [ @@ -1011,7 +991,6 @@ { "cell_type": "code", "execution_count": 36, - "id": "730ff483", "metadata": {}, "outputs": [ { @@ -1032,7 +1011,6 @@ { "cell_type": "code", "execution_count": 37, - "id": "5e2ab6a8", "metadata": {}, "outputs": [ { @@ -1052,7 +1030,6 @@ }, { "cell_type": "markdown", - "id": "f00040e0", "metadata": {}, "source": [ "Conversely, if a is a list, `a[:]` returns a new object that is a copy of `a`:" @@ -1061,7 +1038,6 @@ { "cell_type": "code", "execution_count": 38, - "id": "f80028f3", "metadata": {}, "outputs": [], "source": [ @@ -1071,7 +1047,6 @@ { "cell_type": "code", "execution_count": 39, - "id": "cb40d715", "metadata": {}, "outputs": [ { @@ -1092,7 +1067,6 @@ { "cell_type": "code", "execution_count": 40, - "id": "e3bf2d76", "metadata": {}, "outputs": [ { @@ -1112,7 +1086,6 @@ }, { "cell_type": "markdown", - "id": "fcf87db3", "metadata": {}, "source": [ "Several Python operators and built-in functions can also be used with lists in ways that are analogous to strings:" @@ -1120,7 +1093,6 @@ }, { "cell_type": "markdown", - "id": "bfbe8474", "metadata": {}, "source": [ "- The `in` and `not in` operators:" @@ -1129,7 +1101,6 @@ { "cell_type": "code", "execution_count": 50, - "id": "5d0cc53f", "metadata": {}, "outputs": [ { @@ -1150,7 +1121,6 @@ { "cell_type": "code", "execution_count": 51, - "id": "5175dcf1", "metadata": {}, "outputs": [ { @@ -1170,7 +1140,6 @@ }, { "cell_type": "markdown", - "id": "baa92b09", "metadata": {}, "source": [ "- The concatenation (`+`) and replication (`*`) operators:" @@ -1179,7 +1148,6 @@ { "cell_type": "code", "execution_count": 61, - "id": "da5445ce", "metadata": {}, "outputs": [ { @@ -1200,7 +1168,6 @@ { "cell_type": "code", "execution_count": 62, - "id": "8f052203", "metadata": {}, "outputs": [ { @@ -1221,7 +1188,6 @@ { "cell_type": "code", "execution_count": 63, - "id": "e975dda3", "metadata": {}, "outputs": [ { @@ -1252,7 +1218,6 @@ }, { "cell_type": "markdown", - "id": "477f6546", "metadata": {}, "source": [ "- The `len()`, `min()`, and `max(`) functions:" @@ -1261,7 +1226,6 @@ { "cell_type": "code", "execution_count": 64, - "id": "8f61ce86", "metadata": {}, "outputs": [ { @@ -1282,7 +1246,6 @@ { "cell_type": "code", "execution_count": 65, - "id": "19230651", "metadata": {}, "outputs": [ { @@ -1303,7 +1266,6 @@ { "cell_type": "code", "execution_count": 38, - "id": "a1465ad4", "metadata": {}, "outputs": [ { @@ -1324,7 +1286,6 @@ { "cell_type": "code", "execution_count": 70, - "id": "73689bec", "metadata": {}, "outputs": [ { @@ -1344,7 +1305,6 @@ }, { "cell_type": "markdown", - "id": "5bd17e5b", "metadata": {}, "source": [ "It’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." @@ -1352,7 +1312,6 @@ }, { "cell_type": "markdown", - "id": "5024671e", "metadata": {}, "source": [ "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:" @@ -1361,7 +1320,6 @@ { "cell_type": "code", "execution_count": 40, - "id": "2e58770c", "metadata": {}, "outputs": [ { @@ -1382,7 +1340,6 @@ { "cell_type": "code", "execution_count": 41, - "id": "349a8106", "metadata": {}, "outputs": [ { @@ -1403,7 +1360,6 @@ { "cell_type": "code", "execution_count": 42, - "id": "6f28b0fd", "metadata": {}, "outputs": [ { @@ -1424,7 +1380,6 @@ { "cell_type": "code", "execution_count": 43, - "id": "2224aa12", "metadata": {}, "outputs": [ { @@ -1445,7 +1400,6 @@ { "cell_type": "code", "execution_count": 44, - "id": "097e60a7", "metadata": {}, "outputs": [ { @@ -1465,7 +1419,6 @@ }, { "cell_type": "markdown", - "id": "0661e9b1", "metadata": {}, "source": [ "For that matter, you can do likewise with a string literal:" @@ -1474,7 +1427,6 @@ { "cell_type": "code", "execution_count": 124, - "id": "bf6c14f6", "metadata": {}, "outputs": [ { @@ -1494,17 +1446,17 @@ }, { "cell_type": "markdown", - "id": "825e5a91", "metadata": {}, "source": [ - "### 4. Lists Can Be Nested\n", + "\n", + "### 4. Lists Can Be Nested [](#table_of_contents)\n", + "\n", "\n", "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." ] }, { "cell_type": "markdown", - "id": "f2c80983", "metadata": {}, "source": [ "Consider this (admittedly contrived) example:" @@ -1513,7 +1465,6 @@ { "cell_type": "code", "execution_count": 72, - "id": "509d8e21", "metadata": {}, "outputs": [], "source": [ @@ -1522,7 +1473,6 @@ }, { "cell_type": "markdown", - "id": "ff778fc9", "metadata": {}, "source": [ "The object structure that x references is diagrammed below:" @@ -1530,7 +1480,6 @@ }, { "cell_type": "markdown", - "id": "7b681953", "metadata": {}, "source": [ "\"nested" @@ -1538,7 +1487,6 @@ }, { "cell_type": "markdown", - "id": "cf3b3523", "metadata": {}, "source": [ "`x[0]`, `x[2]`, and `x[4]` are strings, each one character long:" @@ -1547,7 +1495,6 @@ { "cell_type": "code", "execution_count": 49, - "id": "f7d30716", "metadata": {}, "outputs": [ { @@ -1567,7 +1514,6 @@ }, { "cell_type": "markdown", - "id": "faa8b1de", "metadata": {}, "source": [ "But `x[1]` and `x[3]` are sublists:" @@ -1576,7 +1522,6 @@ { "cell_type": "code", "execution_count": 50, - "id": "bd2afbad", "metadata": {}, "outputs": [ { @@ -1597,7 +1542,6 @@ { "cell_type": "code", "execution_count": 51, - "id": "9b0bbf8d", "metadata": {}, "outputs": [ { @@ -1617,7 +1561,6 @@ }, { "cell_type": "markdown", - "id": "14b8a84b", "metadata": {}, "source": [ "To access the items in a sublist, simply append an additional index:" @@ -1626,7 +1569,6 @@ { "cell_type": "code", "execution_count": 53, - "id": "e539e131", "metadata": {}, "outputs": [ { @@ -1647,7 +1589,6 @@ { "cell_type": "code", "execution_count": 54, - "id": "7ffdb3b7", "metadata": {}, "outputs": [ { @@ -1668,7 +1609,6 @@ { "cell_type": "code", "execution_count": 55, - "id": "3189540d", "metadata": {}, "outputs": [ { @@ -1689,7 +1629,6 @@ { "cell_type": "code", "execution_count": 56, - "id": "a22d1a11", "metadata": {}, "outputs": [ { @@ -1710,7 +1649,6 @@ { "cell_type": "code", "execution_count": 57, - "id": "61b051cf", "metadata": {}, "outputs": [ { @@ -1731,7 +1669,6 @@ { "cell_type": "code", "execution_count": 58, - "id": "008ef48d", "metadata": {}, "outputs": [ { @@ -1751,7 +1688,6 @@ }, { "cell_type": "markdown", - "id": "2e8c0f2d", "metadata": {}, "source": [ "`x[1][1]` is yet another sublist, so adding one more index accesses its elements:" @@ -1760,7 +1696,6 @@ { "cell_type": "code", "execution_count": 59, - "id": "e21d0bfa", "metadata": {}, "outputs": [ { @@ -1781,7 +1716,6 @@ { "cell_type": "code", "execution_count": 60, - "id": "1089635f", "metadata": {}, "outputs": [ { @@ -1802,7 +1736,6 @@ { "cell_type": "code", "execution_count": 61, - "id": "c4f7356c", "metadata": {}, "outputs": [ { @@ -1822,7 +1755,6 @@ }, { "cell_type": "markdown", - "id": "ba86c2fe", "metadata": {}, "source": [ "There is no limit, short of the extent of your computer’s memory, to the depth or complexity with which lists can be nested in this way." @@ -1830,7 +1762,6 @@ }, { "cell_type": "markdown", - "id": "8eb1e152", "metadata": {}, "source": [ "All the usual syntax regarding indices and slicing applies to sublists as well:" @@ -1839,7 +1770,6 @@ { "cell_type": "code", "execution_count": 62, - "id": "67b5631b", "metadata": {}, "outputs": [ { @@ -1860,7 +1790,6 @@ { "cell_type": "code", "execution_count": 63, - "id": "4f9714c4", "metadata": {}, "outputs": [ { @@ -1881,7 +1810,6 @@ { "cell_type": "code", "execution_count": 64, - "id": "81a1dd51", "metadata": {}, "outputs": [ { @@ -1901,7 +1829,6 @@ }, { "cell_type": "markdown", - "id": "54539219", "metadata": {}, "source": [ "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 `x` using `len()`:" @@ -1910,7 +1837,6 @@ { "cell_type": "code", "execution_count": 65, - "id": "3e78a3f3", "metadata": {}, "outputs": [ { @@ -1931,7 +1857,6 @@ { "cell_type": "code", "execution_count": 66, - "id": "9b4e8070", "metadata": {}, "outputs": [ { @@ -1952,7 +1877,6 @@ { "cell_type": "code", "execution_count": 67, - "id": "0d39cd2b", "metadata": {}, "outputs": [ { @@ -1973,7 +1897,6 @@ { "cell_type": "code", "execution_count": 68, - "id": "46a1e57f", "metadata": {}, "outputs": [ { @@ -1994,7 +1917,6 @@ { "cell_type": "code", "execution_count": 69, - "id": "2bc7ba3b", "metadata": {}, "outputs": [ { @@ -2015,7 +1937,6 @@ { "cell_type": "code", "execution_count": 70, - "id": "e35f116f", "metadata": {}, "outputs": [ { @@ -2036,7 +1957,6 @@ { "cell_type": "code", "execution_count": 71, - "id": "32578a6b", "metadata": {}, "outputs": [ { @@ -2056,7 +1976,6 @@ }, { "cell_type": "markdown", - "id": "c1afc28b", "metadata": {}, "source": [ "`x` has only five elements—three strings and two sublists. The individual elements in the sublists don’t count toward `x`’s length." @@ -2064,7 +1983,6 @@ }, { "cell_type": "markdown", - "id": "73e857bf", "metadata": {}, "source": [ "You’d encounter a similar situation when using the in operator:" @@ -2073,7 +1991,6 @@ { "cell_type": "code", "execution_count": 72, - "id": "70d8feb6", "metadata": {}, "outputs": [ { @@ -2094,7 +2011,6 @@ { "cell_type": "code", "execution_count": 73, - "id": "4b79b4a8", "metadata": {}, "outputs": [ { @@ -2115,7 +2031,6 @@ { "cell_type": "code", "execution_count": 74, - "id": "0d691d61", "metadata": {}, "outputs": [ { @@ -2135,7 +2050,6 @@ }, { "cell_type": "markdown", - "id": "0f83d93c", "metadata": {}, "source": [ "`'ddd'` is not one of the elements in `x` or `x[1]`. It is only directly an element in the sublist `x[1][1]`. An individual element in a sublist does not count as an element of the parent `list(s)`." @@ -2143,16 +2057,17 @@ }, { "cell_type": "markdown", - "id": "ea5e4006", "metadata": {}, "source": [ - "### 5. Lists Are Mutable\n", + "\n", + "### 5. Lists Are Mutable [](#table_of_contents)\n", + "\n", + "\n", "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’t be further broken down. These types are immutable, meaning that they can’t be changed once they have been assigned. It doesn’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." ] }, { "cell_type": "markdown", - "id": "2034dc7c", "metadata": {}, "source": [ "By contrast, the string type is a composite type. Strings are reducible to smaller parts—the component characters. It might make sense to think of changing the characters in a string. But you can’t. In Python, strings are also immutable." @@ -2160,7 +2075,6 @@ }, { "cell_type": "markdown", - "id": "01e81a5a", "metadata": {}, "source": [ "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." @@ -2168,17 +2082,18 @@ }, { "cell_type": "markdown", - "id": "4d6f90a7", "metadata": {}, "source": [ - "#### Modifying a Single List Value\n", + "\n", + "#### Modifying a Single List Value [](#table_of_contents)\n", + "\n", + "\n", "A single value in a list can be replaced by indexing and simple assignment:" ] }, { "cell_type": "code", "execution_count": 83, - "id": "cc6bb5c6", "metadata": {}, "outputs": [], "source": [ @@ -2188,7 +2103,6 @@ { "cell_type": "code", "execution_count": 84, - "id": "2e5c019a", "metadata": {}, "outputs": [ { @@ -2209,7 +2123,6 @@ { "cell_type": "code", "execution_count": 85, - "id": "82256a14", "metadata": {}, "outputs": [], "source": [ @@ -2219,7 +2132,6 @@ { "cell_type": "code", "execution_count": 86, - "id": "3375ed03", "metadata": {}, "outputs": [], "source": [ @@ -2229,7 +2141,6 @@ { "cell_type": "code", "execution_count": 87, - "id": "67f42e68", "metadata": {}, "outputs": [ { @@ -2249,7 +2160,6 @@ }, { "cell_type": "markdown", - "id": "72ccef34", "metadata": {}, "source": [ "You may recall from the section on Strings and Character Data in Python that you can’t do this with a string:" @@ -2258,7 +2168,6 @@ { "cell_type": "code", "execution_count": 89, - "id": "5e0d7fcb", "metadata": {}, "outputs": [], "source": [ @@ -2268,7 +2177,6 @@ { "cell_type": "code", "execution_count": 90, - "id": "7b2952e4", "metadata": {}, "outputs": [ { @@ -2289,7 +2197,6 @@ }, { "cell_type": "markdown", - "id": "2b911673", "metadata": {}, "source": [ "A list item can be deleted with the `del` command:" @@ -2298,7 +2205,6 @@ { "cell_type": "code", "execution_count": 92, - "id": "18d15d1f", "metadata": {}, "outputs": [], "source": [ @@ -2308,7 +2214,6 @@ { "cell_type": "code", "execution_count": 93, - "id": "d8caa2b0", "metadata": {}, "outputs": [], "source": [ @@ -2318,7 +2223,6 @@ { "cell_type": "code", "execution_count": 94, - "id": "de0c5d08", "metadata": {}, "outputs": [ { @@ -2338,10 +2242,12 @@ }, { "cell_type": "markdown", - "id": "cbe55162", "metadata": {}, "source": [ - "#### Modifying Multiple List Values\n", + "\n", + "#### Modifying Multiple List Values [](#table_of_contents)\n", + "\n", + "\n", "\n", "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:\n", "\n", @@ -2352,7 +2258,6 @@ }, { "cell_type": "markdown", - "id": "4a99e7fc", "metadata": {}, "source": [ "Again, for the moment, think of an iterable as a list. This assignment replaces the specified slice of a with ``:" @@ -2361,7 +2266,6 @@ { "cell_type": "code", "execution_count": 242, - "id": "74da295b", "metadata": {}, "outputs": [], "source": [ @@ -2371,7 +2275,6 @@ { "cell_type": "code", "execution_count": 243, - "id": "5aae64b9", "metadata": {}, "outputs": [ { @@ -2392,7 +2295,6 @@ { "cell_type": "code", "execution_count": 244, - "id": "7ea4c9c2", "metadata": {}, "outputs": [], "source": [ @@ -2402,7 +2304,6 @@ { "cell_type": "code", "execution_count": 245, - "id": "76994c62", "metadata": {}, "outputs": [ { @@ -2423,7 +2324,6 @@ { "cell_type": "code", "execution_count": 99, - "id": "b56fecb6", "metadata": {}, "outputs": [ { @@ -2444,7 +2344,6 @@ { "cell_type": "code", "execution_count": 100, - "id": "aaf1a477", "metadata": {}, "outputs": [], "source": [ @@ -2454,7 +2353,6 @@ { "cell_type": "code", "execution_count": 101, - "id": "b23cf51b", "metadata": {}, "outputs": [ { @@ -2474,7 +2372,6 @@ }, { "cell_type": "markdown", - "id": "1cbe3508", "metadata": {}, "source": [ "The number of elements inserted need not be equal to the number replaced. Python just grows or shrinks the list as needed." @@ -2482,7 +2379,6 @@ }, { "cell_type": "markdown", - "id": "0f9fd23a", "metadata": {}, "source": [ "You can insert multiple elements in place of a single element—just use a slice that denotes only one element:" @@ -2491,7 +2387,6 @@ { "cell_type": "code", "execution_count": 102, - "id": "246ce51d", "metadata": {}, "outputs": [], "source": [ @@ -2501,7 +2396,6 @@ { "cell_type": "code", "execution_count": 103, - "id": "6b83bcc5", "metadata": {}, "outputs": [], "source": [ @@ -2511,7 +2405,6 @@ { "cell_type": "code", "execution_count": 104, - "id": "f55f6bdd", "metadata": {}, "outputs": [ { @@ -2531,7 +2424,6 @@ }, { "cell_type": "markdown", - "id": "f49b0899", "metadata": {}, "source": [ "Note that this is not the same as replacing the single element with a list:" @@ -2540,7 +2432,6 @@ { "cell_type": "code", "execution_count": 106, - "id": "949ce113", "metadata": {}, "outputs": [], "source": [ @@ -2550,7 +2441,6 @@ { "cell_type": "code", "execution_count": 107, - "id": "11c7f9f6", "metadata": {}, "outputs": [], "source": [ @@ -2560,7 +2450,6 @@ { "cell_type": "code", "execution_count": 108, - "id": "8d58652b", "metadata": {}, "outputs": [ { @@ -2580,7 +2469,6 @@ }, { "cell_type": "markdown", - "id": "5d73ed33", "metadata": {}, "source": [ "You can also insert elements into a list without removing anything. Simply specify a slice of the form `[n:n]` (a zero-length slice) at the desired index:" @@ -2589,7 +2477,6 @@ { "cell_type": "code", "execution_count": 109, - "id": "1a9c2a32", "metadata": {}, "outputs": [], "source": [ @@ -2599,7 +2486,6 @@ { "cell_type": "code", "execution_count": 110, - "id": "d0626b56", "metadata": {}, "outputs": [], "source": [ @@ -2609,7 +2495,6 @@ { "cell_type": "code", "execution_count": 111, - "id": "4e7c3244", "metadata": {}, "outputs": [ { @@ -2629,7 +2514,6 @@ }, { "cell_type": "markdown", - "id": "8bba76d8", "metadata": {}, "source": [ "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 del statement with the same slice:" @@ -2638,7 +2522,6 @@ { "cell_type": "code", "execution_count": 115, - "id": "7bcf5f1f", "metadata": {}, "outputs": [], "source": [ @@ -2648,7 +2531,6 @@ { "cell_type": "code", "execution_count": 116, - "id": "99f2580f", "metadata": {}, "outputs": [], "source": [ @@ -2658,7 +2540,6 @@ { "cell_type": "code", "execution_count": 117, - "id": "d047bbff", "metadata": {}, "outputs": [ { @@ -2679,7 +2560,6 @@ { "cell_type": "code", "execution_count": 118, - "id": "6c54c55b", "metadata": {}, "outputs": [], "source": [ @@ -2689,7 +2569,6 @@ { "cell_type": "code", "execution_count": 119, - "id": "9dfeb0e2", "metadata": {}, "outputs": [], "source": [ @@ -2699,7 +2578,6 @@ { "cell_type": "code", "execution_count": 246, - "id": "38b8462e", "metadata": {}, "outputs": [ { @@ -2719,10 +2597,11 @@ }, { "cell_type": "markdown", - "id": "b7219cc5", "metadata": {}, "source": [ - "#### Prepending or Appending Items to a List\n", + "\n", + "#### Prepending or Appending Items to a List [](#table_of_contents)\n", + "\n", "\n", "Additional items can be added to the start or end of a list using the + concatenation operator or the `+=` augmented assignment operator:" ] @@ -2730,7 +2609,6 @@ { "cell_type": "code", "execution_count": 121, - "id": "0d66853f", "metadata": {}, "outputs": [], "source": [ @@ -2740,7 +2618,6 @@ { "cell_type": "code", "execution_count": 122, - "id": "43e20929", "metadata": {}, "outputs": [], "source": [ @@ -2750,7 +2627,6 @@ { "cell_type": "code", "execution_count": 123, - "id": "15bde346", "metadata": {}, "outputs": [ { @@ -2771,7 +2647,6 @@ { "cell_type": "code", "execution_count": 124, - "id": "3a607bd9", "metadata": {}, "outputs": [], "source": [ @@ -2781,7 +2656,6 @@ { "cell_type": "code", "execution_count": 125, - "id": "797c39bb", "metadata": {}, "outputs": [], "source": [ @@ -2791,7 +2665,6 @@ { "cell_type": "code", "execution_count": 126, - "id": "11c45a8b", "metadata": {}, "outputs": [ { @@ -2811,7 +2684,6 @@ }, { "cell_type": "markdown", - "id": "12bbfca7", "metadata": {}, "source": [ "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:" @@ -2820,7 +2692,6 @@ { "cell_type": "code", "execution_count": 127, - "id": "6169fab4", "metadata": {}, "outputs": [ { @@ -2843,7 +2714,6 @@ { "cell_type": "code", "execution_count": 128, - "id": "8168bcf0", "metadata": {}, "outputs": [], "source": [ @@ -2853,7 +2723,6 @@ { "cell_type": "code", "execution_count": 119, - "id": "53ec6cc3", "metadata": {}, "outputs": [ { @@ -2873,7 +2742,6 @@ }, { "cell_type": "markdown", - "id": "c432ab55", "metadata": {}, "source": [ "> **Note:** Technically, it isn’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.\n", @@ -2897,17 +2765,18 @@ }, { "cell_type": "markdown", - "id": "3c679f5f", "metadata": {}, "source": [ - "### 6. Lists Are Dynamic\n", + "\n", + "### 6. Lists Are Dynamic [](#table_of_contents)\n", + "\n", + "\n", "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:" ] }, { "cell_type": "code", "execution_count": 135, - "id": "07222c9a", "metadata": {}, "outputs": [], "source": [ @@ -2917,7 +2786,6 @@ { "cell_type": "code", "execution_count": 136, - "id": "90e7fd91", "metadata": {}, "outputs": [], "source": [ @@ -2927,7 +2795,6 @@ { "cell_type": "code", "execution_count": 137, - "id": "c860669c", "metadata": {}, "outputs": [], "source": [ @@ -2937,7 +2804,6 @@ { "cell_type": "code", "execution_count": 138, - "id": "59f45737", "metadata": {}, "outputs": [ { @@ -2957,7 +2823,6 @@ }, { "cell_type": "markdown", - "id": "efebeb5e", "metadata": {}, "source": [ "Similarly, a list shrinks to accommodate the removal of items:" @@ -2966,7 +2831,6 @@ { "cell_type": "code", "execution_count": 139, - "id": "9e8025f4", "metadata": {}, "outputs": [], "source": [ @@ -2976,7 +2840,6 @@ { "cell_type": "code", "execution_count": 140, - "id": "1bfa206c", "metadata": {}, "outputs": [], "source": [ @@ -2986,7 +2849,6 @@ { "cell_type": "code", "execution_count": 141, - "id": "bcb842d3", "metadata": {}, "outputs": [], "source": [ @@ -2996,7 +2858,6 @@ { "cell_type": "code", "execution_count": 279, - "id": "c7f29cd7", "metadata": { "scrolled": true }, @@ -3018,21 +2879,23 @@ }, { "cell_type": "markdown", - "id": "779ebac7", "metadata": {}, "source": [ - "\n", - "## Python Tuples\n", + "\n", + "## Python Tuples [](#table_of_contents)\n", + "\n", "\n", "Python provides another type that is an ordered collection of objects, called a tuple." ] }, { "cell_type": "markdown", - "id": "9d19ee98", "metadata": {}, "source": [ - "### Defining and Using Tuples\n", + "\n", + "### Defining and Using Tuples [](#table_of_contents)\n", + "\n", + "\n", "Tuples are identical to lists in all respects, except for the following properties:\n", "\n", "- Tuples are defined by enclosing the elements in parentheses (`()`) instead of square brackets `[]`).\n", @@ -3041,7 +2904,6 @@ }, { "cell_type": "markdown", - "id": "58fc91ae", "metadata": {}, "source": [ "Here is a short example showing a tuple definition, indexing, and slicing:" @@ -3050,7 +2912,6 @@ { "cell_type": "code", "execution_count": 299, - "id": "8a21fd5f", "metadata": {}, "outputs": [], "source": [ @@ -3060,7 +2921,6 @@ { "cell_type": "code", "execution_count": 300, - "id": "4b5c124e", "metadata": {}, "outputs": [ { @@ -3081,7 +2941,6 @@ { "cell_type": "code", "execution_count": 301, - "id": "e7cd310e", "metadata": {}, "outputs": [ { @@ -3102,7 +2961,6 @@ { "cell_type": "code", "execution_count": 302, - "id": "b447fd42", "metadata": {}, "outputs": [ { @@ -3123,7 +2981,6 @@ { "cell_type": "code", "execution_count": 303, - "id": "4a97577a", "metadata": {}, "outputs": [ { @@ -3143,7 +3000,6 @@ }, { "cell_type": "markdown", - "id": "aa9a0f3b", "metadata": {}, "source": [ "Never fear! Our favorite string and list reversal mechanism works for tuples as well:" @@ -3152,7 +3008,6 @@ { "cell_type": "code", "execution_count": 304, - "id": "c0e9af40", "metadata": {}, "outputs": [ { @@ -3172,7 +3027,6 @@ }, { "cell_type": "markdown", - "id": "fdb1c32a", "metadata": {}, "source": [ "> Note: Even though tuples are defined using parentheses, you still index and slice tuples using square brackets, just as for strings and lists." @@ -3180,7 +3034,6 @@ }, { "cell_type": "markdown", - "id": "ca8d5e75", "metadata": {}, "source": [ "Everything you’ve learned about lists—they are ordered, they can contain arbitrary objects, they can be indexed and sliced, they can be nested—is true of tuples as well. But they can’t be modified:" @@ -3189,7 +3042,6 @@ { "cell_type": "code", "execution_count": 305, - "id": "29c14a99", "metadata": {}, "outputs": [ { @@ -3211,7 +3063,6 @@ }, { "cell_type": "markdown", - "id": "d3c309c0", "metadata": {}, "source": [ "Why use a tuple instead of a list?\n", @@ -3225,7 +3076,6 @@ }, { "cell_type": "markdown", - "id": "77c610d9", "metadata": {}, "source": [ "In a Python REPL session, you can display the values of several objects simultaneously by entering them directly at the `>>>` prompt, separated by commas:" @@ -3234,7 +3084,6 @@ { "cell_type": "code", "execution_count": 150, - "id": "ab20cb42", "metadata": {}, "outputs": [], "source": [ @@ -3244,7 +3093,6 @@ { "cell_type": "code", "execution_count": 151, - "id": "33a267f4", "metadata": {}, "outputs": [], "source": [ @@ -3254,7 +3102,6 @@ { "cell_type": "code", "execution_count": 152, - "id": "0ca51e51", "metadata": {}, "outputs": [ { @@ -3274,7 +3121,6 @@ }, { "cell_type": "markdown", - "id": "dca838bf", "metadata": {}, "source": [ "Python displays the response in parentheses because it is implicitly interpreting the input as a tuple." @@ -3282,7 +3128,6 @@ }, { "cell_type": "markdown", - "id": "1a4ca1ce", "metadata": {}, "source": [ "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:" @@ -3291,7 +3136,6 @@ { "cell_type": "code", "execution_count": 346, - "id": "71c13a4e", "metadata": {}, "outputs": [ { @@ -3313,7 +3157,6 @@ { "cell_type": "code", "execution_count": 347, - "id": "9182eb81", "metadata": {}, "outputs": [ { @@ -3335,7 +3178,6 @@ { "cell_type": "code", "execution_count": 348, - "id": "0f792121", "metadata": {}, "outputs": [ { @@ -3356,7 +3198,6 @@ }, { "cell_type": "markdown", - "id": "94149463", "metadata": {}, "source": [ "But what happens when you try to define a tuple with one item:" @@ -3365,7 +3206,6 @@ { "cell_type": "code", "execution_count": 349, - "id": "482ddc41", "metadata": {}, "outputs": [ { @@ -3386,7 +3226,6 @@ }, { "cell_type": "markdown", - "id": "278c54f2", "metadata": {}, "source": [ "Doh! Since parentheses are also used to define operator precedence in expressions, Python evaluates the expression `(2)` as simply the integer `2` and creates an int object. To tell Python that you really want to define a singleton tuple, include a trailing comma `(,)` just before the closing parenthesis:" @@ -3395,7 +3234,6 @@ { "cell_type": "code", "execution_count": 350, - "id": "978af638", "metadata": {}, "outputs": [ { @@ -3417,7 +3255,6 @@ { "cell_type": "code", "execution_count": 351, - "id": "dc15be8f", "metadata": {}, "outputs": [ { @@ -3438,7 +3275,6 @@ { "cell_type": "code", "execution_count": 352, - "id": "221ed952", "metadata": {}, "outputs": [ { @@ -3458,7 +3294,6 @@ }, { "cell_type": "markdown", - "id": "e67604f3", "metadata": {}, "source": [ "You probably won’t need to define a singleton tuple often, but there has to be a way." @@ -3466,7 +3301,6 @@ }, { "cell_type": "markdown", - "id": "f1c8e7d6", "metadata": {}, "source": [ "When you display a singleton tuple, Python includes the comma, to remind you that it’s a tuple:" @@ -3475,7 +3309,6 @@ { "cell_type": "code", "execution_count": 166, - "id": "fc8bc0fc", "metadata": {}, "outputs": [ { @@ -3495,10 +3328,11 @@ }, { "cell_type": "markdown", - "id": "89dd7789", "metadata": {}, "source": [ - "### Tuple Assignment, Packing, and Unpacking\n", + "\n", + "### Tuple Assignment, Packing, and Unpacking [](#table_of_contents)\n", + "\n", "\n", "As you have already seen above, a literal tuple containing several items can be assigned to a single object:" ] @@ -3506,7 +3340,6 @@ { "cell_type": "code", "execution_count": 69, - "id": "b4bdef2f", "metadata": {}, "outputs": [], "source": [ @@ -3515,7 +3348,6 @@ }, { "cell_type": "markdown", - "id": "303f6805", "metadata": {}, "source": [ "\"tuple-packing\"" @@ -3524,7 +3356,6 @@ { "cell_type": "code", "execution_count": 70, - "id": "9db2d631", "metadata": {}, "outputs": [ { @@ -3545,7 +3376,6 @@ { "cell_type": "code", "execution_count": 71, - "id": "7a298e62", "metadata": {}, "outputs": [ { @@ -3566,7 +3396,6 @@ { "cell_type": "code", "execution_count": 72, - "id": "8e9180a0", "metadata": {}, "outputs": [ { @@ -3586,7 +3415,6 @@ }, { "cell_type": "markdown", - "id": "7d2ce889", "metadata": {}, "source": [ "If that “packed” object is subsequently assigned to a new tuple, the individual items are “unpacked” into the objects in the tuple:" @@ -3594,7 +3422,6 @@ }, { "cell_type": "markdown", - "id": "2cf73f03", "metadata": {}, "source": [ "\"tuple-unpacking\"" @@ -3603,7 +3430,6 @@ { "cell_type": "code", "execution_count": 174, - "id": "022d4f57", "metadata": {}, "outputs": [], "source": [ @@ -3613,7 +3439,6 @@ { "cell_type": "code", "execution_count": 175, - "id": "bf059422", "metadata": {}, "outputs": [ { @@ -3634,7 +3459,6 @@ { "cell_type": "code", "execution_count": 176, - "id": "dd38c5cf", "metadata": {}, "outputs": [ { @@ -3655,7 +3479,6 @@ { "cell_type": "code", "execution_count": 177, - "id": "f1b61f04", "metadata": {}, "outputs": [ { @@ -3676,7 +3499,6 @@ { "cell_type": "code", "execution_count": 178, - "id": "89c0d428", "metadata": {}, "outputs": [ { @@ -3696,7 +3518,6 @@ }, { "cell_type": "markdown", - "id": "b145cde5", "metadata": {}, "source": [ "When unpacking, the number of variables on the left must match the number of values in the tuple:" @@ -3705,7 +3526,6 @@ { "cell_type": "code", "execution_count": 191, - "id": "daee90ca", "metadata": {}, "outputs": [ { @@ -3727,7 +3547,6 @@ { "cell_type": "code", "execution_count": 192, - "id": "36b6bcb2", "metadata": {}, "outputs": [ { @@ -3748,7 +3567,6 @@ }, { "cell_type": "markdown", - "id": "7048d14f", "metadata": {}, "source": [ "Packing and unpacking can be combined into one statement to make a compound assignment:" @@ -3757,7 +3575,6 @@ { "cell_type": "code", "execution_count": 197, - "id": "ada847c3", "metadata": {}, "outputs": [], "source": [ @@ -3767,7 +3584,6 @@ { "cell_type": "code", "execution_count": 198, - "id": "1c204276", "metadata": {}, "outputs": [ { @@ -3788,7 +3604,6 @@ { "cell_type": "code", "execution_count": 199, - "id": "4f181eb8", "metadata": {}, "outputs": [ { @@ -3809,7 +3624,6 @@ { "cell_type": "code", "execution_count": 200, - "id": "bb0bf08c", "metadata": {}, "outputs": [ { @@ -3830,7 +3644,6 @@ { "cell_type": "code", "execution_count": 201, - "id": "b0de32a6", "metadata": {}, "outputs": [ { @@ -3850,7 +3663,6 @@ }, { "cell_type": "markdown", - "id": "bdc934c6", "metadata": {}, "source": [ "Again, the number of elements in the tuple on the left of the assignment must equal the number on the right:" @@ -3859,7 +3671,6 @@ { "cell_type": "code", "execution_count": 202, - "id": "1d1e42ef", "metadata": {}, "outputs": [ { @@ -3880,7 +3691,6 @@ }, { "cell_type": "markdown", - "id": "13931cbc", "metadata": {}, "source": [ "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:" @@ -3889,7 +3699,6 @@ { "cell_type": "code", "execution_count": 203, - "id": "d301d74c", "metadata": {}, "outputs": [ { @@ -3911,7 +3720,6 @@ { "cell_type": "code", "execution_count": 204, - "id": "4eaf55b5", "metadata": {}, "outputs": [ { @@ -3933,7 +3741,6 @@ { "cell_type": "code", "execution_count": 205, - "id": "4a2c32c5", "metadata": {}, "outputs": [ { @@ -3955,7 +3762,6 @@ { "cell_type": "code", "execution_count": 206, - "id": "ecdd33ca", "metadata": {}, "outputs": [ { @@ -3976,7 +3782,6 @@ }, { "cell_type": "markdown", - "id": "0b5e39bb", "metadata": {}, "source": [ "It works the same whether the parentheses are included or not, so if you have any doubt as to whether they’re needed, go ahead and include them." @@ -3984,7 +3789,6 @@ }, { "cell_type": "markdown", - "id": "27814877", "metadata": {}, "source": [ "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:" @@ -3993,7 +3797,6 @@ { "cell_type": "code", "execution_count": 207, - "id": "840beb6d", "metadata": {}, "outputs": [ { @@ -4016,7 +3819,6 @@ { "cell_type": "code", "execution_count": 210, - "id": "94eda2d2", "metadata": {}, "outputs": [ { @@ -4039,7 +3841,6 @@ }, { "cell_type": "markdown", - "id": "717db98e", "metadata": {}, "source": [ "In Python, the swap can be done with a single tuple assignment:" @@ -4048,7 +3849,6 @@ { "cell_type": "code", "execution_count": 212, - "id": "46350be1", "metadata": {}, "outputs": [ { @@ -4071,7 +3871,6 @@ { "cell_type": "code", "execution_count": 213, - "id": "d934380b", "metadata": {}, "outputs": [], "source": [ @@ -4081,7 +3880,6 @@ { "cell_type": "code", "execution_count": 214, - "id": "6f2c968e", "metadata": {}, "outputs": [ { @@ -4101,7 +3899,6 @@ }, { "cell_type": "markdown", - "id": "ad4cb308", "metadata": {}, "source": [ "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." @@ -4110,7 +3907,6 @@ { "cell_type": "code", "execution_count": 383, - "id": "16b352b7", "metadata": {}, "outputs": [], "source": [ @@ -4120,7 +3916,6 @@ { "cell_type": "code", "execution_count": 384, - "id": "41ad8b4d", "metadata": {}, "outputs": [ { @@ -4140,16 +3935,17 @@ }, { "cell_type": "markdown", - "id": "8756eecb", "metadata": {}, "source": [ - "## Conclusion\n", + "\n", + "## Conclusion [](#table_of_contents)\n", + "\n", + "\n", "This tutorial covered the basic properties of Python **lists** and **tuples**, and how to manipulate them. You will use these extensively in your Python programming." ] }, { "cell_type": "markdown", - "id": "dcc73545", "metadata": {}, "source": [ "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’t be modified.)" @@ -4157,7 +3953,6 @@ }, { "cell_type": "markdown", - "id": "d19954dc", "metadata": {}, "source": [ "The next tutorial will introduce you to the Python **dictionary**: a composite data type that is unordered. Read on!" @@ -4180,7 +3975,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/python/01. Basics/09 Composite Data Types: Dictionary.ipynb b/Python/01. Basics/09 Composite Data Types: Dictionary.ipynb similarity index 88% rename from python/01. Basics/09 Composite Data Types: Dictionary.ipynb rename to Python/01. Basics/09 Composite Data Types: Dictionary.ipynb index 26116da..d69089c 100755 --- a/python/01. Basics/09 Composite Data Types: Dictionary.ipynb +++ b/Python/01. Basics/09 Composite Data Types: Dictionary.ipynb @@ -4,11 +4,37 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Dictionary\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Dictionary \n", "\n", "Python provides another composite data type called a dictionary, which is similar to a list in that it is a collection of objects." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents\n", + "\n", + "\n", + "* [Defining a Dictionary](#defining_a_dictionary)\n", + "* [Accessing Dictionary Values](#accessing_dictionary_values)\n", + "* [Dictionary Keys vs. List Indices](#dictionary_keys_vs._list_indices)\n", + "* [Building a Dictionary Incrementally](#building_a_dictionary_incrementally)\n", + "* [Restrictions on Dictionary Keys](#restrictions_on_dictionary_keys)\n", + "* [Restrictions on Dictionary Values](#restrictions_on_dictionary_values)\n", + "* [ Conclusion](#conclusion)\n", + "\n", + "---" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -34,7 +60,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Defining a Dictionary\n", + "\n", + "## Defining a Dictionary [](#table_of_contents)\n", + "\n", + "\n", "Dictionaries are Python’s implementation of a data structure that is more generally known as an associative array. A dictionary consists of a collection of key-value pairs. Each key-value pair maps the key to its associated value." ] }, @@ -207,18 +236,18 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 18, "metadata": {}, "outputs": [ { - "ename": "KeyError", - "evalue": "1", + "ename": "NameError", + "evalue": "name 'MLB_team' is not defined", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m: 1" + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_19329/1469821463.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name 'MLB_team' is not defined" ] } ], @@ -230,7 +259,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Accessing Dictionary Values\n", + "\n", + "## Accessing Dictionary Values [](#table_of_contents)\n", + "\n", "\n", "Of course, dictionary elements must be accessible somehow. If you don’t get them by index, then how do you get them?" ] @@ -385,21 +416,19 @@ }, { "cell_type": "code", - "execution_count": 65, + "execution_count": 26, "metadata": {}, "outputs": [ { - "data": { - "text/plain": [ - "{'Colorado': 'Rockies',\n", - " 'Boston': 'Red Sox',\n", - " 'Minnesota': 'Twins',\n", - " 'Milwaukee': 'Brewers'}" - ] - }, - "execution_count": 65, - "metadata": {}, - "output_type": "execute_result" + "ename": "NameError", + "evalue": "name 'MLB_team' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_19329/3737734966.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mdel\u001b[0m \u001b[0mMLB_team\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'Seattle'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mMLB_team\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'MLB_team' is not defined" + ] } ], "source": [ @@ -411,7 +440,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Dictionary Keys vs. List Indices\n", + "\n", + "## Dictionary Keys vs. List Indices [](#table_of_contents)\n", + "\n", + "\n", "You may have noticed that the interpreter raises the same exception, KeyError, when a dictionary is accessed with either an undefined key or by a numeric index:" ] }, @@ -650,7 +682,7 @@ }, { "cell_type": "code", - "execution_count": 83, + "execution_count": 50, "metadata": {}, "outputs": [ { @@ -660,7 +692,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_19329/3015485889.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0md\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'd' is not defined" ] } @@ -682,7 +714,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Building a Dictionary Incrementally\n", + "\n", + "## Building a Dictionary Incrementally [](#table_of_contents)\n", + "\n", "\n", "Defining a dictionary using curly braces and a list of key-value pairs, as shown above, is fine if you know all the keys and values in advance. But what if you want to build a dictionary on the fly?" ] @@ -696,7 +730,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 118, "metadata": {}, "outputs": [ { @@ -705,7 +739,7 @@ "dict" ] }, - "execution_count": 26, + "execution_count": 118, "metadata": {}, "output_type": "execute_result" } @@ -988,7 +1022,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Restrictions on Dictionary Keys\n", + "\n", + "## Restrictions on Dictionary Keys [](#table_of_contents)\n", + "\n", "\n", "Almost any type of value can be used as a dictionary key in Python. You just saw this example, where integer, float, and Boolean objects are used as keys:" ] @@ -1064,7 +1100,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 139, "metadata": {}, "outputs": [ { @@ -1073,7 +1109,7 @@ "3" ] }, - "execution_count": 41, + "execution_count": 139, "metadata": {}, "output_type": "execute_result" } @@ -1310,7 +1346,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Restrictions on Dictionary Values\n", + "\n", + "## Restrictions on Dictionary Values [](#table_of_contents)\n", + "\n", + "\n", "By contrast, there are no restrictions on dictionary values. Literally none at all. A dictionary value can be any type of object Python supports, including mutable types like lists and dictionaries, and user-defined objects, which you will learn about in upcoming tutorials." ] }, @@ -1366,7 +1405,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Conclusion\n", + "\n", + "## Conclusion [](#table_of_contents)\n", + "\n", + "\n", "In this tutorial, you covered the basic properties of the Python **dictionary** and learned how to access and manipulate dictionary data." ] }, @@ -1408,7 +1450,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/python/01. Basics/10 Composite Data Types: Sets.ipynb b/Python/01. Basics/10 Composite Data Types: Sets.ipynb similarity index 80% rename from python/01. Basics/10 Composite Data Types: Sets.ipynb rename to Python/01. Basics/10 Composite Data Types: Sets.ipynb index b5698b1..7ae1c11 100755 --- a/python/01. Basics/10 Composite Data Types: Sets.ipynb +++ b/Python/01. Basics/10 Composite Data Types: Sets.ipynb @@ -4,11 +4,33 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Set\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Set \n", "\n", "In mathematics, a rigorous definition of a set can be abstract and difficult to grasp. Practically though, a set can be thought of simply as a well-defined collection of distinct objects, typically called **elements** or **members**." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents\n", + "\n", + "\n", + "* [Defining a Set](#defining_a_set)\n", + "* [Set Size and Membership](#set_size_and_membership)\n", + "* [ Conclusion](#conclusion)\n", + "\n", + "---" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -20,7 +42,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Defining a Set\n", + "\n", + "## Defining a Set [](#table_of_contents)\n", + "\n", "\n", "Python’s built-in set type has the following characteristics:\n", "\n", @@ -42,6 +66,142 @@ "```" ] }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "x = {3, 8, 1}" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8\n", + "1\n", + "3\n" + ] + } + ], + "source": [ + "for item in x:\n", + " print(item)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "x = {}" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "a\n", + "e\n", + "h\n", + "l\n", + "s\n" + ] + } + ], + "source": [ + "for char in 'abcdefghijklmnopqrstuvwxyz':\n", + " hash_value = hash(char)\n", + " hash_hash_value = hash(hash_value)\n", + " \n", + " if hash_value == hash_hash_value:\n", + " print(char)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1753726360175525413" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hash('a')" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [], + "source": [ + "x = {\n", + " 'a': 1,\n", + " 1753726360175525413: 2,\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'a': 1, 1753726360175525413: 2}" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "x" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "5603912153990001835" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "hash('a str')" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -543,14 +703,16 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Set Size and Membership\n", + "\n", + "## Set Size and Membership [](#table_of_contents)\n", + "\n", "\n", "The `len()` function returns the number of elements in a set, and the `in` and `not in` operators can be used to test for membership:" ] }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 107, "metadata": {}, "outputs": [], "source": [ @@ -559,7 +721,7 @@ }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 108, "metadata": {}, "outputs": [ { @@ -568,7 +730,7 @@ "3" ] }, - "execution_count": 25, + "execution_count": 108, "metadata": {}, "output_type": "execute_result" } @@ -599,7 +761,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 243, "metadata": {}, "outputs": [ { @@ -608,7 +770,7 @@ "False" ] }, - "execution_count": 28, + "execution_count": 243, "metadata": {}, "output_type": "execute_result" } @@ -621,7 +783,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Conclusion\n", + "\n", + "## Conclusion [](#table_of_contents)\n", + "\n", "\n", "In this tutorial, you learned how to define set objects in Python, and you became familiar with the functions, operators, and methods that can be used to work with sets." ] @@ -657,7 +821,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/python/01. Basics/11 Python Program Lexical Structure.ipynb b/Python/01. Basics/11 Python Program Lexical Structure.ipynb similarity index 89% rename from python/01. Basics/11 Python Program Lexical Structure.ipynb rename to Python/01. Basics/11 Python Program Lexical Structure.ipynb index 1d7fe0c..1a0157a 100755 --- a/python/01. Basics/11 Python Program Lexical Structure.ipynb +++ b/Python/01. Basics/11 Python Program Lexical Structure.ipynb @@ -4,7 +4,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Python Program Lexical Structure\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Python Program Lexical Structure \n", "\n", "You have now covered Python variables, operators, and data types in depth, and you’ve seen quite a bit of example code. Up to now, the code has consisted of short individual statements, simply assigning objects to variables or displaying values.\n", "\n", @@ -15,7 +22,33 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Python Statements\n", + "\n", + "## Table of Contents \n", + "\n", + "\n", + "* [Python Statements](#python_statements)\n", + "* [Line Continuation](#line_continuation)\n", + " * [Implicit Line Continuation](#implicit_line_continuation)\n", + " * [Parentheses](#parentheses)\n", + " * [Curly Braces](#curly_braces)\n", + " * [Square Brackets](#square_brackets)\n", + " * [Explicit Line Continuation](#explicit_line_continuation)\n", + "* [Multiple Statements Per Line](#multiple_statements_per_line)\n", + "* [Comments](#comments)\n", + "* [Whitespace](#whitespace)\n", + "* [Whitespace as Indentation](#whitespace_as_indentation)\n", + "* [ Conclusion](#conclusion)\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Python Statements [](#table_of_contents)\n", + "\n", "\n", "Statements are the basic units of instruction that the Python interpreter parses and processes. In general, the interpreter executes statements sequentially, one after the next as it encounters them. (You will see in the next tutorial on conditional statements that it is possible to alter this behavior.)" ] @@ -73,14 +106,16 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Line Continuation\n", + "\n", + "## Line Continuation [](#table_of_contents)\n", + "\n", "\n", "Suppose a single statement in your Python code is especially long. For example, you may have an assignment statement with many terms:" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -91,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -100,7 +135,7 @@ "True" ] }, - "execution_count": 7, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -186,15 +221,15 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 15, "metadata": {}, "outputs": [ { "ename": "SyntaxError", - "evalue": "invalid syntax (, line 1)", + "evalue": "invalid syntax (1911760183.py, line 1)", "output_type": "error", "traceback": [ - "\u001b[0;36m File \u001b[0;32m\"\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m someone_is_of_working_age = person1_age >= 18 and person1_age <= 65 or\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" + "\u001b[0;36m File \u001b[0;32m\"/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_50053/1911760183.py\"\u001b[0;36m, line \u001b[0;32m1\u001b[0m\n\u001b[0;31m someone_is_of_working_age = person1_age >= 18 and person1_age <= 65 or\u001b[0m\n\u001b[0m ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m invalid syntax\n" ] } ], @@ -213,7 +248,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Implicit Line Continuation\n", + "\n", + "### Implicit Line Continuation [](#table_of_contents)\n", + "\n", "\n", "This is the more straightforward technique for line continuation, and the one that is preferred according to PEP 8." ] @@ -234,7 +271,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -249,7 +286,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 26, "metadata": {}, "outputs": [ { @@ -262,7 +299,7 @@ " [21, 22, 23, 24, 25]]" ] }, - "execution_count": 12, + "execution_count": 26, "metadata": {}, "output_type": "execute_result" } @@ -322,7 +359,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Parentheses\n", + "\n", + "#### Parentheses [](#table_of_contents)\n", + "\n", "\n", "- Expression grouping" ] @@ -369,7 +408,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -441,7 +480,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Curly Braces" + "\n", + "#### Curly Braces [](#table_of_contents)\n", + "\n" ] }, { @@ -487,7 +528,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### Square Brackets" + "\n", + "#### Square Brackets [](#table_of_contents)\n", + "\n" ] }, { @@ -612,7 +655,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 35, "metadata": {}, "outputs": [], "source": [ @@ -631,7 +674,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 36, "metadata": {}, "outputs": [ { @@ -640,7 +683,7 @@ "[[['foo', 'bar'], [1, 2, 3]], {1, 3, 5}, {'a': 1, 'b': 2}]" ] }, - "execution_count": 27, + "execution_count": 36, "metadata": {}, "output_type": "execute_result" } @@ -660,7 +703,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Explicit Line Continuation" + "\n", + "### Explicit Line Continuation [](#table_of_contents)\n", + "\n" ] }, { @@ -722,7 +767,7 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -752,7 +797,7 @@ }, { "cell_type": "code", - "execution_count": 46, + "execution_count": 44, "metadata": {}, "outputs": [], "source": [ @@ -763,7 +808,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 45, "metadata": {}, "outputs": [ { @@ -772,7 +817,7 @@ "21" ] }, - "execution_count": 35, + "execution_count": 45, "metadata": {}, "output_type": "execute_result" } @@ -818,7 +863,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Multiple Statements Per Line\n", + "\n", + "## Multiple Statements Per Line [](#table_of_contents)\n", + "\n", "\n", "Multiple statements may occur on one line, if they are separated by a semicolon (`;`) character:" ] @@ -860,7 +907,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 57, "metadata": {}, "outputs": [], "source": [ @@ -869,7 +916,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 58, "metadata": {}, "outputs": [ { @@ -904,7 +951,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Comments\n", + "\n", + "## Comments [](#table_of_contents)\n", + "\n", "\n", "In Python, the hash character (`#`) signifies a comment. The interpreter will ignore everything from the hash character through the end of that line:" ] @@ -964,7 +1013,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 59, "metadata": {}, "outputs": [ { @@ -973,7 +1022,7 @@ "'foobar # I am *not* a comment.'" ] }, - "execution_count": 54, + "execution_count": 59, "metadata": {}, "output_type": "execute_result" } @@ -997,7 +1046,6 @@ "outputs": [], "source": [ "# Calculate and display the area of a circle.\n", - "\n", "pi = 3.1415926536\n", "r = 12.35" ] @@ -1212,7 +1260,7 @@ }, { "cell_type": "code", - "execution_count": 64, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -1261,7 +1309,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Although this works (and was once put forth as a Python programming tip by Guido himself), PEP 8 actually recommends against it. The reason for this appears to be because of a special Python construct called the **docstring***. A docstring is a special comment at the beginning of a user-defined function that documents the function’s behavior. Docstrings are typically specified as triple-quoted string comments, so PEP 8 recommends that other [block comments](https://www.python.org/dev/peps/pep-0008/?#block-comments) in Python code be designated the usual way, with a hash character at the start of each line." + "Although this works (and was once put forth as a Python programming tip by Guido himself), PEP 8 actually recommends against it. The reason for this appears to be because of a special Python construct called the **docstring**. A docstring is a special comment at the beginning of a user-defined function that documents the function’s behavior. Docstrings are typically specified as triple-quoted string comments, so PEP 8 recommends that other [block comments](https://www.python.org/dev/peps/pep-0008/?#block-comments) in Python code be designated the usual way, with a hash character at the start of each line." ] }, { @@ -1282,7 +1330,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Whitespace\n", + "\n", + "## Whitespace [](#table_of_contents)\n", + "\n", "\n", "When parsing code, the Python interpreter breaks the input up into tokens. Informally, tokens are just the language elements that you have seen so far: identifiers, keywords, literals, and operators." ] @@ -1307,6 +1357,16 @@ "There are other somewhat outdated ASCII whitespace characters such as line feed and form feed, as well as some very esoteric Unicode characters that provide whitespace. But for present purposes, whitespace usually means a space, tab, or newline." ] }, + { + "cell_type": "code", + "execution_count": 68, + "metadata": {}, + "outputs": [], + "source": [ + "x = 3\n", + "x=2" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1475,6 +1535,15 @@ "Most people would likely find that the added whitespace in the second example makes it easier to read. On the other hand, you could probably find a few who would prefer the first example. To some extent, it is a matter of personal preference. But there are standards for [whitespace in expressions and statements](https://www.python.org/dev/peps/pep-0008/?#whitespace-in-expressions-and-statements) put forth in PEP 8, and you should strongly consider adhering to them as much as possible." ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = (1, )" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1715,7 +1784,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Whitespace as Indentation\n", + "\n", + "## Whitespace as Indentation [](#table_of_contents)\n", + "\n", "\n", "There is one more important situation in which whitespace is significant in Python code. Indentation—whitespace that appears to the left of the first token on a line—has very special meaning." ] @@ -1795,7 +1866,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Conclusion\n", + "\n", + "## Conclusion [](#table_of_contents)\n", + "\n", "\n", "This tutorial introduced you to Python program lexical structure. You learned what constitutes a valid Python **statement** and how to use **implicit** and **explicit line continuation** to write a statement that spans multiple lines. You also learned about commenting Python code, and about use of whitespace to enhance readability." ] @@ -1824,7 +1897,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/python/01. Basics/12 Conditional Statements in Python.ipynb b/Python/01. Basics/12 Conditional Statements in Python.ipynb similarity index 89% rename from python/01. Basics/12 Conditional Statements in Python.ipynb rename to Python/01. Basics/12 Conditional Statements in Python.ipynb index 47ada3f..d99b680 100755 --- a/python/01. Basics/12 Conditional Statements in Python.ipynb +++ b/Python/01. Basics/12 Conditional Statements in Python.ipynb @@ -4,7 +4,36 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Conditional Statements in Python" + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Conditional Statements in Python \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents\n", + "\n", + "\n", + "* [Introduction to the `if` Statement](#introduction_to_the_`if`_statement)\n", + "* [Grouping Statements: Indentation and Blocks](#grouping_statements:_indentation_and_blocks)\n", + " * [Python: It’s All About the Indentation](#python:_it’s_all_about_the_indentation)\n", + " * [What Do Other Languages Do?](#what_do_other_languages_do?)\n", + " * [Which Is Better?](#which_is_better?)\n", + "* [The `else` and `elif` Clauses](#the_`else`_and_`elif`_clauses)\n", + "* [One-Line `if` Statements](#one-line_`if`_statements)\n", + "* [Conditional Expressions (Python’s Ternary Operator)](#conditional_expressions_(python’s_ternary_operator))\n", + "* [The Python `pass` Statement](#the_python_`pass`_statement)\n", + "* [ Conclusion](#conclusion)\n", + "\n", + "---" ] }, { @@ -59,7 +88,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Introduction to the `if` Statement" + "\n", + "## Introduction to the `if` Statement [](#table_of_contents)\n", + "\n" ] }, { @@ -237,7 +268,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -249,7 +280,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Grouping Statements: Indentation and Blocks" + "\n", + "## Grouping Statements: Indentation and Blocks [](#table_of_contents)\n", + "\n" ] }, { @@ -294,7 +327,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Python: It’s All About the Indentation" + "\n", + "### Python: It’s All About the Indentation [](#table_of_contents)\n", + "\n" ] }, { @@ -403,7 +438,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -440,7 +475,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### What Do Other Languages Do?" + "\n", + "### What Do Other Languages Do? [](#table_of_contents)\n", + "\n" ] }, { @@ -488,7 +525,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Which Is Better?" + "\n", + "### Which Is Better? [](#table_of_contents)\n", + "\n" ] }, { @@ -537,7 +576,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## The `else` and `elif` Clauses" + "\n", + "## The `else` and `elif` Clauses [](#table_of_contents)\n", + "\n" ] }, { @@ -732,7 +773,7 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 41, "metadata": {}, "outputs": [ { @@ -742,7 +783,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mvar\u001b[0m \u001b[0;31m# Not defined\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_10923/504837137.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mvar\u001b[0m \u001b[0;31m# Not defined\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'var' is not defined" ] } @@ -784,7 +825,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## One-Line `if` Statements" + "\n", + "## One-Line `if` Statements [](#table_of_contents)\n", + "\n" ] }, { @@ -883,7 +926,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 45, "metadata": {}, "outputs": [ { @@ -939,7 +982,7 @@ }, { "cell_type": "code", - "execution_count": 62, + "execution_count": 46, "metadata": {}, "outputs": [ { @@ -983,11 +1026,33 @@ "```" ] }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "False\n" + ] + } + ], + "source": [ + "if x < 5:\n", + " print('True')\n", + "else:\n", + " print('False')" + ] + }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Conditional Expressions (Python’s Ternary Operator)" + "\n", + "## Conditional Expressions (Python’s Ternary Operator) [](#table_of_contents)\n", + "\n" ] }, { @@ -1024,7 +1089,7 @@ }, { "cell_type": "code", - "execution_count": 71, + "execution_count": 78, "metadata": {}, "outputs": [ { @@ -1042,7 +1107,7 @@ }, { "cell_type": "code", - "execution_count": 72, + "execution_count": 79, "metadata": {}, "outputs": [ { @@ -1263,14 +1328,7 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 35, + "execution_count": 80, "metadata": {}, "outputs": [ { @@ -1279,7 +1337,7 @@ "'foo'" ] }, - "execution_count": 35, + "execution_count": 80, "metadata": {}, "output_type": "execute_result" } @@ -1290,7 +1348,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 81, "metadata": {}, "outputs": [ { @@ -1299,7 +1357,7 @@ "'bar'" ] }, - "execution_count": 36, + "execution_count": 81, "metadata": {}, "output_type": "execute_result" } @@ -1367,7 +1425,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## The Python `pass` Statement" + "\n", + "## The Python `pass` Statement [](#table_of_contents)\n", + "\n" ] }, { @@ -1377,6 +1437,32 @@ "Occasionally, you may find that you want to write what is called a code stub: a placeholder for where you will eventually put a block of code that you haven’t implemented yet." ] }, + { + "cell_type": "code", + "execution_count": 91, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n" + ] + } + ], + "source": [ + "name = 'Ali'\n", + "\n", + "if name == 'Ali':\n", + " # TODO: add name to database\n", + " pass\n", + "else:\n", + " # TODO: warn user about registeration\n", + " pass\n", + "\n", + "print('here')" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1456,7 +1542,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Conclusion" + "\n", + "## Conclusion [](#table_of_contents)\n", + "\n" ] }, { @@ -1501,7 +1589,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git "a/python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" "b/Python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" similarity index 87% rename from "python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" rename to "Python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" index 8c1a068..26f97ce 100755 --- "a/python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" +++ "b/Python/01. Basics/13 Python \"while\" Loops (Indefinite Iteration).ipynb" @@ -4,7 +4,33 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Python \"while\" Loops (Indefinite Iteration)" + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Python \"while\" Loops (Indefinite Iteration) \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents \n", + "\n", + "\n", + "* [The `while` Loop](#the_`while`_loop)\n", + "* [The Python `break` and `continue` Statements](#the_python_`break`_and_`continue`_statements)\n", + "* [The `else` Clause](#the_`else`_clause)\n", + "* [Infinite Loops](#infinite_loops)\n", + "* [Nested `while` Loops](#nested_`while`_loops)\n", + "* [One-Line `while` Loops](#one-line_`while`_loops)\n", + "* [ Conclusion](#conclusion)\n", + "\n", + "---" ] }, { @@ -47,7 +73,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## The `while` Loop" + "\n", + "## The `while` Loop [](#table_of_contents)\n" ] }, { @@ -69,13 +96,6 @@ "```" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "`` represents the block to be repeatedly executed, often referred to as the body of the loop. This is denoted with indentation, just as in an if statement." - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -106,7 +126,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -202,11 +222,58 @@ "When a list is evaluated in Boolean context, it is truthy if it has elements in it and falsy if it is empty. In this example, a is true as long as it has elements in it. Once all the items have been removed with the `.pop()` method and the list is empty, `a` is false, and the loop terminates." ] }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "here\n" + ] + } + ], + "source": [ + "x = 5\n", + "if x < 5:\n", + " print('here')" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "x = 5\n", + "while x < 5:\n", + " print('here')" + ] + }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## The Python `break` and `continue` Statements" + "\n", + "## The Python `break` and `continue` Statements [](#table_of_contents)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "x = 5\n", + "\n", + "if x == 5:\n", + " print('x is 5')\n", + "elif x > 6:\n", + " print('x is greater than 6')\n", + "else:\n", + " print('else')" ] }, { @@ -313,7 +380,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## The `else` Clause" + "\n", + "## The `else` Clause [](#table_of_contents)\n" ] }, { @@ -472,6 +540,46 @@ "When might an `else` clause on a while loop be useful? One common situation is if you are searching a list for a specific item. You can use `break` to exit the loop if the item is found, and the `else` clause can contain code that is meant to be executed if the item isn’t found:" ] }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "5\n", + "4\n", + "3\n" + ] + } + ], + "source": [ + "n = 5\n", + "while n > 0:\n", + " print(n)\n", + " \n", + " if n % 3 == 0:\n", + " break\n", + " n -= 1\n", + "else:\n", + " print('found')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "while n > 0:\n", + " print(n)\n", + " n -= 1\n", + "\n", + "print('loop finished')" + ] + }, { "cell_type": "code", "execution_count": 26, @@ -542,7 +650,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Infinite Loops" + "\n", + "## Infinite Loops [](#table_of_contents)\n" ] }, { @@ -640,7 +749,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Nested `while` Loops" + "\n", + "## Nested `while` Loops [](#table_of_contents)\n" ] }, { @@ -790,7 +900,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## One-Line `while` Loops" + "\n", + "## One-Line `while` Loops [](#table_of_contents)\n" ] }, { @@ -882,7 +993,8 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Conclusion" + "\n", + "## Conclusion [](#table_of_contents)\n" ] }, { @@ -928,7 +1040,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git "a/python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" "b/Python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" similarity index 88% rename from "python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" rename to "Python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" index 2f0d0b5..5c8764d 100755 --- "a/python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" +++ "b/Python/01. Basics/14 Python \"for\" Loops (Definite Iteration).ipynb" @@ -4,7 +4,40 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Python \"for\" Loops (Definite Iteration)" + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Python \"for\" Loops (Definite Iteration) \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents \n", + "\n", + "\n", + "* [A Survey of Definite Iteration in Programming](#a_survey_of_definite_iteration_in_programming)\n", + " * [Numeric Range Loop](#numeric_range_loop)\n", + " * [Three-Expression Loop](#three-expression_loop)\n", + " * [Collection-Based or Iterator-Based Loop](#collection-based_or_iterator-based_loop)\n", + " * [The Python for Loop](#the_python_for_loop)\n", + " * [Iterables](#iterables)\n", + " * [Iterators](#iterators)\n", + "* [The Guts of the Python for Loop](#the_guts_of_the_python_for_loop)\n", + "* [Iterating Through a Dictionary](#iterating_through_a_dictionary)\n", + "* [The `range()` Function](#the_`range()`_function)\n", + "* [Altering `for` Loop Behavior](#altering_`for`_loop_behavior)\n", + " * [The break and continue Statements](#the_break_and_continue_statements)\n", + " * [The `else` Clause](#the_`else`_clause)\n", + "* [ Conclusion](#conclusion)\n", + "\n", + "---" ] }, { @@ -57,7 +90,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## A Survey of Definite Iteration in Programming" + "\n", + "## A Survey of Definite Iteration in Programming [](#table_of_contents)\n", + "\n" ] }, { @@ -73,8 +108,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "### Numeric Range Loop" + "\n", + "### Numeric Range Loop [](#table_of_contents)\n", + "\n" ] }, { @@ -100,7 +136,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Three-Expression Loop" + "\n", + "### Three-Expression Loop [](#table_of_contents)\n", + "\n" ] }, { @@ -149,7 +187,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Collection-Based or Iterator-Based Loop" + "\n", + "### Collection-Based or Iterator-Based Loop [](#table_of_contents)\n", + "\n" ] }, { @@ -182,7 +222,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### The Python for Loop" + "\n", + "### The Python for Loop [](#table_of_contents)\n", + "\n" ] }, { @@ -263,7 +305,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Iterables\n", + "\n", + "### Iterables [](#table_of_contents)\n", + "\n", + "\n", "In Python, **iterable** means an object can be used in iteration. The term is used as:\n", "\n", "- **An adjective:** An object may be described as iterable.\n", @@ -393,7 +438,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 49, "metadata": {}, "outputs": [ { @@ -403,7 +448,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0miter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m42\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Integer\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m/var/folders/b4/tsp68dlx1gz9xlnpgbx21ytc0000gn/T/ipykernel_76590/2887938158.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0miter\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m42\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# Integer\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: 'int' object is not iterable" ] } @@ -479,7 +524,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Iterators" + "\n", + "### Iterators [](#table_of_contents)\n", + "\n" ] }, { @@ -804,7 +851,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 51, "metadata": {}, "outputs": [], "source": [ @@ -813,7 +860,7 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 52, "metadata": {}, "outputs": [ { @@ -822,7 +869,7 @@ "('foo', 'bar', 'baz')" ] }, - "execution_count": 31, + "execution_count": 52, "metadata": {}, "output_type": "execute_result" } @@ -834,7 +881,7 @@ }, { "cell_type": "code", - "execution_count": 114, + "execution_count": 53, "metadata": {}, "outputs": [ { @@ -843,7 +890,7 @@ "{'bar', 'baz', 'foo'}" ] }, - "execution_count": 114, + "execution_count": 53, "metadata": {}, "output_type": "execute_result" } @@ -878,7 +925,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## The Guts of the Python for Loop" + "\n", + "## The Guts of the Python for Loop [](#table_of_contents)\n", + "\n" ] }, { @@ -904,7 +953,7 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 64, "metadata": {}, "outputs": [ { @@ -973,7 +1022,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Iterating Through a Dictionary" + "\n", + "## Iterating Through a Dictionary [](#table_of_contents)\n", + "\n" ] }, { @@ -985,7 +1036,20 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "d = {\n", + " 'one': 1,\n", + " 'two': 2,\n", + " 'three': 3,\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": 125, "metadata": {}, "outputs": [ { @@ -1020,7 +1084,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 126, "metadata": {}, "outputs": [ { @@ -1047,7 +1111,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 127, "metadata": {}, "outputs": [ { @@ -1149,7 +1213,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## The `range()` Function" + "\n", + "## The `range()` Function [](#table_of_contents)\n", + "\n" ] }, { @@ -1485,7 +1551,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Altering `for` Loop Behavior" + "\n", + "## Altering `for` Loop Behavior [](#table_of_contents)\n", + "\n" ] }, { @@ -1499,7 +1567,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### The break and continue Statements" + "\n", + "### The break and continue Statements [](#table_of_contents)\n", + "\n" ] }, { @@ -1561,7 +1631,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### The `else` Clause" + "\n", + "### The `else` Clause [](#table_of_contents)\n", + "\n" ] }, { @@ -1628,7 +1700,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Conclusion\n", + "\n", + "## Conclusion [](#table_of_contents)\n", + "\n", + "\n", "This section presented the `for` loop, the workhorse of **definite iteration** in Python." ] }, @@ -1663,7 +1738,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/Python/01. Basics/15 List Comprehension.ipynb b/Python/01. Basics/15 List Comprehension.ipynb new file mode 100644 index 0000000..a0fb7ae --- /dev/null +++ b/Python/01. Basics/15 List Comprehension.ipynb @@ -0,0 +1,925 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# When to Use a List Comprehension in Python \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents\n", + "\n", + "\n", + "* [How to Create Lists in Python](#how_to_create_lists_in_python)\n", + " * [Using for Loops](#using_for_loops)\n", + " * [Using `map()` Objects](#using_`map()`_objects)\n", + " * [Using List Comprehensions](#using_list_comprehensions)\n", + "* [Benefits of Using List Comprehensions](#benefits_of_using_list_comprehensions)\n", + "* [How to Supercharge Your Comprehensions](#how_to_supercharge_your_comprehensions)\n", + " * [Using Conditional Logic](#using_conditional_logic)\n", + " * [Using Set and Dictionary Comprehensions](#using_set_and_dictionary_comprehensions)\n", + "* [When Not to Use a List Comprehension in Python](#when_not_to_use_a_list_comprehension_in_python)\n", + " * [Watch Out for Nested Comprehensions](#watch_out_for_nested_comprehensions)\n", + "* [ Conclusion](#conclusion)\n", + "\n", + "---" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Python is famous for allowing you to write code that’s elegant, easy to write, and almost as easy to read as plain English. One of the language’s most distinctive features is the list comprehension, which you can use to create powerful functionality within a single line of code. However, many developers struggle to fully leverage the more advanced features of a list comprehension in Python. Some programmers even use them too much, which can lead to code that’s less efficient and harder to read." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## How to Create Lists in Python [](#table_of_contents)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There are a few different ways you can create lists in Python. To better understand the trade-offs of using a list comprehension in Python, let’s first see how to create lists with these approaches." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Using for Loops [](#table_of_contents)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The most common type of loop is the for loop. You can use a for loop to create a list of elements in three steps:\n", + "\n", + "- Instantiate an empty list.\n", + "- Loop over an iterable or range of elements.\n", + "- Append each element to the end of the list." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you want to create a list containing the first ten perfect squares, then you can complete these steps in three lines of code:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "squares = []\n", + "for i in range(10):\n", + " squares.append(i * i)\n", + "squares" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, you instantiate an empty list, squares. Then, you use a for loop to iterate over `range(10)`. Finally, you multiply each number by itself and append the result to the end of the list." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Using `map()` Objects [](#table_of_contents)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "`map()` provides an alternative approach that’s based in functional programming. You pass in a function and an iterable, and `map()` will create an object. This object contains the output you would get from running each iterable element through the supplied function." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As an example, consider a situation in which you need to calculate the price after tax for a list of transactions:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "txns = [1.09, 23.56, 57.84, 4.56, 6.78]\n", + "TAX_RATE = .08" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def get_price_with_tax(txn):\n", + " return txn * (1 + TAX_RATE)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1.1772000000000002, 25.4448, 62.467200000000005, 4.9248, 7.322400000000001]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "final_prices = map(get_price_with_tax, txns)\n", + "list(final_prices)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, you have an iterable txns and a function `get_price_with_tax()`. You pass both of these arguments to `map()`, and store the resulting object in final_prices. You can easily convert this map object into a list using `list()`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Using List Comprehensions [](#table_of_contents)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "List comprehensions are a third way of making lists. With this elegant approach, you could rewrite the for loop from the first example in just a single line of code:" + ] + }, + { + "cell_type": "code", + "execution_count": 87, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" + ] + }, + "execution_count": 87, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "squares = [i * i for i in range(10)]\n", + "squares" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Rather than creating an empty list and adding each element to the end, you simply define the list and its contents at the same time by following this format:\n", + "\n", + "```python\n", + "new_list = [expression for member in iterable]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Every list comprehension in Python includes three elements:\n", + "\n", + "- **expression** is the member itself, a call to a method, or any other valid expression that returns a value. In the example above, the expression `i * i` is the square of the member value.\n", + "- **member** is the object or value in the list or iterable. In the example above, the member value is `i`.\n", + "- **iterable** is a list, set, sequence, generator, or any other object that can return its elements one at a time. In the example above, the iterable is `range(10)`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Because the expression requirement is so flexible, a list comprehension in Python works well in many places where you would use `map()`. You can rewrite the pricing example with its own list comprehension:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "txns = [1.09, 23.56, 57.84, 4.56, 6.78]\n", + "TAX_RATE = .08" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "def get_price_with_tax(txn):\n", + " return txn * (1 + TAX_RATE)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1.1772000000000002, 25.4448, 62.467200000000005, 4.9248, 7.322400000000001]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "final_prices = [get_price_with_tax(i) for i in txns]\n", + "final_prices" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The only distinction between this implementation and `map()` is that the list comprehension in Python returns a list, not a map object." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Benefits of Using List Comprehensions [](#table_of_contents)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "List comprehensions are often described as being more Pythonic than loops or `map()`. But rather than blindly accepting that assessment, it’s worth it to understand the benefits of using a list comprehension in Python when compared to the alternatives. Later on, you’ll learn about a few scenarios where the alternatives are a better choice." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One main benefit of using a list comprehension in Python is that it’s a single tool that you can use in many different situations. In addition to standard list creation, list comprehensions can also be used for mapping and filtering. You don’t have to use a different approach for each scenario." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This is the main reason why list comprehensions are considered **Pythonic**, as Python embraces simple, powerful tools that you can use in a wide variety of situations. As an added side benefit, whenever you use a list comprehension in Python, you won’t need to remember the proper order of arguments like you would when you call `map()`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "List comprehensions are also more **declarative** than loops, which means they’re easier to read and understand. Loops require you to focus on how the list is created. You have to manually create an empty list, loop over the elements, and add each of them to the end of the list. With a list comprehension in Python, you can instead focus on what you want to go in the list and trust that Python will take care of how the list construction takes place." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## How to Supercharge Your Comprehensions [](#table_of_contents)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In order to understand the full value that list comprehensions can provide, it’s helpful to understand their range of possible functionality. You’ll also want to understand the changes that are coming to the list comprehension in Python 3.8." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Using Conditional Logic [](#table_of_contents)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Earlier, you saw this formula for how to create list comprehensions:\n", + "\n", + "```python\n", + "new_list = [expression for member in iterable]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "While this formula is accurate, it’s also a bit incomplete. A more complete description of the comprehension formula adds support for optional **conditionals**. The most common way to add conditional logic to a list comprehension is to add a conditional to the end of the expression:\n", + "\n", + "```python\n", + "new_list = [expression for member in iterable (if conditional)]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, your conditional statement comes just before the closing bracket." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Conditionals are important because they allow list comprehensions to filter out unwanted values, which would normally require a call to `filter()`:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['e', 'o', 'e', 'a', 'e', 'a', 'o', 'a']" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sentence = 'the rocket came back from mars'\n", + "vowels = [i for i in sentence if i in 'aeiou']\n", + "vowels" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this code block, the conditional statement filters out any characters in sentence that aren’t a vowel." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The conditional can test any valid expression. If you need a more complex filter, then you can even move the conditional logic to a separate function:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "sentence = 'The rocket, who was named Ted, came back \\\n", + "from Mars because he missed his friends.'" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "def is_consonant(letter):\n", + " vowels = 'aeiou'\n", + " return letter.isalpha() and letter.lower() not in vowels" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "consonants = [i for i in sentence if is_consonant(i)]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, you create a complex filter `is_consonant()` and pass this function as the conditional statement for your list comprehension. Note that the member value `i` is also passed as an argument to your function." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You can place the conditional at the end of the statement for simple filtering, but what if you want to change a member value instead of filtering it out? In this case, it’s useful to place the conditional near the beginning of the expression:\n", + "\n", + "```python\n", + "new_list = [expression (if conditional) for member in iterable]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "With this formula, you can use conditional logic to select from multiple possible output options. For example, if you have a list of prices, then you may want to replace negative prices with 0 and leave the positive values unchanged:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1.25, 0, 10.22, 3.78, 0, 1.16]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "original_prices = [1.25, -9.45, 10.22, 3.78, -5.92, 1.16]\n", + "prices = [i if i > 0 else 0 for i in original_prices]\n", + "prices" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here, your expression `i` contains a conditional statement, if `i > 0` else `0`. This tells Python to output the value of `i` if the number is positive, but to change `i` to `0` if the number is negative. If this seems overwhelming, then it may be helpful to view the conditional logic as its own function:" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[1.25, 0, 10.22, 3.78, 0, 1.16]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def get_price(price):\n", + " return price if price > 0 else 0\n", + "prices = [get_price(i) for i in original_prices]\n", + "prices" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, your conditional statement is contained within `get_price()`, and you can use it as part of your list comprehension expression." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Using Set and Dictionary Comprehensions [](#table_of_contents)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "While the list comprehension in Python is a common tool, you can also create set and dictionary comprehensions. A **set** comprehension is almost exactly the same as a list comprehension in Python. The difference is that set comprehensions make sure the output contains no duplicates. You can create a set comprehension by using curly braces instead of brackets:" + ] + }, + { + "cell_type": "code", + "execution_count": 110, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'a', 'e', 'i', 'u'}" + ] + }, + "execution_count": 110, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "quote = \"life, uh, finds a way\"\n", + "unique_vowels = {i for i in quote if i in 'aeiou'}\n", + "unique_vowels" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Your set comprehension outputs all the unique vowels it found in `quote`. Unlike lists, sets don’t guarantee that items will be saved in any particular order. This is why the first member of the set is `a`, even though the first vowel in quote is `i`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Dictionary comprehensions** are similar, with the additional requirement of defining a key:" + ] + }, + { + "cell_type": "code", + "execution_count": 111, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}" + ] + }, + "execution_count": 111, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "squares = {i: i * i for i in range(10)}\n", + "squares" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To create the squares dictionary, you use curly braces (`{}`) as well as a key-value pair (`i: i * i`) in your expression." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## When Not to Use a List Comprehension in Python [](#table_of_contents)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "List comprehensions are useful and can help you write elegant code that’s easy to read and debug, but they’re not the right choice for all circumstances. They might make your code run more slowly or use more memory. If your code is less performant or harder to understand, then it’s probably better to choose an alternative." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "### Watch Out for Nested Comprehensions [](#table_of_contents)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Comprehensions can be **nested** to create combinations of lists, dictionaries, and sets within a collection. For example, say a climate laboratory is tracking the high temperature in five different cities for the first week of June. The perfect data structure for storing this data could be a Python list comprehension nested within a dictionary comprehension:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'Austin': [0, 0, 0, 0, 0, 0, 0],\n", + " 'Tacoma': [0, 0, 0, 0, 0, 0, 0],\n", + " 'Topeka': [0, 0, 0, 0, 0, 0, 0],\n", + " 'Sacramento': [0, 0, 0, 0, 0, 0, 0],\n", + " 'Charlotte': [0, 0, 0, 0, 0, 0, 0]}" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cities = ['Austin', 'Tacoma', 'Topeka', 'Sacramento', 'Charlotte']\n", + "temps = {city: [0 for _ in range(7)] for city in cities}\n", + "temps" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "You create the outer collection temps with a dictionary comprehension. The expression is a key-value pair, which contains yet another comprehension. This code will quickly generate a list of data for each city in `cities`." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Nested lists are a common way to create **matrices**, which are often used for mathematical purposes. Take a look at the code block below:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[0, 1, 2, 3, 4],\n", + " [0, 1, 2, 3, 4],\n", + " [0, 1, 2, 3, 4],\n", + " [0, 1, 2, 3, 4],\n", + " [0, 1, 2, 3, 4],\n", + " [0, 1, 2, 3, 4]]" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "matrix = [[i for i in range(5)] for _ in range(6)]\n", + "matrix" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The outer list comprehension `[... for _ in range(6)]` creates six rows, while the inner list comprehension `[i for i in range(5)]` fills each of these rows with values." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So far, the purpose of each nested comprehension is pretty intuitive. However, there are other situations, such as **flattening** nested lists, where the logic arguably makes your code more confusing. Take this example, which uses a nested list comprehension to flatten a matrix:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4,\n", + " 0,\n", + " 1,\n", + " 2,\n", + " 3,\n", + " 4]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "flat = [num for row in matrix for num in row]\n", + "flat" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The code to flatten the matrix is concise, but it may not be so intuitive to understand how it works. On the other hand, if you were to use `for` loops to flatten the same matrix, then your code will be much more straightforward:" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "matrix = [\n", + " [0, 0, 0],\n", + " [1, 1, 1],\n", + " [2, 2, 2],\n", + "]" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [], + "source": [ + "flat = []\n", + "for row in matrix:\n", + " for num in row:\n", + " flat.append(num)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[0, 0, 0, 1, 1, 1, 2, 2, 2]" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "flat" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now you can see that the code traverses one row of the matrix at a time, pulling out all the elements in that row before moving on to the next one." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "While the single-line nested list comprehension might seem more Pythonic, what’s most important is to write code that your team can easily understand and modify. When you choose your approach, you’ll have to make a judgment call based on whether you think the comprehension helps or hurts readability." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Conclusion [](#table_of_contents)\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In this tutorial, you learned how to use a list comprehension in Python to accomplish complex tasks without making your code overly complicated." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now you can:\n", + "\n", + "- Simplify loops and `map()` calls with declarative **list comprehensions**\n", + "- Supercharge your comprehensions with **conditional logic**\n", + "- Create **set** and **dictionary** comprehensions\n", + "- Determine when code clarity or performance dictates an **alternative approach**" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Whenever you have to choose a list creation method, try multiple implementations and consider what’s easiest to read and understand in your specific scenario. If performance is important, then you can use profiling tools to give you actionable data instead of relying on hunches or guesses about what works the best." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Remember that while Python list comprehensions get a lot of attention, your intuition and ability to use data when it counts will help you write clean code that serves the task at hand. This, ultimately, is the key to making your code Pythonic!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/python/01. Basics/15 Basic Input, Output, and String Formatting in Python.ipynb b/Python/01. Basics/16 Basic Input, Output, and String Formatting in Python.ipynb similarity index 84% rename from python/01. Basics/15 Basic Input, Output, and String Formatting in Python.ipynb rename to Python/01. Basics/16 Basic Input, Output, and String Formatting in Python.ipynb index d7a00ef..b82e069 100755 --- a/python/01. Basics/15 Basic Input, Output, and String Formatting in Python.ipynb +++ b/Python/01. Basics/16 Basic Input, Output, and String Formatting in Python.ipynb @@ -4,7 +4,34 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Basic Input, Output, and String Formatting in Python" + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Basic Input, Output, and String Formatting in Python \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents \n", + "\n", + "\n", + "* [Reading Input From the Keyboard](#reading_input_from_the_keyboard)\n", + "* [Writing Output to the Console](#writing_output_to_the_console)\n", + " * [Unformatted Console Output](#unformatted_console_output)\n", + " * [Keyword Arguments to `print()`](#keyword_arguments_to_`print()`)\n", + " * [The `sep=` Keyword Argument](#the_`sep=`_keyword_argument)\n", + " * [The `end=` Keyword Argument](#the_`end=`_keyword_argument)\n", + " * [Output Stream Keyword Arguments](#output_stream_keyword_arguments)\n", + "* [Formatted String Output](#formatted_string_output)\n", + "\n", + "---" ] }, { @@ -36,7 +63,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Reading Input From the Keyboard" + "\n", + "## Reading Input From the Keyboard [](#table_of_contents)\n", + "\n" ] }, { @@ -143,7 +172,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 60, "metadata": {}, "outputs": [ { @@ -160,7 +189,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 61, "metadata": {}, "outputs": [ { @@ -170,7 +199,7 @@ "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;31mTypeError\u001b[0m: can only concatenate str (not \"int\") to str" ] } @@ -239,7 +268,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Writing Output to the Console" + "\n", + "## Writing Output to the Console [](#table_of_contents)\n", + "\n" ] }, { @@ -253,7 +284,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Unformatted Console Output\n", + "\n", + "### Unformatted Console Output [](#table_of_contents)\n", + "\n", + "\n", "To display objects to the console, pass them as a comma-separated list of arguments to `print()`." ] }, @@ -411,7 +445,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Keyword Arguments to `print()`\n", + "\n", + "### Keyword Arguments to `print()` [](#table_of_contents)\n", + "\n", + "\n", "\n", "`print()` takes a few additional arguments that provide modest control over the format of the output. Each of these is a special type of argument called a **keyword argument**. This introductory series will include a section on functions and parameter passing so you can learn more about keyword arguments." ] @@ -454,7 +491,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### The `sep=` Keyword Argument" + "\n", + "#### The `sep=` Keyword Argument [](#table_of_contents)\n", + "\n" ] }, { @@ -571,7 +610,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "#### The `end=` Keyword Argument\n", + "\n", + "#### The `end=` Keyword Argument [](#table_of_contents)\n", + "\n", + "\n", "The keyword argument `end=` causes output to be terminated by `` instead of the default newline:" ] }, @@ -661,7 +703,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Output Stream Keyword Arguments\n", + "\n", + "### Output Stream Keyword Arguments [](#table_of_contents)\n", + "\n", + "\n", "`print()` accepts two additional keyword arguments, both of which affect handling of the output stream:\n", "\n", "- `file=`: By default, `print()` sends its output to a default stream called `sys.stdout`, which is usually equivalent to the console. The `file=` argument causes output to be sent to an alternate stream designated by `` instead.\n", @@ -680,7 +725,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Formatted String Output" + "\n", + "## Formatted String Output [](#table_of_contents)\n", + "\n" ] }, { @@ -721,7 +768,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.10" + "version": "3.7.6" } }, "nbformat": 4, diff --git a/python/01. Basics/16 Newer Python String Format Techniques.ipynb b/Python/01. Basics/17 Newer Python String Format Techniques.ipynb similarity index 90% rename from python/01. Basics/16 Newer Python String Format Techniques.ipynb rename to Python/01. Basics/17 Newer Python String Format Techniques.ipynb index 2b437d4..31d0cd0 100755 --- a/python/01. Basics/16 Newer Python String Format Techniques.ipynb +++ b/Python/01. Basics/17 Newer Python String Format Techniques.ipynb @@ -2,15 +2,56 @@ "cells": [ { "cell_type": "markdown", - "id": "6fc28563", "metadata": {}, "source": [ - "# Newer Python String Format Techniques" + "" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Newer Python String Format Techniques \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "## Table of Contents\n", + "\n", + "\n", + "* [The Python String `.format()` Method](#the_python_string_`.format()`_method)\n", + "* [The String `.format()` Method: Arguments](#the_string_`.format()`_method:_arguments)\n", + " * [Positional Arguments](#positional_arguments)\n", + " * [Keyword Arguments](#keyword_arguments)\n", + "* [The String `.format()` Method: Simple Replacement Fields](#the_string_`.format()`_method:_simple_replacement_fields)\n", + " * [The `` Component](#the_``_component)\n", + " * [The `` Component](#the_``_component)\n", + " * [The `` Component](#the_``_component)\n", + " * [The `` Subcomponent](#the_``_subcomponent)\n", + " * [The `` and `` Subcomponents](#the_``_and_``_subcomponents)\n", + " * [The `` Subcomponent](#the_``_subcomponent)\n", + " * [The `#`` Subcomponent](#the_`#``_subcomponent)\n", + " * [The `0 `Subcomponent](#the_`0_`subcomponent)\n", + " * [The `` Subcomponent](#the_``_subcomponent)\n", + " * [The `` Subcomponent](#the_``_subcomponent)\n", + " * [The `.` Subcomponent](#the_`.`_subcomponent)\n", + "* [The Python Formatted String Literal (f-String)](#the_python_formatted_string_literal_(f-string))\n", + " * [Why `str.format()` Isn’t Great](#why_`str.format()`_isn’t_great)\n", + " * [f-String Syntax](#f-string_syntax)\n", + " * [f-String Expression Limitations](#f-string_expression_limitations)\n", + " * [f-String Formatting](#f-string_formatting)\n", + "* [Python f-string benchmarks](#python_f-string_benchmarks)\n", + "* [ Conclusion](#conclusion)\n", + "* [Further Reading](#further_reading)\n", + "\n", + "---" ] }, { "cell_type": "markdown", - "id": "aed78bcd", "metadata": {}, "source": [ "The **string modulo operator** is useful, and it’s good for you to be familiar with it because you’re likely to encounter it in older Python code. However, there are two newer ways that you can use Python to format strings that are arguably more preferable." @@ -18,7 +59,6 @@ }, { "cell_type": "markdown", - "id": "fa853e41", "metadata": {}, "source": [ "In this section, you’ll learn about:\n", @@ -29,7 +69,6 @@ }, { "cell_type": "markdown", - "id": "0ad988e6", "metadata": {}, "source": [ "You’ll learn about these formatting techniques in detail and add them to your Python string formatting toolkit. Note that there’s a standard module called string containing a class called `Template`, which provides some `string` formatting through interpolation. The string modulo operator provides more or less the same functionality, so you won’t cover `string.Template` here." @@ -37,10 +76,12 @@ }, { "cell_type": "markdown", - "id": "08ad6a1c", "metadata": {}, "source": [ - "## The Python String `.format()` Method\n", + "\n", + "## The Python String `.format()` Method [](#table_of_contents)\n", + "\n", + "\n", "The Python string `.format()` method was introduced in version 2.6. It’s similar in many ways to the string modulo operator, but `.format()` goes well beyond in versatility. The general form of a Python `.format()` call is shown below:\n", "\n", "```python\n", @@ -50,7 +91,6 @@ }, { "cell_type": "markdown", - "id": "7fc376ad", "metadata": {}, "source": [ "Note that this is a method, not an operator (You will learn methods in details in OOP, for now just know that you call methods on objects). You call the method on `