diff --git a/f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions.ipynb b/f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions.ipynb index ebc051762c547285b77a83568760649b903408e6..ab9fe95ae111d233bf68aa06eef35b4c6ca32daa 100644 --- a/f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions.ipynb +++ b/f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions.ipynb @@ -44,7 +44,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -109,12 +109,7 @@ "## Learning Objectives\n", "\n", " - Create list and dictionary comprehensions\n", - " - Use the correct vocabulary to describe iteration\n", - " - iterable, sequence, iterator\n", - " - Determine if an object is an iterable, or if it is an iterator\n", - " - try to use iter() to determine if an object is an iterable\n", - " - try to use next() to determine if an object is an iterator\n", - " - Use iterator/iterable language to open and process files" + " - Use the alterate syntax to handle if/else conditions in comprehensions" ] }, { @@ -150,7 +145,9 @@ "\n", "```\n", "newlist = [expression for item in iterable if condition]\n", - "```" + "```\n", + "\n", + "Let's try putting different things for `expression` and `condition` to understand what they control. Let's first look at the `condition`." ] }, { @@ -163,7 +160,15 @@ "# https://en.wikipedia.org/wiki/Code_golf\n", "# Yes! Using List Comprehensions -- Create a list of all fruits that contain 'berry'\n", "fruits = [\"blackberry\", \"apple\", \"banana\", \"fig\", \"blueberry\", \"strawberry\"]\n", - "\n" + "\n", + "[x for x in fruits if 'berry' in x]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### You Try It" ] }, { @@ -172,7 +177,14 @@ "metadata": {}, "outputs": [], "source": [ - "# All fruits that start with the letter 'b'\n" + "# Get all fruits that start with the letter 'b'\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's try different things for the `expression`." ] }, { @@ -181,7 +193,16 @@ "metadata": {}, "outputs": [], "source": [ - "# All fruits with short names\n" + "# Get the first three letters of all fruits\n", + "\n", + "[x[:3] for x in fruits]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### You Try It" ] }, { @@ -235,7 +256,9 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Even More List Comprehensions" + "### Even More List Comprehensions\n", + "\n", + "Now try working with a list of dictionaries to create a new list. These may require varying both the `expression` and the `condition`." ] }, { @@ -283,8 +306,13 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Dictionary Comprehensions\n", - "Same thing as a list comprehension, but with a key *and* value!" + "## Dictionary Comprehensions\n", + "\n", + "A dictionary comprehension creates a dictionary from a list using similar syntax as a list comprehension, but with a key *and* value!\n", + "\n", + "```\n", + "{key:value for item in iterable if condition}\n", + "```" ] }, { @@ -295,13 +323,41 @@ "source": [ "# Generate a dictionary of numbers and their squares! e.g. {1: 1, 2: 4, 3: 9, 4: 16, ...}\n", "nums = [1, 2, 3, 4, 5, 6, 7]\n", - "square_mapping_dict = ...\n", + "square_mapping_dict = {x:x*x for x in nums}\n", "square_mapping_dict" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### You Try It\n", + "\n", + "Create a dictionary where the key is the fruit name and the value is the fruit length." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "fruits = [\"blackberry\", \"apple\", \"banana\", \"fig\", \"blueberry\", \"strawberry\"]\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using the dictionaries `items()` method\n", + "\n", + "Recall the `.items()` method converts key,value pairs in a dictionary to a list-like structure of (key,value) tuples. You can then use this with comprehensions." + ] + }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -311,10 +367,8 @@ " \"Alice\": [16, 33, 42, 89, 90], \n", " \"Meena\": [39, 93, 9, 3, 55, 72, 19]}\n", "\n", - "# A dictionary of how many scores each player has\n", - "# A dictionary of everyone's highest score\n", - "# A dictionary of everyone's average score\n", - "# ..." + "\n", + "scores_dict.items()" ] }, { @@ -323,8 +377,7 @@ "metadata": {}, "outputs": [], "source": [ - "# Tip: We can use \"tuple unpacking\" in our for loop!\n", - "# An old fashioned for loop...\n", + "# Here is how it can be done using a traditional for loop\n", "new_scores_dict = {}\n", "for (player, scores) in scores_dict.items():\n", " new_scores_dict[player] = len(scores)\n", @@ -337,7 +390,17 @@ "metadata": {}, "outputs": [], "source": [ - "# A dictionary of how many scores each player has\n" + "# Here is how it could be done using a comprehension\n", + "new_scores_dict = {x[0]:len(x[1]) for x in scores_dict.items()}\n", + "new_scores_dict" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### You Try It\n", + "Create the dictionaries described below using comprehensions." ] }, { @@ -373,7 +436,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### The Syntax of Comprehensions" + "### The Syntax and Alternate Syntax of Comprehensions\n", + "\n", + "There is a second syntax for creating a comprehension that can handle values for the `if` and `else`\n", + "portion of a conditional." ] }, { @@ -388,6 +454,33 @@ "" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "scores = [87, 45, 67, 76, 88, 91, 71]\n", + "\n", + "['pass' if x >= 60 else 'fail' for x in scores]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### You Try It\n", + "\n", + "Create a list of boolean values using scores indicating `True` if the score is even and `False` otherwise." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "markdown", "metadata": {}, @@ -404,7 +497,7 @@ "metadata": {}, "source": [ "### Challenge: Recursion, Lambdas, and Comprehensions Together!\n", - "Sort the family tree as a list of people from youngest to oldest." + "Sort the `family_tree` to create a list of dictionaries representing people from youngest to oldest." ] }, { @@ -456,15 +549,18 @@ "\n", "def get_person_info(person):\n", " \"\"\"\n", - " person is a dictionary of key:value pairs where the keys are different attributes about the person (including mother)\n", + " person is a dictionary of key:value pairs where the keys are different attributes about\n", + " the person (including mother).\n", " return a dictionary of the same key:value pairs without the mother key\n", " \"\"\"\n", " pass # hint: try to use a dictionary comprehension\n", " \n", "def get_people(person):\n", " \"\"\"\n", - " person is a dictionary of key:value pairs where the keys are different attributes about the person (including mother)\n", - " return a list of dictionaries where each dictionary are the key:value pairs for a person without the mother key\n", + " person is a dictionary of key:value pairs where the keys are different attributes about\n", + " the person (including mother)\n", + " return a list of dictionaries where each dictionary are the key:value pairs for a person\n", + " without the mother key\n", " \"\"\"\n", " person_info = get_person_info(person)\n", " if ???: # base case\n", diff --git a/f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions_Solution_Oliphant.ipynb b/f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions_Solution.ipynb similarity index 94% rename from f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions_Solution_Oliphant.ipynb rename to f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions_Solution.ipynb index 84077cc2dd9b2d3c999d7386fef18cf9fab1d35a..2a4f1b135db213cebc6f130b0940131fcb10df38 100644 --- a/f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions_Solution_Oliphant.ipynb +++ b/f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions_Solution.ipynb @@ -1,5 +1,12 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Warmup" + ] + }, { "cell_type": "code", "execution_count": 1, @@ -17,14 +24,14 @@ } ], "source": [ - "# Warmup 1a: Sort this list by the length of each word using a normal function\n", + "# Warmup 1a: Sort this list by the length of each word using key=get_fruit_len\n", "\n", "fruits = [\"blackberry\", \"apple\", \"banana\", \"fig\", \"blueberry\", \"strawberry\"]\n", "\n", "def get_fruit_len(f):\n", " return len(f)\n", "\n", - "# Why might we use sorted rather than sort?\n", + "# TODO Sort the list of fruits\n", "sorted(fruits, key=get_fruit_len)" ] }, @@ -52,7 +59,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -64,7 +71,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -79,7 +86,7 @@ " 'Ohio State': 61369}" ] }, - "execution_count": 4, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -102,7 +109,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -114,7 +121,7 @@ " {'name': 'Sky', 'hours': 53}]" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -131,7 +138,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -143,7 +150,7 @@ " 'Dane': ['Madison', 'Sun Prairie', 'Middleton', 'Waunakee']}" ] }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -154,6 +161,7 @@ " \"Milwaukee\": [\"Milwaukee\", \"West Allis\", \"Wauwatosa\"],\n", " \"Rock\": [\"Janesville\", \"Beloit\"],\n", " \"Waukesha\": [\"Brookfield\"]}\n", + "\n", "cities_by_county_tuples = cities_by_county.items()\n", "sorted_cities_by_county_tuples = sorted(cities_by_county_tuples, key = lambda t: len(t[1]))\n", "dict(sorted_cities_by_county_tuples)" @@ -161,7 +169,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -170,7 +178,7 @@ "['blackberry', 'blueberry', 'strawberry']" ] }, - "execution_count": 7, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -190,73 +198,81 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Lecture 24: Iterators and Comprehensions\n", + "# Iterators and Comprehensions\n", "\n", - "Learning Objectives:\n", + "## Read\n", "\n", - " - Create list and dictionary comprehensions\n", + "- [Downey Ch 19.2](https://greenteapress.com/thinkpython2/html/thinkpython2020.html) and [12.3](https://greenteapress.com/thinkpython2/html/thinkpython2013.html)\n", "\n", - " - Use the correct vocabulary to describe iteration\n", - " - iterable, sequence, iterator\n", "\n", - " - Determine if an object is an iterable, or if it is an iterator\n", - " - try to use iter() to determine if an object is an iterable\n", - " - try to use next() to determine if an object is an iterator\n", + "## Learning Objectives\n", "\n", - " - Use iterator/iterable language to open and process files" + " - Create list and dictionary comprehensions\n", + " - Use the alterate syntax to handle if/else conditions in comprehensions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## List Comprehensions" + "## List Comprehensions\n", + "\n", + "List comprehension offers a shorter syntax when you want to create a new list based on the values of an existing list.\n", + "\n", + "```python\n", + "fruits = [\"apple\", \"banana\", \"cherry\", \"kiwi\", \"mango\"]\n", + "newlist = []\n", + "\n", + "for x in fruits:\n", + " if \"a\" in x:\n", + " newlist.append(x)\n", + "\n", + "print(newlist)\n", + "```\n", + "\n", + "Using **list comprehensions** you can do all of this work in one line of code.\n", + "\n", + "```python\n", + "fruits = [\"apple\", \"banana\", \"cherry\", \"kiwi\", \"mango\"]\n", + "\n", + "newlist = [x for x in fruits if \"a\" in x]\n", + "\n", + "print(newlist)\n", + "```\n", + "\n", + "the general syntax is:\n", + "\n", + "```\n", + "newlist = [expression for item in iterable if condition]\n", + "```\n", + "\n", + "Let's try putting different things for `expression` and `condition` to understand what they control. Let's first look at the `condition`." ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "['blackberry', 'blueberry', 'strawberry']" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# Do we have a shorter way to complete Warmup 6?\n", "# https://en.wikipedia.org/wiki/Code_golf\n", - "# Yes! Using List Comprehensions\n", + "# Yes! Using List Comprehensions -- Create a list of all fruits that contain 'berry'\n", "fruits = [\"blackberry\", \"apple\", \"banana\", \"fig\", \"blueberry\", \"strawberry\"]\n", "\n", - "[f for f in fruits if 'berry' in f]" + "[x for x in fruits if 'berry' in x]" ] }, { - "cell_type": "code", - "execution_count": 9, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# What other ways could we filter our fruits list?\n", - "fruits = [\"blackberry\", \"apple\", \"banana\", \"fig\", \"blueberry\", \"strawberry\"]\n", - "\n", - "# All fruits that contain berry (we just did this!)\n", - "# All fruits that start with the letter 'b'\n", - "# All fruits with short names\n", - "# The length of every fruit name\n", - "# ..." + "#### You Try It" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -265,40 +281,55 @@ "['blackberry', 'banana', 'blueberry']" ] }, - "execution_count": 10, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# All fruits that start with the letter 'b'\n", - "[f for f in fruits if f.startswith('b')]" + "# Get all fruits that start with the letter 'b'\n", + "[x for x in fruits if x.startswith('b')]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now let's try different things for the `expression`." ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "['apple', 'fig']" + "['bla', 'app', 'ban', 'fig', 'blu', 'str']" ] }, - "execution_count": 11, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# All fruits with short names\n", - "[f for f in fruits if len(f) < 6]" + "# Get the first three letters of all fruits\n", + "\n", + "[x[:3] for x in fruits]" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### You Try It" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -307,14 +338,14 @@ "[10, 5, 6, 3, 9, 10]" ] }, - "execution_count": 12, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The length of every fruit name\n", - "[len(f) for f in fruits]" + "[len(x) for x in fruits]" ] }, { @@ -326,7 +357,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -335,7 +366,7 @@ "[0.0, 7.222222222222222, 32.22222222222222, 100.0]" ] }, - "execution_count": 13, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } @@ -354,7 +385,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -363,7 +394,7 @@ "[0.0, 7.222222222222222, 32.22222222222222, 100.0]" ] }, - "execution_count": 14, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -375,7 +406,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -384,7 +415,7 @@ "[0.0, 7.222222222222222, 32.22222222222222, 100.0]" ] }, - "execution_count": 15, + "execution_count": 12, "metadata": {}, "output_type": "execute_result" } @@ -399,12 +430,14 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Even More List Comprehensions" + "### Even More List Comprehensions\n", + "\n", + "Now try working with a list of dictionaries to create a new list. These may require varying both the `expression` and the `condition`." ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -413,16 +446,12 @@ " {\"name\": \"Patrice\", \"hours\": 72},\n", " {\"name\": \"Gabriella\", \"hours\": 45},\n", " {\"name\": \"Jade\", \"hours\": 62}\n", - " ]\n", - "\n", - "# Those that have volunteered atleast 60 hours\n", - "# Those with short names\n", - "# ..." + " ]\n" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 13, "metadata": {}, "outputs": [ { @@ -431,19 +460,19 @@ "['Patrice', 'Jade']" ] }, - "execution_count": 17, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Those that have volunteered atleast 60 hours\n", + "# names of those that have volunteered at least 60 hours\n", "[d['name'] for d in volunteers if d['hours'] > 60]" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 14, "metadata": {}, "outputs": [ { @@ -452,19 +481,19 @@ "['Sky', 'Jade']" ] }, - "execution_count": 18, + "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Those with short names\n", + "# names of those with short names\n", "[d['name'] for d in volunteers if len(d['name']) < 5]" ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -473,7 +502,7 @@ "[{'name': 'Sky', 'hours': 53}, {'name': 'Jade', 'hours': 62}]" ] }, - "execution_count": 19, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } @@ -487,38 +516,88 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### Dictionary Comprehensions\n", - "Same thing as a list comprehension, but with a key *and* value!" + "## Dictionary Comprehensions\n", + "\n", + "A dictionary comprehension creates a dictionary from a list using similar syntax as a list comprehension, but with a key *and* value!\n", + "\n", + "```\n", + "{key:value for item in iterable if condition}\n", + "```" ] }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Generate a dictionary of numbers and their squares! e.g. {1: 1, 2: 4, 3: 9, 4: 16, ...}\n", + "nums = [1, 2, 3, 4, 5, 6, 7]\n", + "square_mapping_dict = {x:x*x for x in nums}\n", + "square_mapping_dict" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### You Try It\n", + "\n", + "Create a dictionary where the key is the fruit name and the value is the fruit length." + ] + }, + { + "cell_type": "code", + "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "{1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49}" + "{'blackberry': 10,\n", + " 'apple': 5,\n", + " 'banana': 6,\n", + " 'fig': 3,\n", + " 'blueberry': 9,\n", + " 'strawberry': 10}" ] }, - "execution_count": 20, + "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Generate a dictionary of numbers and their squares! e.g. {1: 1, 2: 4, 3: 9, 4: 16, ...}\n", - "nums = [1, 2, 3, 4, 5, 6, 7]\n", - "square_mapping_dict = {num: num ** 2 for num in nums}\n", - "square_mapping_dict" + "fruits = [\"blackberry\", \"apple\", \"banana\", \"fig\", \"blueberry\", \"strawberry\"]\n", + "\n", + "{x:len(x) for x in fruits}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Using the dictionaries `items()` method\n", + "\n", + "Recall the `.items()` method converts key,value pairs in a dictionary to a list-like structure of (key,value) tuples. You can then use this with comprehensions." ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 19, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "dict_items([('Bob', [18, 72, 83]), ('Cindy', [27, 11, 55, 73, 87]), ('Alice', [16, 33, 42, 89, 90]), ('Meena', [39, 93, 9, 3, 55, 72, 19])])" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# What ways could we filter this dictionary of people's scores?\n", "scores_dict = {\"Bob\": [18, 72, 83], \n", @@ -526,15 +605,13 @@ " \"Alice\": [16, 33, 42, 89, 90], \n", " \"Meena\": [39, 93, 9, 3, 55, 72, 19]}\n", "\n", - "# A dictionary of how many scores each player has\n", - "# A dictionary of everyone's highest score\n", - "# A dictionary of everyone's average score\n", - "# ..." + "\n", + "scores_dict.items()" ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -543,14 +620,13 @@ "{'Bob': 3, 'Cindy': 5, 'Alice': 5, 'Meena': 7}" ] }, - "execution_count": 22, + "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# Tip: We can use \"tuple unpacking\" in our for loop!\n", - "# An old fashioned for loop...\n", + "# Here is how it can be done using a traditional for loop\n", "new_scores_dict = {}\n", "for (player, scores) in scores_dict.items():\n", " new_scores_dict[player] = len(scores)\n", @@ -559,7 +635,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 21, "metadata": {}, "outputs": [ { @@ -568,19 +644,28 @@ "{'Bob': 3, 'Cindy': 5, 'Alice': 5, 'Meena': 7}" ] }, - "execution_count": 23, + "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "# A dictionary of how many scores each player has.\n", - "{player : len(scores) for (player, scores) in scores_dict.items()}" + "# Here is how it could be done using a comprehension\n", + "new_scores_dict = {x[0]:len(x[1]) for x in scores_dict.items()}\n", + "new_scores_dict" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### You Try It\n", + "Create the dictionaries described below using comprehensions." ] }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 22, "metadata": {}, "outputs": [ { @@ -589,19 +674,19 @@ "{'Bob': 83, 'Cindy': 87, 'Alice': 90, 'Meena': 93}" ] }, - "execution_count": 24, + "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# A dictionary of everyone's highest score\n", - "{player : max(scores) for (player, scores) in scores_dict.items()}" + "{x[0]:max(x[1]) for x in scores_dict.items()}" ] }, { "cell_type": "code", - "execution_count": 25, + "execution_count": 24, "metadata": {}, "outputs": [ { @@ -613,19 +698,19 @@ " 'Meena': 41.42857142857143}" ] }, - "execution_count": 25, + "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# A dictionary of everyone's average score\n", - "{player : sum(scores) / len(scores) for (player, scores) in scores_dict.items()}" + "{x[0]:sum(x[1])/len(x[1]) for x in scores_dict.items()}" ] }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 25, "metadata": {}, "outputs": [ { @@ -637,13 +722,15 @@ " 'Bob': 57.666666666666664}" ] }, - "execution_count": 26, + "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Challenge: A sorted dictionary of everyone's average score.\n", + "# Hint: Convert the above dictionary to a list of tuples,\n", + "# sort based on the score, and turn back into a dict.\n", "avg_scores = {player : sum(scores) / len(scores) for (player, scores) in scores_dict.items()}\n", "# Convert the dictionary to a list of tuples, sort based on the score, and turn back into a dict.\n", "dict(sorted(avg_scores.items(), key=lambda t: t[1]))" @@ -653,7 +740,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### The Syntax of Comprehensions" + "### The Syntax and Alternate Syntax of Comprehensions\n", + "\n", + "There is a second syntax for creating a comprehension that can handle values for the `if` and `else`\n", + "portion of a conditional." ] }, { @@ -668,6 +758,57 @@ "" ] }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['pass', 'fail', 'pass', 'pass', 'pass', 'pass', 'pass']" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "scores = [87, 45, 67, 76, 88, 91, 71]\n", + "\n", + "['pass' if x >= 60 else 'fail' for x in scores]\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### You Try It\n", + "\n", + "Create a list of boolean values using scores indicating `True` if the score is even and `False` otherwise." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[False, False, False, True, True, False, False]" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "[True if x%2==0 else False for x in scores]" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -684,7 +825,7 @@ "metadata": {}, "source": [ "### Challenge: Recursion, Lambdas, and Comprehensions Together!\n", - "Sort the family tree as a list of people from youngest to oldest." + "Sort the `family_tree` to create a list of dictionaries representing people from youngest to oldest." ] }, { @@ -705,7 +846,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 28, "metadata": {}, "outputs": [ { @@ -719,7 +860,7 @@ " {'name': 'Dot', 'age': 111}]" ] }, - "execution_count": 27, + "execution_count": 28, "metadata": {}, "output_type": "execute_result" } @@ -751,13 +892,24 @@ "}\n", "\n", "def get_person_info(person):\n", + " \"\"\"\n", + " person is a dictionary of key:value pairs where the keys are different attributes about\n", + " the person (including mother).\n", + " return a dictionary of the same key:value pairs without the mother key\n", + " \"\"\"\n", " return {k: v for (k, v) in person.items() if k != 'mother'}\n", - "\n", + " \n", "def get_people(person):\n", + " \"\"\"\n", + " person is a dictionary of key:value pairs where the keys are different attributes about\n", + " the person (including mother)\n", + " return a list of dictionaries where each dictionary are the key:value pairs for a person\n", + " without the mother key\n", + " \"\"\"\n", " person_info = get_person_info(person)\n", - " if 'mother' not in person:\n", + " if 'mother' not in person: # base case\n", " return [person_info]\n", - " else:\n", + " else: # recursive case\n", " current_mother = person['mother']\n", " return get_people(current_mother) + [person_info]\n", "\n", diff --git a/f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions_Worksheet_Template.ipynb b/f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions_Worksheet.ipynb similarity index 100% rename from f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions_Worksheet_Template.ipynb rename to f24/Louis_Lecture_Notes/24_Comprehensions/Lec24_Comprehensions_Worksheet.ipynb