\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
}