11. Tuples#
In this notebook, we cover the following subjects:
Defining a Tuple;
Working with Tuples;
More Advanced Tasks.
# To enable type hints for lists, dicts, and tuples, we need to import the following:
from typing import List, Dict, Tuple
11.1. Defining a Tuple#
In this notebook, we introduce a unique data type used in Python: tuples. A tuple is a sequence of values that is similar to a list, as it is indexed by integers and can contain elements of any type, including duplicates. However, tuples are immutable, whereas lists are mutable. This immutability can be a strength in certain situations, ensuring that the data you store in a tuple remains constant throughout your program’s execution.
Tuples are defined using parentheses ()
.
my_tuple: Tuple = (element1, element2, element3)
Let’s look at an example.
my_tuple: Tuple[int, int] = (1, 2, 3, 4, 5)
print(my_tuple)
type(my_tuple)
(1, 2, 3, 4, 5)
tuple
If you want to create a tuple with just one element, then you have to add a comma (,
) as terminator.
my_second_tuple: tuple = 'programming',
print(my_second_tuple)
type(my_second_tuple)
('programming',)
tuple
A single value between parentheses is not a tuple.
my_third_tuple: tuple = ('statistics')
print(my_third_tuple)
type(my_third_tuple)
statistics
str
11.1.1. The tuple()
function#
The syntax of the tuple()
function is:
tuple(<iterable>)
iterable (optional) - an iterable (list, range, etc.) or an iterator object
If the iterable is not passed to tuple(), the function returns an empty tuple.
Let’s see a few examples:
# Empty tuple, so we specify it as Tuple[()]
t1: Tuple[()] = tuple()
print('t1 =', t1)
# Tuple with integers
t2: Tuple[int, int] = tuple([1, 4, 6])
print('t2 =', t2)
# Tuple with characters (from a string, so str elements)
t3: Tuple[str, str] = tuple('Python')
print('t3 =', t3)
# Tuple with integers (from dictionary keys)
t4: Tuple[int, int] = tuple({1: 'one', 2: 'two'})
print('t4 =', t4)
t1 = ()
t2 = (1, 4, 6)
t3 = ('P', 'y', 't', 'h', 'o', 'n')
t4 = (1, 2)
11.1.2. An Overview#
Now, let’s add the Tuple to the data types we’ve covered so far to create a clear overview of their properties.
Property |
Tuple |
List |
Dict Keys |
Dict Values |
---|---|---|---|---|
Mutable (can you add add/remove?) |
no |
yes |
yes |
yes |
Can contain duplicates |
yes |
yes |
no |
yes |
Ordered |
yes |
yes |
yes (since Python 3.7) |
yes (follows key order) |
Can contain |
all |
all |
immutables |
all |
11.2. Working with Tuples#
11.2.1. Accessing Elements#
The elements in a tuple can be accessed using indexing. (same as with lists)
numbers_tuple: Tuple[int, int] = (1, 2, 3, 4, 5)
# index 0, 1, 2, 3, 4
first_element = numbers_tuple[0]
second_element = numbers_tuple[1]
last_element = numbers_tuple[-1]
print(first_element)
print(second_element)
print(last_element)
1
2
5
11.2.2. Slicing#
You can create sub-tuples by slicing a tuple and assigning them to a new variable. (same as with lists)
actors_tuple: Tuple[str, str] = ("Cillian Murphy", "Emily Blunt", "Robert Downey Jr.", "Matt Damon", "Florence Pugh", "Kenneth Branagh", "Rami Malek")
main_cast_oppenheimer = actors_tuple[:5]
print(main_cast_oppenheimer)
('Cillian Murphy', 'Emily Blunt', 'Robert Downey Jr.', 'Matt Damon', 'Florence Pugh')
11.2.3. Concatenation#
Identical to lists, the +
operator can be used to concatenate two tuples.
morning_tasks: Tuple[str, str] = ("Wake up", "Brush teeth", "Eat breakfast")
evening_tasks: Tuple[str, str] = ("Dinner", "Watch TV", "Go to bed")
daily_tasks = morning_tasks + evening_tasks
print(daily_tasks)
('Wake up', 'Brush teeth', 'Eat breakfast', 'Dinner', 'Watch TV', 'Go to bed')
11.2.4. Repetition#
A new tuple can be created by repeating an existing one using the *
operator.
favorite_fruits: Tuple[str, str] = ("Apple", "Banana", "Cherry")
abundant_fruit_basket = favorite_fruits * 3
print(abundant_fruit_basket)
('Apple', 'Banana', 'Cherry', 'Apple', 'Banana', 'Cherry', 'Apple', 'Banana', 'Cherry')
11.2.5. Length#
The length of a tuple can be found using the len()
function.
road_trip_stops: Tuple[str, str] = ("Gas Station", "Restaurant", "Hotel", "Park", "Museum")
number_of_stops = len(road_trip_stops)
print(f"Number of stops on the road trip: {number_of_stops}")
Number of stops on the road trip: 5
Note
Just as with other data types, dir()
and help()
can be used for tuples.
11.3. More Advanced Tasks#
11.3.1. Packing and Unpacking#
Tuples allow you to pack multiple values into one variable and unpack them into several variables.
# Packing multiple values into a tuple
my_tuple: Tuple[int, int] = (1, 2, 3)
# Unpacking values from the tuple
a, b, c = my_tuple
print(a, b, c)
1 2 3
11.3.2. Tuples as Return Values#
By means of a tuple a function can return a collection of values.
def get_coordinates() -> Tuple[int, int]:
x: int = 10
y: int = 20
return x, y # Returning a tuple
coordinates: Tuple[int, int] = get_coordinates()
x, y = coordinates # Unpacking the returned values
print(x, y)
10 20
Note
Unlike lists, tuples can be used as keys in dictionaries due to their immutability.
Exercises
Let’s practice! Mind that each exercise is designed with multiple levels to help you progressively build your skills. Level 1 is the foundational level, designed to be straightforward so that everyone can successfully complete it. In Level 2, we step it up a notch, expecting you to use more complex concepts or combine them in new ways. Finally, in Level 3, we get closest to exam level questions, but we may use some concepts that are not covered in this notebook. However, in programming, you often encounter situations where you’re unsure how to proceed. Fortunately, you can often solve these problems by starting to work on them and figuring things out as you go. Practicing this skill is extremely helpful, so we highly recommend completing these exercises.
For each of the exercises, make sure to add a docstring
and type hints
, and do not import any libraries unless specified otherwise.
11.3.3. Exercise 1#
An article critic works with multiple magazines and realizes that most articles use the same words to describe specific events.
Level 1: Your task is to define a function named common_words()
that creates a tuple containing all the common words found in both article_1
and article_2
. You are not allowed to use sets and their methods.
The function common_words()
should:
Accept two parameters in the following order:
A string containing
article_1
A string containing
article_2
Create a tuple with the words that are common to both
article_1
andarticle_2
(excluding spaces and punctuation).Return the tuple of common words.
Print the tuple outside the function in a clear and readable format.
Example input: you pass these arguments to the parameters in the function call.
article_1 : str = "The strong winds in the Netherlands bring cool air from the North Sea."
article_2 : str = "In the Netherlands, windmills have been used for centuries to harness the power of the wind from the sea."
Example output:
"Common words in both articles: ('sea', 'the', 'netherlands', 'in', 'from')"
# TODO.
Level 2: Now, let’s take the common_words()
function up a notch. Your task is to copy and modify this function so that it not only identifies the common words but also counts how many times each of these common words shows up across both articles. The function should return a tuple of tuples, where each inner tuple consists of a word and its total count from both articles combined.
The function common_words()
should now:
Accept two parameters in the following order:
A string containing
article_1
A string containing
article_2
Create a dictionary (excluding spaces and punctuation) where the keys are the common words and the values are the total counts of those words across both articles.
Convert the dictionary into a tuple of tuples, where each inner tuple is in the form
(word, count)
.Return the tuple of tuples sorted alphabetically by the word.
Print the tuple outside the function in a clear and readable format.
Example input: you pass these arguments to the parameters in the function call.
article_1 : str = "The strong winds in the Netherlands bring cool air from the North Sea."
article_2 : str = "In the Netherlands, windmills have been used for centuries to harness the power of the wind from the sea."
Example output:
"The word frequency of the common words: (('from', 2), ('in', 2), ('netherlands', 2), ('sea', 2), ('the', 7))"
Level 3: In this level, we’ll explore word similarity instead of exact matches. Modify the common_words()
function so that it not only finds words that are common in both articles but also identifies similar words.
Define “similar words” as words that share a common root or stem. For example, “running” and “run” would be considered similar, as would “houses” and “house.”
For the purpose of this exercise, assume that words are similar if they:
Share at least the first four characters (e.g., “windmill” and “windmills”).
OR, have a common suffix that is three characters or fewer (e.g., “running” and “run”).
The new function should:
Accept two parameters in the following order:
A string containing
article_1
A string containing
article_2
Find words that are similar across both articles, using the above definitions of similarity.
Count the total occurrences of each similar word group across both articles.
Return a tuple of tuples, where each inner tuple is in the form (word_root, count), sorted by frequency in descending order, then alphabetically for ties.
Example input:
article_1 : str = "The strong winds in the Netherlands bring cool air from the North Sea. Windmills help harness wind power."
article_2 : str = "Wind power has been crucial in the Netherlands. Many windmills stand tall and capture the wind for power generation."
Example output:
"The word frequency of similar words: (('wind', 6), ('netherland', 2), ('power', 2), ('mill', 2))""
# TODO.
11.3.4. Exercise 2#
VU Amsterdam aims to award a scholarship to the best-performing student and recognize all students who have excelled academically.
Level 1: Your task is to define a function named honors_students()
that determines the student with the highest GPA and identifies all students with a 9.0 GPA or higher. The function should work as follows:
It receive one parameter: a dictionary where the keys are the names of the students and the values are their GPA scores.
It creates a tuple with two parts:
The first part is a tuple containing the name and GPA of the best performing student.
The second part is a tuple of tuples, where each inner tuple contains the name and GPA of a student with a GPA of 9.0 or above.
Finally, the function should return these two parts as a single tuple using the statement:
return highest_gpa_student, honors
.
Print the result outside the function in a clear and readable format.
Example input:
student_scores : Dict[str,float]= {
"Alice": 9.5,
"Bob": 8.8,
"Charlie": 9.2,
"David": 9.8,
"Eve": 8.9,
"Frank": 9.7,
"Grace": 8.0,
"Hannah": 9.1,
"Isaac": 7.5,
"Jack": 8.5,
"Katherine": 9.3,
"Liam": 7.2,
"Mia": 8.2,
"Noah": 7.9,
}
Example return value:
(('David', 9.8), (('Alice', 9.5), ('Charlie', 9.2), ('David', 9.8), ('Frank', 9.7), ('Hannah', 9.1), ('Katherine', 9.3)))
Example output:
David has the highest GPA in the scientific department, with a score of 9.8.
Students with a GPA above 9.0:
- Alice: GPA 9.5
- Charlie: GPA 9.2
- David: GPA 9.8
- Frank: GPA 9.7
# TODO.
Level 2: Copy the honors_students()
function and modify it so that it not only finds the student with the highest GPA and those with GPAs of 9.0 or higher but also ranks the top 3 students by GPA. The function should now return a three-part tuple:
The student with the highest GPA, as before;
A tuple of tuples containing students with GPAs of 9.0 or higher;
A list of tuples with the top 3 students, sorted by GPA in descending order;
Return these three parts as a single tuple using return highest_gpa_student, honors, top3_gpa
.
If there are fewer than three students, the list should include only the available students.
Print the result outside the function in a clear and readable format.
Example input:
student_scores : Dict[str,float]= {
"Alice": 9.5,
"Bob": 8.8,
"Charlie": 9.2,
"David": 9.8,
"Eve": 8.9,
"Frank": 9.7,
"Grace": 8.0,
"Hannah": 9.1,
"Isaac": 7.5,
"Jack": 8.5,
"Katherine": 9.3,
"Liam": 7.2,
"Mia": 8.2,
"Noah": 7.9,
}
Example return value:
(('David', 9.8), (('Alice', 9.5), ('Charlie', 9.2), ('David', 9.8), ('Frank', 9.7), ('Hannah', 9.1), ('Katherine', 9.3)), [('David', 9.8), ('Frank', 9.7), ('Alice', 9.5)])
Example output:
David has the highest GPA in the scientific department, with a score of 9.8.
Students with a GPA above 9.0:
- Alice: GPA 9.5
- Charlie: GPA 9.2
- David: GPA 9.8
- Frank: GPA 9.7
Top 3 students by GPA:
1. David: GPA 9.8
2. Frank: GPA 9.7
3. Alice: GPA 9.5
# TODO.
Level 3: As the data we want to extract grows, using a format of tuples can become less readable. Do you remember a better way to organize multi-layered data? Exactly—dictionaries!
In this exercise, your task is to enhance the honors_students()
function so that it returns a comprehensive analysis of student performance in a single dictionary. The function should do the following:
Identify the student(s) with the highest GPA.
Rank the top 3 students by GPA, including ties if multiple students share the same GPA.
Rather than simply filtering students with GPAs of 9.0 or higher, the function should categorize students into three distinct GPA tiers:
Tier 1: Students with a GPA of 9.5 or higher.
Tier 2: Students with a GPA between 9.0 and 9.5 (exclusive).
Tier 3: Students with a GPA below 9.0 but above or equal to 8.0.
The function should return a dictionary with the following structure:
“Highest GPA”: A list of tuples with the name(s) and GPA(s) of the student(s) with the highest GPA.
“Top 3 Students”: A list of tuples representing the top 3 students, sorted by GPA in descending order (including ties).
“Tiers”: A nested dictionary categorizing students into the three GPA tiers. Each tier list sorted by GPA in descending order (including ties).
Return this dictionary using the statement: return result_dict
and print the dictionary outside the function.
Example input:
student_scores : Dict[str,float]= {
"Alice": 9.5,
"Bob": 9.5,
"Charlie": 9.2,
"David": 9.8,
"Eve": 8.9,
"Frank": 9.7,
"Grace": 8.5,
"Hannah": 9.1,
"Isaac": 7.5,
"Jack": 8.5,
"Katherine": 9.3,
"Liam": 7.2,
"Mia": 8.2,
"Noah": 7.9,
}
Example return value/output:
{
"Highest GPA": [("David", 9.8)],
"Top 3 Students": [("David", 9.8), ("Frank", 9.7), ("Alice", 9.5), ("Bob", 9.5)],
"Tiers": {
"Tier 1": [("David", 9.8), ("Frank", 9.7), ("Alice", 9.5), ("Bob", 9.5)],
"Tier 2": [("Katherine", 9.3), ("Charlie", 9.2), ("Hannah", 9.1)],
"Tier 3": [("Eve", 8.9), ("Grace", 8.5), ("Jack", 8.5), ("Mia", 8.2)]
}
}
# TODO.
11.3.5. Exercise 3#
Level 1 Create a function named election_results_summary()
that takes a list of tuples, where each tuple represents a candidate and their votes in a specific state.
The function should:
Accept a list of tuples, where each tuple has:
A string for the state
A string for the candidate name
An integer representing the number of votes
Return a tuple with:
The total number of states,
The total number of candidates (count unique candidate names),
The total number of votes cast.
Example input:
election_data: List[str, int] = [
("California", "Kamala Koala", 5000000),
("Texas", "Donald Duck", 4500000),
("California", "Donald Duck", 4000000),
("Florida", "Kamala Koala", 3500000)
]
Example output:
(3, 2, 17000000)
# TODO.
Level 2 Now, create function named state_winner_summary()
that provides a breakdown of each state’s winning candidate.
The function should:
Accept a list of tuples in the format: (state, candidate, votes).
Use a dictionary to store each state’s data, with:
the state as the key
and a tuple containing the winning candidate and their vote count as the value.
Unpack each tuple in the input list to extract the state, candidate, and votes.
For each state, keep track of only the candidate with the highest vote count.
If there is a tie, retain only the first candidate in the input list for that state.
Return a tuple of tuples where each inner tuple is in the form (state, candidate, votes), sorted alphabetically by state (ascending order, a to z).
Example input:
election_data: List[str, int] = [
("California", "Kamala Koala", 5000000),
("California", "Donald Duck", 4000000),
("Texas", "Kamala Koala", 4500000),
("Texas", "Donald Duck", 4600000),
("Florida", "Kamala Koala", 3500000)
]
Example output:
(("California", "Kamala Koala", 5000000), ("Florida", "Kamala Koala", 3500000), ("Texas", "Donald Duck", 4600000))
# TODO.
Level 3 Lastly, create a function named detailed_candidate_results()
to validate and structure a breakdown of the top two candidates in each state.
The function should:
Accept a list of tuples in the format (state, candidate, votes).
Use a dictionary to store each state’s candidates, sorted by vote count in descending order.
Perform the following validations:
Assert
each candidate has a positive vote count.Assert
each state has at least two candidates; if a state has only one candidate, raise anAssertionError
with the message"Insufficient candidates in <state name>."
For each state, use your programming knowledge to get only the top two candidates by votes.
Return a dictionary where:
the keys are states,
and the values are tuples containing only the top two candidates, with each candidate represented by a tuple in the form (candidate, votes).
Example input:
election_data: List[str, int] = [
("California", "Kamala Koala", 5000000),
("California", "Goofy Gopher", 2000000),
("Florida", "Kamala Koala", 3500000),
("Florida", "Donald Duck", 3400000),
("Texas", "Minnie Mouse", 3000000),
("Florida", "Daisy Duck", 3300000),
("Florida", "Bugs Bunny", 1000000),
("Texas", "Kamala Koala", 4500000),
("California", "Donald Duck", 4000000),
("California", "Mickey Mouse", 3000000),
("Texas", "Donald Duck", 4600000)
]
Example output:
{
"California": (("Kamala Koala", 5000000), ("Donald Duck", 4000000)),
"Texas": (("Donald Duck", 4600000), ("Kamala Koala", 4500000)),
"Florida": (("Kamala Koala", 3500000), ("Donald Duck", 3400000))
}
# TODO.
Material for the VU Amsterdam course “Introduction to Python Programming” for BSc Artificial Intelligence students. These notebooks are created using the following sources:
Learning Python by Doing: This book, developed by teachers of TU/e Eindhoven and VU Amsterdam, is the main source for the course materials. Code snippets or text explanations from the book may be used in the notebooks, sometimes with slight adjustments.