Skip to content

Instantly share code, notes, and snippets.

@aparrish
Last active September 16, 2023 16:16
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save aparrish/50803e0ae51a2c6e775af36ea79be285 to your computer and use it in GitHub Desktop.
Save aparrish/50803e0ae51a2c6e775af36ea79be285 to your computer and use it in GitHub Desktop.
Just enough Python!
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Enough Python\n",
"\n",
"By [Allison Parrish](http://www.decontextualize.com/)\n",
"\n",
"This notebook aims to prepare you to mess around with Python code in Jupyter Notebooks. The goal isn't necessarily to teach you how to write Python programs from scratch, but instead to give you some signposts so that you can better understand what's happening in the code you run, and to help you make changes to that code.\n",
"\n",
"## Expressions and variables\n",
"\n",
"At its core, Python works like a calculator: type an expression in, get an answer out. Here's how you write simple arithmetic expressions in Python:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"9"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"4 + 5"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Use `*` for multiplication, `/` for division, and parentheses to group expressions and change the order of operations (just like regular arithmetic):"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"7.714285714285714"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"((4 + 5) * 6) / 7"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can assign the result of an expression to a *variable*. Whenever you see an equal sign (`=`) with an expression to the right and a single word (or multiple words `joined_up_like_this`), the code in the cell is creating a variable."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"x = 4 + 5"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"(Note that Python doesn't display anything when you have a cell that just assigns a value to a variable.)\n",
"\n",
"After you've run a cell with a variable assignment, you can use the name of the variable in any expression to stand in for the variable's value, e.g.:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"27"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x * 3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Type a variable into a cell on its own and then run the cell to see the variable's contents:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"9"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can change a variable's value by assigning to it again:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"51"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = 17\n",
"x * 3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that the name of the variable doesn't matter. Usually, programmers give variables mnemonic names to help remind them what the variable is intended to do. This is nice, but sometimes beginners come to believe that the name of the variable has some magic effect. Don't fall into this trap!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Strings and lists\n",
"\n",
"The *string* is the Python data type that stores text and makes it easy to manipulate. There are a number of ways to get text into strings. The first is with a *string literal*, where you just enclose the string inside of quotes (either double or single quotes):"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"message = \"it was the best of times\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The second is by reading in the string from a file using `open(...).read()`. (For our purposes here, this should be a plain text file.) The following line will read `frost.txt` into a variable called `text`:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"text = open('frost.txt').read()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can show a text in the notebook by simply evaluating the variable name:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Two roads diverged in a yellow wood,\\nAnd sorry I could not travel both\\nAnd be one traveler, long I stood\\nAnd looked down one as far as I could\\nTo where it bent in the undergrowth;\\n\\nThen took the other, as just as fair,\\nAnd having perhaps the better claim,\\nBecause it was grassy and wanted wear;\\nThough as for that the passing there\\nHad worn them really about the same,\\n\\nAnd both that morning equally lay\\nIn leaves no step had trodden black.\\nOh, I kept the first for another day!\\nYet knowing how way leads on to way,\\nI doubted if I should ever come back.\\n\\nI shall be telling this with a sigh\\nSomewhere ages and ages hence:\\nTwo roads diverged in a wood, and I---\\nI took the one less travelled by,\\nAnd that has made all the difference.\\n'"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"text"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"But you'll notice that this text has a weird \"control character\" in it, shown as `\\n`. This symbol actually means that the file contains a new line. If you want Python to display the string with the control characters interpreted, you can use the `print()` function:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Two roads diverged in a yellow wood,\n",
"And sorry I could not travel both\n",
"And be one traveler, long I stood\n",
"And looked down one as far as I could\n",
"To where it bent in the undergrowth;\n",
"\n",
"Then took the other, as just as fair,\n",
"And having perhaps the better claim,\n",
"Because it was grassy and wanted wear;\n",
"Though as for that the passing there\n",
"Had worn them really about the same,\n",
"\n",
"And both that morning equally lay\n",
"In leaves no step had trodden black.\n",
"Oh, I kept the first for another day!\n",
"Yet knowing how way leads on to way,\n",
"I doubted if I should ever come back.\n",
"\n",
"I shall be telling this with a sigh\n",
"Somewhere ages and ages hence:\n",
"Two roads diverged in a wood, and I---\n",
"I took the one less travelled by,\n",
"And that has made all the difference.\n",
"\n"
]
}
],
"source": [
"print(text)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Strings have a number of helpful \"methods,\" which are little bits of code you can put after the variable name to return a copy of the string's text with some changes applied. For example, adding `.upper()` shows the text as all upper-case:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'IT WAS THE BEST OF TIMES'"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"message.upper()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"An especially helpful method is `.split()`, which \"splits\" a string up into units. To split a string up into words:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['Two',\n",
" 'roads',\n",
" 'diverged',\n",
" 'in',\n",
" 'a',\n",
" 'yellow',\n",
" 'wood,',\n",
" 'And',\n",
" 'sorry',\n",
" 'I',\n",
" 'could',\n",
" 'not',\n",
" 'travel',\n",
" 'both',\n",
" 'And',\n",
" 'be',\n",
" 'one',\n",
" 'traveler,',\n",
" 'long',\n",
" 'I',\n",
" 'stood',\n",
" 'And',\n",
" 'looked',\n",
" 'down',\n",
" 'one',\n",
" 'as',\n",
" 'far',\n",
" 'as',\n",
" 'I',\n",
" 'could',\n",
" 'To',\n",
" 'where',\n",
" 'it',\n",
" 'bent',\n",
" 'in',\n",
" 'the',\n",
" 'undergrowth;',\n",
" 'Then',\n",
" 'took',\n",
" 'the',\n",
" 'other,',\n",
" 'as',\n",
" 'just',\n",
" 'as',\n",
" 'fair,',\n",
" 'And',\n",
" 'having',\n",
" 'perhaps',\n",
" 'the',\n",
" 'better',\n",
" 'claim,',\n",
" 'Because',\n",
" 'it',\n",
" 'was',\n",
" 'grassy',\n",
" 'and',\n",
" 'wanted',\n",
" 'wear;',\n",
" 'Though',\n",
" 'as',\n",
" 'for',\n",
" 'that',\n",
" 'the',\n",
" 'passing',\n",
" 'there',\n",
" 'Had',\n",
" 'worn',\n",
" 'them',\n",
" 'really',\n",
" 'about',\n",
" 'the',\n",
" 'same,',\n",
" 'And',\n",
" 'both',\n",
" 'that',\n",
" 'morning',\n",
" 'equally',\n",
" 'lay',\n",
" 'In',\n",
" 'leaves',\n",
" 'no',\n",
" 'step',\n",
" 'had',\n",
" 'trodden',\n",
" 'black.',\n",
" 'Oh,',\n",
" 'I',\n",
" 'kept',\n",
" 'the',\n",
" 'first',\n",
" 'for',\n",
" 'another',\n",
" 'day!',\n",
" 'Yet',\n",
" 'knowing',\n",
" 'how',\n",
" 'way',\n",
" 'leads',\n",
" 'on',\n",
" 'to',\n",
" 'way,',\n",
" 'I',\n",
" 'doubted',\n",
" 'if',\n",
" 'I',\n",
" 'should',\n",
" 'ever',\n",
" 'come',\n",
" 'back.',\n",
" 'I',\n",
" 'shall',\n",
" 'be',\n",
" 'telling',\n",
" 'this',\n",
" 'with',\n",
" 'a',\n",
" 'sigh',\n",
" 'Somewhere',\n",
" 'ages',\n",
" 'and',\n",
" 'ages',\n",
" 'hence:',\n",
" 'Two',\n",
" 'roads',\n",
" 'diverged',\n",
" 'in',\n",
" 'a',\n",
" 'wood,',\n",
" 'and',\n",
" 'I---',\n",
" 'I',\n",
" 'took',\n",
" 'the',\n",
" 'one',\n",
" 'less',\n",
" 'travelled',\n",
" 'by,',\n",
" 'And',\n",
" 'that',\n",
" 'has',\n",
" 'made',\n",
" 'all',\n",
" 'the',\n",
" 'difference.']"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"text.split()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Or, to split a text into lines:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['Two roads diverged in a yellow wood,',\n",
" 'And sorry I could not travel both',\n",
" 'And be one traveler, long I stood',\n",
" 'And looked down one as far as I could',\n",
" 'To where it bent in the undergrowth;',\n",
" '',\n",
" 'Then took the other, as just as fair,',\n",
" 'And having perhaps the better claim,',\n",
" 'Because it was grassy and wanted wear;',\n",
" 'Though as for that the passing there',\n",
" 'Had worn them really about the same,',\n",
" '',\n",
" 'And both that morning equally lay',\n",
" 'In leaves no step had trodden black.',\n",
" 'Oh, I kept the first for another day!',\n",
" 'Yet knowing how way leads on to way,',\n",
" 'I doubted if I should ever come back.',\n",
" '',\n",
" 'I shall be telling this with a sigh',\n",
" 'Somewhere ages and ages hence:',\n",
" 'Two roads diverged in a wood, and I---',\n",
" 'I took the one less travelled by,',\n",
" 'And that has made all the difference.',\n",
" '']"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"text.split(\"\\n\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can see that `.split()` produces a value different from what we've seen before—this is a *list*. A list has multiple items in it—in this case, multiple strings. Python displays lists with an opening square bracket `[`, a closing square bracket `]`, and then the items in the list with a comma between them.\n",
"\n",
"Assign a list to a variable like so:"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"words = text.split()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Part of the reason to split text into lists is so we can analyze the parts themselves, or just a segment of those parts. For example, now that we've split the text into words, we can ask for the length of the text in words using the `len()` function:"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"144"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(words)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note that the `len()` function works on strings as well:"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"24"
]
},
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(message)"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"144"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(words)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Indexing"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can grab individual items from the list using square bracket indexing (note that indexes start at zero):"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Two'"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"words[0]"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'yellow'"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"words[5]"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'And'"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"x = 7\n",
"words[x]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using a colon between two numbers in brackets gives you a *slice* of the list (which is itself a list):"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['diverged', 'in', 'a', 'yellow', 'wood,']"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"words[2:7]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Negative indexes start from the end of the list; empty indexes assume the start end of the list, respectively:"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['Two', 'roads', 'diverged', 'in', 'a', 'yellow', 'wood,', 'And']"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"words[:8]"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['by,', 'And', 'that', 'has', 'made', 'all', 'the', 'difference.']"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"words[-8:]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can use the same indexing on strings:"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"it was the best of times\n",
"as the bes\n"
]
}
],
"source": [
"print(message)\n",
"print(message[4:14])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Making lists from scratch and modifying lists\n",
"\n",
"You can also make a new list with a *list literal*. This takes the form of a series of values separated by commas, surrounded by square brackets:"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [],
"source": [
"plums = [\"this\", \"is\", \"just\", \"to\", \"say\"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The list type's `.append()` method adds a new item to the end of the list."
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
"plums.append(\"I\")\n",
"plums.append(\"have\")\n",
"plums.append(\"eaten\")"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['this', 'is', 'just', 'to', 'say', 'I', 'have', 'eaten']"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plums"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Gluing lists back together\n",
"\n",
"To turn lists back into strings, you need to `join()` it back together. This expression glues the items back together with a space in between:"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'this is just to say I have eaten'"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"' '.join(plums)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"While this expression joins them back together with an empty string (i.e., mushes the items together):"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'thisisjusttosayIhaveeaten'"
]
},
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"''.join(plums)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Random numbers"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Python comes with a number of *libraries*—bits of pre-built code—to help with various tasks. The `import` keyword makes these libraries available in your notebook. The `random` library is one we'll use a lot:"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [],
"source": [
"import random"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `random` library has a handful of important functions. The first we'll discuss is `random.choice()`, which picks a random item from a list:"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'leads'"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"random.choice(words)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `random.sample()` function takes two parameters: a list to draw samples from, and the sample you want to draw. (Samples are guaranteed not to be duplicates.)"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['stood', 'that', 'leads', 'really', 'kept']"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"random.sample(words, 5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And `random.randrange()` returns a random integer from zero up to (but not including) the number that you specify between the parentheses:"
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"9"
]
},
"execution_count": 46,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"random.randrange(14)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To make a d20 simulator:"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"7"
]
},
"execution_count": 51,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"random.randrange(20) + 1"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Loops and comprehensions\n",
"\n",
"To do something more than once, take the code you want to run more than once and tab it over once (i.e., indent each line by four spaces—you can do this in Jupyter Notebook by selecting the code and hitting `TAB`.) Above the indented code, put `for i in range(n):` on a line, replacing `n` with the number of times you want to repeat. For example, the code in this cell prints out three randomly selected words from the Frost poem:"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"as just if\n"
]
}
],
"source": [
"selected = random.sample(words, 3)\n",
"joined = ' '.join(selected)\n",
"print(joined)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And this cell does the same thing ten times:"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"less passing same,\n",
"be day! perhaps\n",
"really And And\n",
"ages And Then\n",
"first as made\n",
"And long and\n",
"a I I\n",
"wanted lay as\n",
"step Yet claim,\n",
"I--- ages Oh,\n"
]
}
],
"source": [
"for i in range(10):\n",
" selected = random.sample(words, 3)\n",
" joined = ' '.join(selected)\n",
" print(joined)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To print squares of integers less than ten:"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 0\n",
"1 1\n",
"2 4\n",
"3 9\n",
"4 16\n",
"5 25\n",
"6 36\n",
"7 49\n",
"8 64\n",
"9 81\n"
]
}
],
"source": [
"for i in range(10):\n",
" print(i, i*i)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A common task in computer programming is to take a list and perform the same operation on each item in the list. You can do this in Python with a `for` loop. In this case, put the variable name referring to the list (or an expression evaluating to a list) after the word `in`, and use the word `item` instead of `i`. This loop prints each word in the Frost poem along with the length of the word:"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Two 3\n",
"roads 5\n",
"diverged 8\n",
"in 2\n",
"a 1\n",
"yellow 6\n",
"wood, 5\n",
"And 3\n",
"sorry 5\n",
"I 1\n",
"could 5\n",
"not 3\n",
"travel 6\n",
"both 4\n",
"And 3\n",
"be 2\n",
"one 3\n",
"traveler, 9\n",
"long 4\n",
"I 1\n",
"stood 5\n",
"And 3\n",
"looked 6\n",
"down 4\n",
"one 3\n",
"as 2\n",
"far 3\n",
"as 2\n",
"I 1\n",
"could 5\n",
"To 2\n",
"where 5\n",
"it 2\n",
"bent 4\n",
"in 2\n",
"the 3\n",
"undergrowth; 12\n",
"Then 4\n",
"took 4\n",
"the 3\n",
"other, 6\n",
"as 2\n",
"just 4\n",
"as 2\n",
"fair, 5\n",
"And 3\n",
"having 6\n",
"perhaps 7\n",
"the 3\n",
"better 6\n",
"claim, 6\n",
"Because 7\n",
"it 2\n",
"was 3\n",
"grassy 6\n",
"and 3\n",
"wanted 6\n",
"wear; 5\n",
"Though 6\n",
"as 2\n",
"for 3\n",
"that 4\n",
"the 3\n",
"passing 7\n",
"there 5\n",
"Had 3\n",
"worn 4\n",
"them 4\n",
"really 6\n",
"about 5\n",
"the 3\n",
"same, 5\n",
"And 3\n",
"both 4\n",
"that 4\n",
"morning 7\n",
"equally 7\n",
"lay 3\n",
"In 2\n",
"leaves 6\n",
"no 2\n",
"step 4\n",
"had 3\n",
"trodden 7\n",
"black. 6\n",
"Oh, 3\n",
"I 1\n",
"kept 4\n",
"the 3\n",
"first 5\n",
"for 3\n",
"another 7\n",
"day! 4\n",
"Yet 3\n",
"knowing 7\n",
"how 3\n",
"way 3\n",
"leads 5\n",
"on 2\n",
"to 2\n",
"way, 4\n",
"I 1\n",
"doubted 7\n",
"if 2\n",
"I 1\n",
"should 6\n",
"ever 4\n",
"come 4\n",
"back. 5\n",
"I 1\n",
"shall 5\n",
"be 2\n",
"telling 7\n",
"this 4\n",
"with 4\n",
"a 1\n",
"sigh 4\n",
"Somewhere 9\n",
"ages 4\n",
"and 3\n",
"ages 4\n",
"hence: 6\n",
"Two 3\n",
"roads 5\n",
"diverged 8\n",
"in 2\n",
"a 1\n",
"wood, 5\n",
"and 3\n",
"I--- 4\n",
"I 1\n",
"took 4\n",
"the 3\n",
"one 3\n",
"less 4\n",
"travelled 9\n",
"by, 3\n",
"And 3\n",
"that 4\n",
"has 3\n",
"made 4\n",
"all 3\n",
"the 3\n",
"difference. 11\n"
]
}
],
"source": [
"for item in words:\n",
" print(item, len(item))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"(Actually, in both cases, you can use any name you want, instead of `i` and `item`, as long as you use the same name in the body of the loop.)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Another common task is to make a *new* list resulting from applying some operation to each item in a list—potentially skipping items if they don't meet some criterion. For example, let's say that I wanted to make a list of words that start with `t` in the Frost poem, converting each of these words to upper case.\n",
"\n",
"There are two ways to do this. The first is with a `for` loop, a list that starts out empty, and `.append()`:"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [],
"source": [
"t_words = []\n",
"for item in words:\n",
" if item.startswith('t'):\n",
" upper_c = item.upper()\n",
" t_words.append(upper_c)"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['TRAVEL',\n",
" 'TRAVELER,',\n",
" 'THE',\n",
" 'TOOK',\n",
" 'THE',\n",
" 'THE',\n",
" 'THAT',\n",
" 'THE',\n",
" 'THERE',\n",
" 'THEM',\n",
" 'THE',\n",
" 'THAT',\n",
" 'TRODDEN',\n",
" 'THE',\n",
" 'TO',\n",
" 'TELLING',\n",
" 'THIS',\n",
" 'TOOK',\n",
" 'THE',\n",
" 'TRAVELLED',\n",
" 'THAT',\n",
" 'THE']"
]
},
"execution_count": 65,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t_words"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `if` statement in the loop serves to essentially \"skip\" items in the list if they don't meet some criterion. (The `.startswith()` method checks to see if the given string begins with the substring specified in the parentheses.)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can also write this differently, in a format known as a *list comprehension*, which takes the syntax of the `for` loop and inverts it:"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [],
"source": [
"t_words = [item.upper() for item in words if item.startswith('t')]"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['TRAVEL',\n",
" 'TRAVELER,',\n",
" 'THE',\n",
" 'TOOK',\n",
" 'THE',\n",
" 'THE',\n",
" 'THAT',\n",
" 'THE',\n",
" 'THERE',\n",
" 'THEM',\n",
" 'THE',\n",
" 'THAT',\n",
" 'TRODDEN',\n",
" 'THE',\n",
" 'TO',\n",
" 'TELLING',\n",
" 'THIS',\n",
" 'TOOK',\n",
" 'THE',\n",
" 'TRAVELLED',\n",
" 'THAT',\n",
" 'THE']"
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t_words"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The list comprehension above does exactly the same thing as the `for` loop. Both syntaxes are valid! I usually prefer list comprehensions when possible, since they are shorter and more clear. I'm showing them here so that you recognize that both syntaxes are meant to accomplish the same task (i.e., make a copy of a list, modifying and potentially throwing out items from the list.)"
]
}
],
"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.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Two roads diverged in a yellow wood,
And sorry I could not travel both
And be one traveler, long I stood
And looked down one as far as I could
To where it bent in the undergrowth;
Then took the other, as just as fair,
And having perhaps the better claim,
Because it was grassy and wanted wear;
Though as for that the passing there
Had worn them really about the same,
And both that morning equally lay
In leaves no step had trodden black.
Oh, I kept the first for another day!
Yet knowing how way leads on to way,
I doubted if I should ever come back.
I shall be telling this with a sigh
Somewhere ages and ages hence:
Two roads diverged in a wood, and I---
I took the one less travelled by,
And that has made all the difference.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment