You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

20 KiB

Python Programming: Sets and Tuples


Learning Objectives

After this lesson, you will be able to:

  • Perform common actions with sets.
  • Perform common actions with tuples.
  • Know when to use different data structures.

Discussion: Lists

Here are some lists:

unique_colors = ["red", "yellow", "red", "green", "red", "yellow"]
subscribed_emails = ["mary@gmail.com", "opal@gmail.com", "mary@gmail.com", "sayed@gmail.com"]

What could be a problem here?


Introducing Sets

Lists:

unique_colors_list = ["red", "yellow", "red", "green", "red", "yellow"]
subscribed_emails_list = ["mary@gmail.com", "opal@gmail.com", "mary@gmail.com", "sayed@gmail.com"]

Sets: an unordered collection of unique elements. These are powerful because set theory operations can be applied to them in O(1) time.

unique_colors_set = {"green", "yellow", "red"}
subscribed_emails_set = {"mary@gmail.com", "opal@gmail.com", "sayed@gmail.com"}
  • Notice the {} versus the [].

How Can We Make a Set?

If we explicitly cast a set from a list, Python removes duplicates automatically.

my_set = set(a_list_to_convert)

# In action:
unique_colors_list = ["red", "yellow", "red", "green", "red", "yellow"]
unique_colors_set = set(unique_colors_list)
# => {"green", "yellow", "red"}

# In action:
unique_colors_set_2 = set(["red", "yellow", "red", "green", "red", "yellow"])
# => {"green", "yellow", "red"}

We can make a set directly using curly braces:

colors = {"red", "orange", "yellow", "green", "blue", "indigo", "violet"}

Important Note: Sets

Lists are always in the same order:

  • my_list = ["green", "yellow", "red"] is always going to be["green", "yellow", "red"]
  • my_list[0] is always "green"; my_list[1] is always "yellow"; my_list[2] is always "red".

Sets are not like this! Similar to dictionaries, they're not ordered.

  • my_set = {"green", "yellow", "red"} could later be {"red", "yellow", "green"}!
  • 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.

We cannot do: my_set[0] - sets are unordered, and a TypeError exception will be thrown.


We Do: Creating a Set from a List

Let's pull up a new set_practice.py file and make some sets!

  • Make a list clothing_list containing the main color of your classmates' clothing.
  • Using clothing_list, make a set named clothing_set.
  • Use a for loop to print out both clothing_list and clothing_set.
  • Try to print an index!

We Do: Adding to a Set

How do we add more to a set?

# In a list:
clothing_list.append("red")

# In a set
clothing_set.add("red")

add vs append - this is because we can't guarantee it's going at the end!

Let's add a few colors to clothing_list and clothing_set and then print them.

  • What happens if you add a duplicate?

We Do: Removing from a List and a Set

Remember, lists are always the same order and sets are not!

  • With the set {"green", "yellow", "red"}, my_set[0] could be green, red, or yellow.

So thus, we need to be careful about removal:

# In a list:
clothing_list.pop() # Removes and returns the last item in the list.
clothing_list.pop(0) # Removes and returns a specific (here, the first) item in the list.

# In a set
clothing_set.pop() # Removes and returns an arbitrary element. This is probably not what you want to do in most cases.
clothing_set.pop(0) # Python throws a TypeError error (pop takes no arguments)
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.
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.
---

We Do: Set Intersection

  • 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.
  • Sets are really good at this because they use the same hashing trick under the hood that dictionaries use and makes them so fast.

Let's start by making two sets:

set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
---

We Do: Set Intersection

Now let's use the .intersection() set method to find out what elements these two sets have in common:

set1.intersection(set2)

Yields the result:

{4, 5}
  • This makes sense, the two sets share the elements 4 and 5.
  • Note that this is commutative, meaning we could also write set2.intersection(set1) and receive the same result.

We Do: Set Differences

  • Instead of finding elements in common between two sets, we can also find their differences.
  • To do this, we use .difference().
  • Note that this method is not commutative, meaning order matters.
  • The difference is what is contained in the first set, but not in the second set.
set1.difference(set2)

Yields the result:

{1, 2, 3}
set2.difference(set1)

Yields the result:

{6, 7, 8}

Quick Review: Sets vs. Lists

Lists:

  • The original, normal object.
  • Created with [].
  • append(), insert(index), pop(), pop(index).
  • Duplicates and mutable.

Sets:

  • Lists without duplicates.
  • Created with {} or with set(my_list).
  • add() and remove(element).

Quick Review: Sets vs. Lists

### Creation ###
# List
my_list = ["red",  "yellow", "green", "red"]
# Sets
my_set = {"red",  "yellow", "green"}
my_set2 = set(my_list)
my_set = set(a_list_to_convert)

### Appending a New Value ###
my_list.append("blue")
my_set.add("blue")

### Appending a Duplicate ###
my_list.append("blue")
# => my_list = ["red",  "yellow", "green", "red", "blue",  "blue"]
my_set.add("blue")
# => my_set = {"red",  "yellow", "green", "blue"}

### Removing items: ###
my_list.pop(1)
my_set.remove("red")

Discussion: Immutability Thoughts

A set is a type of list which doesn't allow duplicates.

What if, instead, we have a list we don't want to change?

rainbow_colors = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"]

We don't want:

rainbow_colors[0] = "gray"
## Gray's not in the rainbow!
rainbow_colors.pop()
## We can't lose violet!
rainbow_colors.append("pink")
# Pink's not in the rainbow!

We want rainbow_colors to be immutable - the list cannot be changed.

How we do that in Python?


Introducing: Tuples

Sets have the following properties:

  • No duplicates
  • Mutable

Tuples are similar to a list with the following differences:

  • Allows duplicates (same as a list)
  • Once assigned, the tuple cannot be changed
rainbow_colors_tuple = ("red", "orange", "yellow", "green", "blue", "indigo", "violet")

When should you use a tuple?

  • When you need data protection through immutability (note: all Python variables are public).
  • When you never want to change the list.
  • Tuples are sometimes wrapped in a class namespace to simulate what would be done with a const structure in a C-based language.
  • This is a way of holding appconstants, or constants your program will use (like the API endpoint of a server, credentials, etc.)

Tuple Syntax

  • Created with parentheses ().
  • Access values via indices (like regular lists, but not like sets).
rainbow_colors_tuple = ("red", "orange", "yellow", "green", "blue", "indigo", "violet")
print(rainbow_colors[1])
# Prints "orange"
  • Tuples can be printed with a for loop (just like a set or list!).
rainbow_colors_tuple = ("red", "orange", "yellow", "green", "blue", "indigo", "violet")

for color in rainbow_colors_tuple:
  print(color)

We Do: Tuples

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)!


Quick Review: Sets, Tuples, Lists

List:

  • The original, normal object: ["red", "red", "yellow", "green"].
  • Has duplicates; mutable: append(), insert(index), pop(), pop(index)

Set:

  • List without duplicates: {"red", "yellow", "green"}.
  • Mutable: add() and remove(element)

Tuple:

  • Has duplicates, but immutable: You can't change it!
  • ("red", "red", "yellow", "green") will always be ("red", "red", "yellow", "green").

Quick Review: Sets, Tuples, Lists

### Creation ###
# List
my_list = ["red",  "yellow", "green", "red"]
# Sets
my_set = {"red",  "yellow", "green"}
my_set2 = set(my_list))
my_set = set(a_list_to_convert)
# Tuples
my_tuple = ("red",  "yellow", "green")

### Appending a New Value ###
my_list.append("blue")
my_set.add("blue")
# Tuples -> You can't!

### Removing items: ###
my_list.pop(1)
my_set.remove("red")
# Tuples -> You can't!

Introducing Types

Variables certainly can hold a lot!

  • Sets, tuples, and lists are easily confused.
  • type() tells us what a variable is: set, tuple, list, dictionary, integer, string - anything!

Try it:


You Do: List Types Practice

Create a local file, sets_tuples.py. In it:

  • Create a list ([]), set ({}), and tuple (()) of some of your favorite foods.
  • Create a second set from the list.

Next, in every list type that you can:

  • Add "pizza" anywhere; append "eggs" to the end.
  • Remove "pizza".
  • Re-assign the element at index 1 to be "popcorn".
  • Remove the element at index 2 and re-insert it at index 0.
  • Print the element at index 0.

Print your final lists using a loop, then print their types. Don't throw an error!


Summary and Q&A

We've learned two new types of lists:

Sets:

  • A mutable list without duplicates.
  • Handy for storing emails, usernames, and other unique elements.
email_set = {'my_email@gmail.com', 'second_email@yahoo.com', "third_email@hotmail.com"}

Tuples:

  • An immutable list that allows duplicates.
  • Handy for storing anything that won't change.
rainbow_tuple = ("red", "orange", "yellow", "green", "blue", "indigo", "violet")

Additional Reading