{ "cells": [ { "cell_type": "markdown", "id": "super-sweden", "metadata": {}, "source": [ "\n", "\n", "## ![](https://s3.amazonaws.com/python-ga/images/GA_Cog_Medium_White_RGB.png) {.separator}\n", "\n", "

Python Programming: Sets and Tuples

\n", "\n", "\n", "\n", "---\n", "\n", "## Learning Objectives\n", "\n", "*After this lesson, you will be able to:*\n", "\n", "- Perform common actions with sets.\n", "- Perform common actions with tuples.\n", "- Know when to use different data structures.\n", "\n", "\n", "\n", "---\n", "\n", "## Discussion: Lists\n", "\n", "Here are some lists:\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "beautiful-discipline", "metadata": {}, "outputs": [], "source": [ "unique_colors = [\"red\", \"yellow\", \"red\", \"green\", \"red\", \"yellow\"]\n", "subscribed_emails = [\"mary@gmail.com\", \"opal@gmail.com\", \"mary@gmail.com\", \"sayed@gmail.com\"]" ] }, { "cell_type": "markdown", "id": "waiting-tokyo", "metadata": {}, "source": [ "\n", "What could be a problem here?\n", "\n", "---\n", "\n", "## Introducing Sets\n", "\n", "\n", "Lists:\n" ] }, { "cell_type": "code", "execution_count": null, "id": "standing-stand", "metadata": {}, "outputs": [], "source": [ "unique_colors_list = [\"red\", \"yellow\", \"red\", \"green\", \"red\", \"yellow\"]\n", "subscribed_emails_list = [\"mary@gmail.com\", \"opal@gmail.com\", \"mary@gmail.com\", \"sayed@gmail.com\"]" ] }, { "cell_type": "markdown", "id": "chicken-addiction", "metadata": {}, "source": [ "\n", "Sets: an unordered collection of unique elements. These are powerful because set theory operations can be applied to them in O(1) time.\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ahead-puzzle", "metadata": {}, "outputs": [], "source": [ "unique_colors_set = {\"green\", \"yellow\", \"red\"}\n", "subscribed_emails_set = {\"mary@gmail.com\", \"opal@gmail.com\", \"sayed@gmail.com\"}" ] }, { "cell_type": "markdown", "id": "copyrighted-underwear", "metadata": {}, "source": [ "\n", "- Notice the `{}` versus the `[]`.\n", "\n", "---\n", "\n", "\n", "## How Can We Make a Set?\n", "\n", "If we explicitly cast a set from a list, Python removes duplicates automatically.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "sharing-orlando", "metadata": {}, "outputs": [], "source": [ "my_set = set(a_list_to_convert)\n", "\n", "# In action:\n", "unique_colors_list = [\"red\", \"yellow\", \"red\", \"green\", \"red\", \"yellow\"]\n", "unique_colors_set = set(unique_colors_list)\n", "# => {\"green\", \"yellow\", \"red\"}\n", "\n", "# In action:\n", "unique_colors_set_2 = set([\"red\", \"yellow\", \"red\", \"green\", \"red\", \"yellow\"])\n", "# => {\"green\", \"yellow\", \"red\"}" ] }, { "cell_type": "markdown", "id": "historical-impossible", "metadata": {}, "source": [ "\n", "We can make a set directly using curly braces:\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "protective-easter", "metadata": {}, "outputs": [], "source": [ "colors = {\"red\", \"orange\", \"yellow\", \"green\", \"blue\", \"indigo\", \"violet\"}" ] }, { "cell_type": "markdown", "id": "broke-clearance", "metadata": {}, "source": [ "---\n", "\n", "## Important Note: Sets\n", "\n", "Lists are always in the same order:\n", "\n", "- `my_list = [\"green\", \"yellow\", \"red\"]` is always going to be`[\"green\", \"yellow\", \"red\"]`\n", "- `my_list[0]` is always `\"green\"`; `my_list[1]` is always `\"yellow\"`; `my_list[2]` is always `\"red\"`.\n", "\n", "Sets are not like this! Similar to dictionaries, they're not ordered.\n", "\n", "- `my_set = {\"green\", \"yellow\", \"red\"}` could later be `{\"red\", \"yellow\", \"green\"}`!\n", "- Note that python defaults to displaying an ascending sort of a set. Although this is displayed to the user when the variable is called via the interpreter, _the order cannot be relied upon_.\n", "\n", "We **cannot** do: `my_set[0]` - sets are unordered, and a `TypeError`\n", "exception will be thrown.\n", "\n", "---\n", "\n", "## We Do: Creating a Set from a List\n", "\n", "Let's make some sets!\n", "\n", "- Make a list `clothing_list` containing the main color of your classmates' clothing.\n", "- Using `clothing_list`, make a set named `clothing_set`.\n", "- Use a `for` loop to print out both `clothing_list` and `clothing_set`.\n", "- Try to print an index!" ] }, { "cell_type": "code", "execution_count": null, "id": "conditional-brake", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "italic-drinking", "metadata": {}, "source": [ "---\n", "\n", "## We Do: Adding to a Set\n", "\n", "How do we add more to a set?" ] }, { "cell_type": "code", "execution_count": null, "id": "confidential-documentary", "metadata": {}, "outputs": [], "source": [ "# In a list:\n", "clothing_list.append(\"red\")\n", "\n", "# In a set\n", "clothing_set.add(\"red\")" ] }, { "cell_type": "markdown", "id": "postal-vinyl", "metadata": {}, "source": [ "\n", "`add` vs `append` - this is because we can't guarantee it's going at the end!\n", "\n", "Let's add a few colors to `clothing_list` and `clothing_set` and then print them.\n", "\n", "- What happens if you add a duplicate?\n", "\n", "---\n", "\n", "## We Do: Removing from a List and a Set\n", "\n", "Remember, lists are always the same order and sets are not!\n", "\n", "- With the set `{\"green\", \"yellow\", \"red\"}`, `my_set[0]` could be `green`, `red`, or `yellow`.\n", "\n", "So thus, we need to be careful about removal:\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "clear-rwanda", "metadata": {}, "outputs": [], "source": [ "# In a list:\n", "clothing_list.pop() # Removes and returns the last item in the list.\n", "clothing_list.pop(0) # Removes and returns a specific (here, the first) item in the list.\n", "\n", "# In a set\n", "clothing_set.pop() # Removes and returns an arbitrary element. This is probably not what you want to do in most cases.\n", "# clothing_set.pop(0) # Python throws a TypeError error (pop takes no arguments)\n", "clothing_set.remove('red') # This removes an element from the set directly, and raises KeyError if the element is not present. This is the most common use.\n", "clothing_set.discard('red') # This removes an element from the set directly, but does NOT throw a KeyError if the element is not present in the set." ] }, { "cell_type": "markdown", "id": "cheap-killer", "metadata": {}, "source": [ "\n", "---\n", "\n", "## We Do: Set Intersection\n", "\n", "- One thing that sets are _really_ good at is _relational algebra_ (set theory). This is a fancy word for a SQL join, or comparing elements between two sets.\n", "- Sets are really good at this because they use the same [hashing trick](https://en.wikipedia.org/wiki/Hash_table) under the hood that dictionaries use and makes them so fast.\n", "\n", "Let's start by making two sets:\n" ] }, { "cell_type": "code", "execution_count": null, "id": "reverse-demonstration", "metadata": {}, "outputs": [], "source": [ "set1 = {1, 2, 3, 4, 5}\n", "set2 = {4, 5, 6, 7, 8}" ] }, { "cell_type": "markdown", "id": "owned-noise", "metadata": {}, "source": [ "\n", "---\n", "\n", "## We Do: Set Intersection\n", "\n", "\n", "Now let's use the `.intersection()` set method to find out _what elements these two sets have in common_:\n" ] }, { "cell_type": "code", "execution_count": null, "id": "opened-connectivity", "metadata": {}, "outputs": [], "source": [ "set1.intersection(set2)" ] }, { "cell_type": "markdown", "id": "persistent-jacob", "metadata": {}, "source": [ "\n", "Yields the result: `{4, 5}`\n", "\n", "- This makes sense, the two sets share the elements `4` and `5`.\n", "- Note that this is commutative, meaning we could also write `set2.intersection(set1)` and receive the same result.\n", "\n", "---\n", "\n", "## We Do: Set Differences\n", "\n", "- Instead of finding _elements in common_ between two sets, we can also find _their differences_.\n", "- To do this, we use `.difference()`.\n", "- Note that this method _is not commutative_, meaning _order matters_.\n", "- The difference is what is contained in the _first_ set, _but not in the second set_.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "neural-reform", "metadata": {}, "outputs": [], "source": [ "set1.difference(set2)" ] }, { "cell_type": "markdown", "id": "equal-prince", "metadata": {}, "source": [ "\n", "Yields the result: `{1, 2, 3}`\n" ] }, { "cell_type": "code", "execution_count": null, "id": "breeding-vector", "metadata": {}, "outputs": [], "source": [ "set2.difference(set1)" ] }, { "cell_type": "markdown", "id": "photographic-channels", "metadata": {}, "source": [ "Yields the result: `{6, 7, 8}`\n", "\n", "---\n", "\n", "## Quick Review: Sets vs. Lists\n", "\n", "**Lists**:\n", "\n", "- The original, normal object.\n", "- Created with `[]`.\n", "- `append()`, `insert(index)`, `pop()`, `pop(index)`.\n", "- Duplicates and mutable.\n", "\n", "**Sets**:\n", "\n", "- Lists without duplicates.\n", "- Created with `{}` or with `set(my_list)`.\n", "- `add()` and `remove(element)`.\n", "\n", "---\n", "## Quick Review: Sets vs. Lists" ] }, { "cell_type": "code", "execution_count": null, "id": "exclusive-safety", "metadata": {}, "outputs": [], "source": [ "### Creation ###\n", "# List\n", "my_list = [\"red\", \"yellow\", \"green\", \"red\"]\n", "# Sets\n", "my_set = {\"red\", \"yellow\", \"green\"}\n", "my_set2 = set(my_list)\n", "my_set = set(a_list_to_convert)\n", "\n", "### Appending a New Value ###\n", "my_list.append(\"blue\")\n", "my_set.add(\"blue\")\n", "\n", "### Appending a Duplicate ###\n", "my_list.append(\"blue\")\n", "# => my_list = [\"red\", \"yellow\", \"green\", \"red\", \"blue\", \"blue\"]\n", "my_set.add(\"blue\")\n", "# => my_set = {\"red\", \"yellow\", \"green\", \"blue\"}\n", "\n", "### Removing items: ###\n", "my_list.pop(1)\n", "my_set.remove(\"red\")" ] }, { "cell_type": "markdown", "id": "golden-crest", "metadata": {}, "source": [ "\n", "---\n", "\n", "## Discussion: Immutability Thoughts\n", "\n", "A set is a type of list which doesn't allow duplicates.\n", "\n", "What if, instead, we have a list we don't want to change?\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "hourly-asbestos", "metadata": {}, "outputs": [], "source": [ "rainbow_colors = [\"red\", \"orange\", \"yellow\", \"green\", \"blue\", \"indigo\", \"violet\"]" ] }, { "cell_type": "markdown", "id": "eleven-explorer", "metadata": {}, "source": [ "\n", "We **don't** want:\n" ] }, { "cell_type": "code", "execution_count": null, "id": "aboriginal-denver", "metadata": {}, "outputs": [], "source": [ "rainbow_colors[0] = \"gray\"\n", "## Gray's not in the rainbow!\n", "rainbow_colors.pop()\n", "## We can't lose violet!\n", "rainbow_colors.append(\"pink\")\n", "# Pink's not in the rainbow!" ] }, { "cell_type": "markdown", "id": "literary-disorder", "metadata": {}, "source": [ "\n", "We want `rainbow_colors` to be **immutable** - the list _cannot_ be changed.\n", "\n", "How we do that in Python?\n", "\n", "---\n", "\n", "## Introducing: Tuples\n", "\n", "**Sets** have the following properties:\n", "\n", "- No duplicates\n", "- Mutable\n", "\n", "**Tuples** are similar to a list with the following differences:\n", "\n", "- Allows duplicates (same as a list)\n", "- Once assigned, the tuple _cannot be changed_\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "competitive-latitude", "metadata": {}, "outputs": [], "source": [ "rainbow_colors_tuple = (\"red\", \"orange\", \"yellow\", \"green\", \"blue\", \"indigo\", \"violet\")" ] }, { "cell_type": "markdown", "id": "cubic-prospect", "metadata": {}, "source": [ "\n", "When should you use a tuple?\n", "\n", "- When you need data protection through immutability (note: all Python variables are public).\n", "- When you never want to change the list.\n", "- Tuples are sometimes wrapped in a class namespace to simulate what would be done with a [const structure](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/how-to-define-constants) in a C-based language.\n", "- This is a way of holding appconstants, or constants your program will use (like the API endpoint of a server, credentials, etc.)\n", "\n", "---\n", "\n", "## Tuple Syntax\n", "\n", "- Created with parentheses `()`.\n", "- Access values via indices (like regular lists, but *not* like sets).\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "closed-tennessee", "metadata": {}, "outputs": [], "source": [ "rainbow_colors_tuple = (\"red\", \"orange\", \"yellow\", \"green\", \"blue\", \"indigo\", \"violet\")\n", "print(rainbow_colors[1])" ] }, { "cell_type": "markdown", "id": "inner-stick", "metadata": {}, "source": [ "\n", "- Tuples can be printed with a `for` loop (just like a set or list!).\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "caroline-anniversary", "metadata": {}, "outputs": [], "source": [ "rainbow_colors_tuple = (\"red\", \"orange\", \"yellow\", \"green\", \"blue\", \"indigo\", \"violet\")\n", "\n", "for color in rainbow_colors_tuple:\n", " print(color)" ] }, { "cell_type": "markdown", "id": "mysterious-daniel", "metadata": {}, "source": [ "---\n", "\n", "## We Do: Tuples\n", "\n", "Let's declare a tuple named `seasons` and set it to have the values `fall`, `winter`, `spring`, and `summer`. We'll print the tuple and each value. Then we'll try to reassign them (we can't)!" ] }, { "cell_type": "code", "execution_count": null, "id": "committed-vector", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "occasional-agriculture", "metadata": {}, "source": [ "---\n", "\n", "## Quick Review: Sets, Tuples, Lists\n", "\n", "**List**:\n", "\n", "- The original, normal object: `[\"red\", \"red\", \"yellow\", \"green\"]`.\n", "- Has duplicates; mutable: `append()`, `insert(index)`, `pop()`, `pop(index)`\n", "\n", "**Set**:\n", "\n", "- List without duplicates: `{\"red\", \"yellow\", \"green\"}`.\n", "- Mutable: `add()` and `remove(element)`\n", "\n", "**Tuple**:\n", "\n", "- Has duplicates, but immutable: You can't change it!\n", "- `(\"red\", \"red\", \"yellow\", \"green\")` will *always* be `(\"red\", \"red\", \"yellow\", \"green\")`.\n", "\n", "---\n", "\n", "## Quick Review: Sets, Tuples, Lists" ] }, { "cell_type": "code", "execution_count": null, "id": "black-spanish", "metadata": {}, "outputs": [], "source": [ "### Creation ###\n", "# List\n", "my_list = [\"red\", \"yellow\", \"green\", \"red\"]\n", "# Sets\n", "my_set = {\"red\", \"yellow\", \"green\"}\n", "my_set2 = set(my_list))\n", "my_set = set(a_list_to_convert)\n", "# Tuples\n", "my_tuple = (\"red\", \"yellow\", \"green\")\n", "\n", "### Appending a New Value ###\n", "my_list.append(\"blue\")\n", "my_set.add(\"blue\")\n", "# Tuples -> You can't!\n", "\n", "### Removing items: ###\n", "my_list.pop(1)\n", "my_set.remove(\"red\")\n", "# Tuples -> You can't!" ] }, { "cell_type": "markdown", "id": "prompt-glass", "metadata": {}, "source": [ "\n", "---\n", "\n", "## Introducing Types\n", "\n", "Variables certainly can hold a lot!\n", "\n", "- Sets, tuples, and lists are easily confused.\n", "- `type()` tells us what a variable is: set, tuple, list, dictionary, integer, string - anything!\n", "\n", "Try it:" ] }, { "cell_type": "code", "execution_count": null, "id": "engaged-support", "metadata": {}, "outputs": [], "source": [ "unique_colors = set([\"red\", \"yellow\", \"green\", \"red\"])\n", "print(\"unique_colors is\", type(unique_colors))\n", "# --\n", "unique_colors_2 = [\"red\", \"yellow\", \"green\", \"red\"]\n", "print(\"unique_colors_2 is\", type(unique_colors_2))\n", "# --\n", "unique_colors_3 = (\"red\", \"yellow\", \"green\", \"red\")\n", "print(\"unique_colors_3 is\", type(unique_colors_3))\n", "# --\n", "my_number = 2\n", "print(\"my_number is\", type(my_number))\n", "# --\n", "my_string = \"Hello!\"\n", "print(\"my_string is\", type(my_string))" ] }, { "cell_type": "markdown", "id": "unnecessary-tunnel", "metadata": {}, "source": [ "\n", "\n", "---\n", "\n", "## You Do: List Types Practice\n", "\n", "- Create a list (`[]`), set (`{}`), and tuple (`()`) of some of your favorite foods.\n", "- Create a second set from the list.\n", "\n", "Next, in every list type that you can:\n", "\n", "- Add `\"pizza\"` anywhere; append `\"eggs\"` to the end.\n", "- Remove `\"pizza\"`.\n", "- Re-assign the element at index `1` to be `\"popcorn\"`.\n", "- Remove the element at index `2` and re-insert it at index `0`.\n", "- Print the element at index `0`.\n", "\n", "Print your final lists using a loop, then print their types. Don't throw an error!" ] }, { "cell_type": "code", "execution_count": null, "id": "drawn-imagination", "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "id": "collected-internet", "metadata": {}, "source": [ "---\n", "\n", "## Summary and Q&A\n", "\n", "We've learned two new types of lists:\n", "\n", "Sets:\n", "\n", "- A mutable list without duplicates.\n", "- Handy for storing emails, usernames, and other unique elements." ] }, { "cell_type": "code", "execution_count": null, "id": "arbitrary-movie", "metadata": {}, "outputs": [], "source": [ "email_set = {'my_email@gmail.com', 'second_email@yahoo.com', \"third_email@hotmail.com\"}" ] }, { "cell_type": "markdown", "id": "aboriginal-omaha", "metadata": {}, "source": [ "\n", "Tuples:\n", "\n", "- An immutable list that allows duplicates.\n", "- Handy for storing anything that won't change.\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "id": "valid-trail", "metadata": {}, "outputs": [], "source": [ "rainbow_tuple = (\"red\", \"orange\", \"yellow\", \"green\", \"blue\", \"indigo\", \"violet\")" ] }, { "cell_type": "markdown", "id": "specialized-ribbon", "metadata": {}, "source": [ "\n", "---\n", "\n", "## Additional Reading\n", "\n", "- [Repl.it that recaps Tuples](https://repl.it/@GAcoding/python-programming-tuple-practice?lite=true)\n", "- [Python Count Occurrences of Letters, Words and Numbers in Strings and Lists-Video](https://www.youtube.com/watch?v=szIFFw_Xl_M)\n", "- [Storing Multiple Values in Lists](https://swcarpentry.github.io/python-novice-inflammation/03-lists/)\n", "- [Sets and Frozen Sets](https://www.python-course.eu/sets_frozensets.php)\n", "- [Sets](https://www.learnpython.org/en/Sets)\n", "- [Python Tuple](https://www.programiz.com/python-programming/tuple)\n", "- [Tuples](http://openbookproject.net/thinkcs/python/english3e/tuples.html)\n", "- [Strings, Lists, Tuples, and Dictionaries Video](https://www.youtube.com/watch?v=19EfbO5D_8s)\n", "- [Python Data Structures: Lists, Tuples, Sets, and Dictionaries Video](https://www.youtube.com/watch?v=R-HLU9Fl5ug)\n" ] } ], "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 }