An Introduction to Tuple, Set, and Dictionary in Data Structure

Quang TrịnhQuang Trịnh
17 min read

This article explores essential data structures in Python, including tuples, sets, and dictionaries. It explains the characteristics and use cases of each structure, highlighting tuples for immutability, sets for handling unique elements, and dictionaries for efficient key-value storage. The article also covers practical examples and coding techniques, emphasizing how understanding these structures ensures efficient data management and application-specific coding in Python.

Tuple in Python

Do you know what a data structure is? A data structure is a system used to store and organize data. It arranges data on a computer so it can be accessed and updated efficiently.

1D List Solution

Dr. Nguyen presents a math problem where you use Python to create a list of about 6 students in a class. You need to check their seating arrangement, which is organized in 3 rows and 2 columns. This 1D List Solution means you solve the problem using only a basic list in Python, not a matrix.

You have 6 students:

["Vinh", "An", "Toan", "Lam", "Tam", "Chuyen"]

They sit in 3 rows and 2 columns, from top to bottom, left to right:

Row 1: Vinh   | An
Row 2: Toan   | Lam
Row 3: Tam    | Chuyen
       Col 1    Col 2

Dr. Nguyen suggests a solution for this problem using an algorithm that can be difficult for beginners. He uses two examples, Tam and Chuyen, to explain this solution. This is a classic 2D-to-1D indexing problem that you can solve using Python.

# List of students arranged row-wise
student_list = ["Vinh", "An", "Toan", "Lam", "Tam", "Chuyen"]

# Dimensions of the classroom
row_class = 3
col_class = 2

# Function to find the student at a given (row, column)
def find_student(student_list, r, c):
    index = (r - 1) * col_class + (c - 1)
    return student_list[index]

# Find student at location (3, 1)
print(find_student(student_list, 3, 1))  # Output: Tam

# Find student at location (3, 2)
print(find_student(student_list, 3, 2))  # Output: Chuyen

The key part of this solution is the algorithm for calculating the index in the find_student function. It shows how we convert from 2D to 1D using simple math to solve the problem.

To get the student at row r and column c, you calculate the index in the list with the formula:

index = (r - 1) * col_class + (c - 1)

The formula moves us row by row:

  • Row 1: starts at index 0 → positions 0, 1

  • Row 2: starts at index 2 → positions 2, 3

  • Row 3: starts at index 4 → positions 4, 5

Using (r - 1) * col_class helps us skip whole rows, and (c - 1) picks the seat in the row.

ExampleResultAnalysis
find_student(student_list, 3, 1)TamRow 1: starts at index 0
find_student(student_list, 3, 2)ChuyenRow 2: starts at index 2
find_student(student_list, 2, 1)ToanRow 3: starts at index 4
find_student(student_list, row, col)Row 1 index: (1 - 1) * 2 = 0
Row 2 index: (2 - 1) * 2 = 2
Row 3 index: (3 - 1) * 2 = 4
find_student(student_list, 3, 1)TamIndex = (3 - 1) * 2 + (1 - 1) = 4
find_student(student_list, 3, 2)ChuyenIndex = (3 - 1) * 2 + (2 - 1) = 5

You can see that it can be challenging for people using Python or learning data structures for the first time. Dr. Nguyen will teach you a 2D List Solution that is much easier and more understandable for everyone, similar to algebra.

2D List Solution

Dr. Nguyen suggests using a 3x1D List in one list instead of just a 1D list for all.

Instead of one giant list, you can structure each row as a 1D list:

row1_student = ["Vinh", "An"]
row2_student = ["Toan", "Lam"]
row3_student = ["Tam", "Chuyen"]

Then, we combine them into a 2D list:

student_list = [row1_student, row2_student, row3_student]

2D List

  • Easy to visualize and manage tabular data.

  • Helps with real-world mapping: seating plans, spreadsheets, matrices, etc.

  • Provides clean indexing for accessing or updating values.

And by combining all of this, you will have a program to solve this problem more easily.

# Step 1: Define each row as a 1D list
row1_student = ["Vinh", "An"]
row2_student = ["Toan", "Lam"]
row3_student = ["Tam", "Chuyen"]

# Step 2: Combine rows into a 2D list
student_list = [row1_student, row2_student, row3_student]

# Step 3: Define a function to find a student at row r and column c (1-based indexing)
def find_student(student_list, r, c):
    return student_list[r - 1][c - 1]

# Step 4: Use the function to find students
print(find_student(student_list, 3, 1))  # Output: Tam
print(find_student(student_list, 3, 2))  # Output: Chuyen

Python Basics: Mutable vs. Immutable

In Python, everything is treated as an object. Each object has three core attributes:

  • Identity: The memory address (where it's stored)

  • Type: The kind of object (e.g., list, string, int)

  • Value: The actual data stored in the object

Understanding the difference between mutable and immutable types is essential for writing reliable and efficient Python code.

MutableImmutable
Can change value?✅ Yes❌ No
ExamplesList, Dictionary, SetString, Tuple, Integer

Lists Are Mutable

Mutable objects like lists can have their content changed without changing their identity.

list = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
print("original list")
print(list)

# Change value at index 4
list[4] = 'hello'
print("changed list")
print(list)
#original list
#['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
#changed list
#['a', 'b', 'c', 'd', 'hello', 'f', 'g', 'h']

Strings Are Immutable

Immutable objects like strings cannot be changed after creation.

words = "AI is trending"
words[3] = 'e'  # Attempt to change character at index 3
#TypeError: 'str' object does not support item assignment

Memory Address Check

List (Mutable):

list1 = [1, 2, 3, 4, 5]
list2 = [1, 2, 3, 4, 5]

print(id(list1))  # Memory address of list1
print(id(list2))  # Memory address of list2
#Different between 2 ID

String (Immutable):

str1 = "AI2024"
str2 = "AI2024"

print(id(str1))  # Memory address of str1
print(id(str2))  # Memory address of str2
# Two ID are the same

Conclusion:

FeatureMutable (e.g., List)Immutable (e.g., String)
Can change value?✅ Yes❌ No (new object is created)
Memory behaviorNew object → new memory addressIdentical values may share memory address

Tuple Motivation And Definition of Tuple

Definition

Tuple are another kind of sequence that functions much like a list - they have elements which are indexed starting at 0. Unlike a list, once you create a tuple, you cannot alter its contents - similar to a string.

FeatureTupleList
Mutable❌ No✅ Yes
Faster✅ Yes❌ No
Hashable✅ (if elements are)❌ No
Safe for configs✅ Yes❌ No
Can be dict key✅ Yes❌ No

Structure

 tuple_name = (element-1, …, element-n)

When you use a tuple, you can use many functions in Python like len(), zip(), sorted(), etc.

Tuple Examples

  • Swapping two variables

      def swap(v1, v2):
          (v2, v1) = (v1, v2)
          return (v1, v2)
    
      v1 = 2
      v2 = 3
      (v1, v2) = swap(v1, v2)
    
      print(v1)
      print(v2)
    
  • Memory requirement

      # memory comparison
      import sys
      alist = [3, 4, 5, 6, 7]
      aTuple = (3, 4, 5, 6, 7)
    
      print(sys.getsizeof(alist))
      print(sys.getsizeof(aTuple))
    
  • Tuple slicing

      data = (1, 2, 3, 4, 5)
      print(data[2:])  # (3, 4, 5)
    
  • List2tuple

      # convert from list to tuple
      alist = [3, 4, 5, 6, 7]
      aTuple = tuple(alist)
    
      print(aTuple)
      print(type(aTuple))  # <class 'tuple'>
    
  • Tuple2list

      # convert from tuple to list
      aTuple = (3, 4, 5, 6, 7)
      alist = list(aTuple)
    
      print(alist)
      print(type(alist))  # <class 'list'>
    

Example: Solve quadratic equation

import math

def quadratic_equation(a, b, c):
    # This function solves the quadratic equation
    # a, b, c -- three parameters and a != 0
    # compute delta
    delta = b*b - 4*a*c

    if delta < 0:
        return ()
    elif delta == 0:
        x = (-b)/(2*a)
        return (x,)
    else:
        x1 = (-b + math.sqrt(delta))/(2*a)
        x2 = (-b - math.sqrt(delta))/(2*a)
        return (x1, x2)

# Case 1: delta > 0
result = quadratic_equation(1, -5, 6)
print(result)  # (3.0, 2.0)
print(type(result))  # <class 'tuple'>

# Case 2: delta = 0
result = quadratic_equation(1, 2, 1)
print(result)  # (-1.0,)
print(type(result))  # <class 'tuple'>

# Case 3: delta < 0
result = quadratic_equation(1, 1, 1)
print(result)  # ()
print(type(result))  # <class 'tuple'>

# Data is protected
result = quadratic_equation(1, 1, 1)

Set Motivation in Python

Definition

Sets, unlike lists or tuples, do not allow duplicate elements and store values in no particular order.

What you can do?

Create a set

  • Using curly brackets

      # create a set
      animals = {"cat", "dog", "tiger"}
      print(type(animals))
      # <class 'set'>
    
  • Items with different data types

      # a set
      a = {"cat", 5, True, 40.0}
      print(type(a))
      # <class 'set'>
    
  • Set comprehension

      # a set comprehension
      a_set = {i * i for i in range(10)}
      print(a_set)
      # {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
    
  • Access the items of a set

      # accessing the items of a set
      animals = {"cat", "dog", "tiger"}
      for animal in animals:
          print(animal)
      # dog
      # cat
      # tiger
    
  • Copy a set

      # copy a set
      animals = {"cat", "dog", "tiger"}
      print(animals)  # animals
      a_copy = animals.copy()
      print(a_copy)  # a_copy
      # Animals: {'dog', 'cat', 'tiger'}
      # Copy: {'dog', 'cat', 'tiger'}
    
  • Add an item

      # add an item
      animals = {"cat", "dog", "tiger"}
      animals.add("bear")
      print(animals)
      # {'dog', 'bear', 'cat', 'tiger'}
    
  • Insert a set to another set

      # insert a set into another set
      animals = {"cat", "dog", "tiger"}
      animals.update({"chicken", "duck"})
      print(animals)
      # {'Duck', 'tiger', 'dog', 'cat', 'chicken'}
    
  • Join two sets

      # join two sets
      set1 = {"duck", "dog"}
      set2 = {"cat", "tiger"}
      set3 = set1.union(set2)
      print(set3)
      # {'duck', 'dog', 'cat', 'tiger'}
    
  • Not allow duplicate values

      # no duplication
      animals = {"cat", "dog", "tiger"}
      animals.add("cat")
      print(animals)
      # {'tiger', 'cat', 'dog'}
    
  • Difference function

      # difference function
      set1 = {"apple", "banana", "cherry"}
      set2 = {"pineapple", "apple"}
      set3 = set1.difference(set2)
      print(set3)
      # {'cherry', 'banana'}
    
  • Symmetric_difference

      # symmetric difference
      set1 = {"apple", "banana", "cherry"}
      set2 = {"pineapple", "apple"}
      set3 = set1.symmetric_difference(set2)
      print(set3)
      # {'pineapple', 'cherry', 'banana'}
    
  • Difference_update function

      # difference update function
      set1 = {"apple", "banana", "cherry"}
      set2 = {"pineapple", "apple"}
      set1.difference_update(set2)
      print(set1)
      # {'cherry', 'banana'}
    
  • Symmetric_difference_update

      # symmetric difference update
      set1 = {"apple", "banana", "cherry"}
      set2 = {"pineapple", "apple"}
      set1.symmetric_difference_update(set2)
      print(set1)
      # {'pineapple', 'cherry', 'banana'}
    
  • Unordered and unindexed

      # not support indexing
      animals = {"cat", "dog", "tiger"}
      print(animals[1])  # Raises TypeError
      # TypeError: 'set' object is not subscriptable
    
  • Cannot contain unhashable types

      # create a set
      a_list = [1, 2, 3]
      a_set = {"cat", a_list}  # Raises TypeError
      print(a_set)
      # TypeError: unhashable type: 'list'
    

Bitwise operator

  • AND

      # AND (&)
      set1 = {1, 2, 3}
      set2 = {3, 4, 5}
      print(set1 & set2)
      # {3}
    
  • XOR

      # XOR (^)
      set1 = {1, 2, 3}
      set2 = {3, 4, 5}
      print(set1 ^ set2)
      # {1, 2, 4, 5}
    
  • OR

      # OR (|)
      set1 = {1, 2, 3}
      set2 = {3, 4, 5}
      print(set1 | set2)
      # {1, 2, 3, 4, 5}
    
  • SUBTRACTION

      # subtraction (-)
      set1 = {1, 2, 3}
      set2 = {3, 4, 5}
      print(set1 - set2)
      # {1, 2}
    

Remove an item

Instead of using remove, you must use discard when working with a set which item is not contained in this set

  • remove(item)

      # remove an item
      animals = {"cat", "dog", "tiger"}
      animals.remove("cat")
      print(animals)
      # {'dog', 'tiger'}
    
  • discard(item)

      # remove an item from the set if it is present
      animals = {"cat", "dog", "tiger"}
      animals.discard("tiger")
      print(animals)
      # {'dog', 'cat'}
    
  • Set comprehension

      # a set comprehension
      a_set = {i for i in range(10)}
      print(a_set)
      # {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
    
  • remove(item)
    Remove an item from the set.
    Raises KeyError if elem is not contained in the set.

      # remove an item
      animals = {"cat", "dog", "tiger"}
      animals.remove("duck")  # Raises KeyError if 'duck' is not in the set
      print(animals)
      # KeyError: 'duck'
    
  • discard(item)
    Remove an item from the set if it is present.

      # remove an item from the set if it is present
      animals = {"cat", "dog", "tiger"}
      animals.discard("duck")
      print(animals)
      # {'dog', 'cat', 'tiger'}
    

Set to List and Tuple

  • Set to List

      # convert from set to list
      aSet = {1, 2, 3, 4, 5}
      aList = list(aSet)
      print(aList)
      print(type(aList))
      # [1, 2, 3, 4, 5]
      # <class 'list'>
    
  • List to Set

      # convert from list to set
      aList = [1, 2, 3, 2, 1]
      aSet = set(aList)
      print(aSet)
      print(type(aSet))
      # {1, 2, 3}
      # <class 'set'>
    
  • Set to Tuple

      # convert from set to tuple
      aSet = {1, 2, 3, 4, 5}
      aTuple = tuple(aSet)
      print(aTuple)
      print(type(aTuple))
      # (1, 2, 3, 4, 5)
      # <class 'tuple'>
    
  • Tuple to Set

      # convert from tuple to set
      aTuple = (1, 2, 3, 2, 1)
      aSet = set(aTuple)
      print(aSet)
      print(type(aSet))
      # {1, 2, 3}
      # <class 'set'>
    

Dictionary in Python

Definition

A dictionary in Python is a built-in data structure that stores data as key-value pairs. It's an unordered, mutable collection where each element consists of a unique key and its associated value.

Structure

Dictionaries use curly braces {} and store data in the format {key: value, key: value, ...}

 dictionary_name = {key-1:value-1, …, key-n:value-n}

Key Properties:

  • Keys must be unique and immutable (strings, numbers, tuples)

  • Values can be of any data type and can be duplicated

  • Dictionaries are mutable (can be modified after creation)

  • As of Python 3.7+, dictionaries maintain insertion order

Comparing between List and Dictionary

AspectListsDictionaries
Keys/IndicesNumeric indices onlyAny immutable type (strings, numbers, tuples)
DuplicatesValues can be duplicatedKeys must be unique, values can be duplicated
PerformanceO(n) for searchingO(1) average for key lookup
Use CaseSequential data, ordered collectionsMappings, lookups, related data

Use Lists when:

  • You need ordered data

  • Working with sequences

  • Indices have meaning (like time series)

  • Need to maintain duplicates

Use Dictionaries when:

  • You need fast lookups

  • Data has natural key-value relationships

  • Keys are more meaningful than positions

  • Building mappings or associations

What you can do?

Create a Dictionary

  • Dictionary comprehension

      # dic comprehension
      a_dict = {i: i * i for i in range(5)}
      print(a_dict)
      # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
    
  • From zip

      # from zip
      tuple1 = (1, 2, 3)
      tuple2 = (4, 5, 6)
      a_dict = dict(zip(tuple1, tuple2))
      print(a_dict)
      # {1: 4, 2: 5, 3: 6}
    
  • From zip (alternative)

      # from zip
      list1 = [1, 2, 3]
      list2 = [4, 5, 6]
      a_dict = dict(zip(list1, list2))
      print(a_dict)
      # {1: 4, 2: 5, 3: 6}
    
  • From zip

      # from zip
      set1 = {1, 2, 3}
      set2 = {4, 5, 6}
      a_dict = dict(zip(set1, set2))
      print(a_dict)
      # {1: 4, 2: 5, 3: 6}
    

Update a value

# update a value
parameters = {"learning_rate": 0.1, "metric": "Accuracy"}
parameters["learning_rate"] = 0.2
print(parameters)
# {'learning_rate': 0.2, 'metric': 'Accuracy'}

Copy a dictionary

# copy a dictionary
parameters = {"learning_rate": 0.1, "metric": "Accuracy"}
a_copy = parameters.copy()
print(a_copy)
# {'learning_rate': 0.1, 'metric': 'Accuracy'}

Copy() function just only copy shallow type

# shallow copy
d1 = {"a": [1, 2], "b": 1}
d2 = d1.copy()
# thay đổi d1 sẽ không ảnh hưởng đến d2
d1["a"][0] = 3
print(d1)  # {'a': [3, 2], 'b': 1}
print(d2)  # {'a': [3, 2], 'b': 1}

Using deepcopy() function in module copy

# using deepcopy
import copy
d1 = {"a": [1, 2], "b": 1}
d2 = copy.deepcopy(d1)
d1["a"][0] = 3
print(d1)  # {'a': [3, 2], 'b': 1}
print(d2)  # {'a': [1, 2], 'b': 1}

Get keys and values

  • Get keys

      # Get keys
      parameters = {"learning_rate": 0.1, "optimizer": "Adam", "metric": "Accuracy"}
      keys = parameters.keys()
      print(keys)
      # dict_keys(['learning_rate', 'optimizer', 'metric'])
    
  • Get values

      # Get values
      parameters = {"learning_rate": 0.1, "optimizer": "Adam", "metric": "Accuracy"}
      values = parameters.values()
      print(values)
      # dict_values([0.1, 'Adam', 'Accuracy'])
    
  • Get keys and values

      # Get keys and values
      parameters = {"learning_rate": 0.1, "optimizer": "Adam", "metric": "Accuracy"}
      items = parameters.items()
      for key, value in items:
          print(key, value)
      # learning_rate 0.1
      # optimizer Adam
      # metric Accuracy
    

Get a value by a key

  • Get value using get() function

      # Get value using get() function
      parameters = {"learning_rate": 0.1, "optimizer": "Adam", "metric": "Accuracy"}
      value = parameters.get("learning_rate")
      print(value)
      print("After using get() function:")
      print(parameters)
      # 0.1
      # After using get() function:
      # {'learning_rate': 0.1, 'optimizer': 'Adam', 'metric': 'Accuracy'}
    
  • Get value and delete the corresponding item

      # Get value and delete the corresponding item
      parameters = {"learning_rate": 0.1, "optimizer": "Adam", "metric": "Accuracy"}
      value = parameters.pop("learning_rate")
      print(value)
      print("After using pop() function:")
      print(parameters)
      # 0.1
      # After using pop() function:
      # {'optimizer': 'Adam', 'metric': 'Accuracy'}
    

Dictionary operations

  • popitem()

      # popitem() - Lấy ra một phần tử cuối cùng của dictionary
      parameters = {"learning_rate": 0.1, "optimizer": "Adam", "metric": "Accuracy"}
      item = parameters.popitem()
      print(item)
      print(parameters)
      # ('metric', 'Accuracy')
      # {'learning_rate': 0.1, 'optimizer': 'Adam'}
    
  • clear()

      # clear() - Xóa tất cả các phần tử trong dictionary
      parameters = {"learning_rate": 0.1, "optimizer": "Adam", "metric": "Accuracy"}
      print("Before using clear() function:")
      print(parameters)
      parameters.clear()
      print("After using clear() function:")
      print(parameters)
      # Before using clear() function:
      # {'learning_rate': 0.1, 'optimizer': 'Adam', 'metric': 'Accuracy'}
      # After using clear() function:
      # {}
    
  • Use del keyword to delete an item

      # Use del keyword to delete an item
      parameters = {"learning_rate": 0.1, "metric": "Accuracy"}
      print(parameters)
      del parameters["metric"]
      print(parameters)
      # {'learning_rate': 0.1, 'metric': 'Accuracy'}
      # {'learning_rate': 0.1}
    

Key that does not exist

  • Try to delete a non-existing item

      # Try to delete a non-existing item
      parameters = {"learning_rate": 0.1, "metric": "Accuracy"}
      del parameters["algorithm"]
      # KeyError: 'algorithm'
    
  • Try to get an item by a non-existing key

      # Try to get an item by a non-existing key
      parameters = {"learning_rate": 0.1, "optimizer": "Adam", "metric": "Accuracy"}
      value = parameters.pop("algorithm")
      # KeyError: 'algorithm'
    
  • Setdefault() function

    • Example 1

        # setdefault() function
        fruits = {"banana": 2}
        fruits.setdefault("apple", 0)
        print(fruits)
        # {'banana': 2, 'apple': 0}
      
  • Example 2

      # setdefault() function
      fruits = {"banana": 2, "apple": 4}
      fruits.setdefault("apple", 0)
      print(fruits)
      # {'banana': 2, 'apple': 4}
    
  • Example 3

      # setdefault() function
      fruits = {"banana": 2}
      fruits["apple"] += 10
      print(fruits)
      # KeyError: 'apple'
    
  • Example 4

      # setdefault() function
      fruits = {"banana": 2}
      fruits.setdefault("apple", 0)
      fruits["apple"] += 10
      print(fruits)
      # {'banana': 2, 'apple': 10}
    

Get a value via a key

  • Method 1

      # access value via key
      fruits = {"banana": 2, "apple": 4}
      print(fruits["apple"])
      print(fruits["corn"])
      # 4
      # KeyError: 'corn'
    
  • Method 2

      # access value via key
      fruits = {"banana": 2, "apple": 4}
      print(fruits.get("apple"))
      print(fruits.get("corn"))
      # 4
      # None
    
  • Merge two dictionaries

      # merge two dicts
      fruits = {"banana": 2, "apple": 4}
      cereal = {"rice": 3, "corn": 7}
      result = {**fruits, **cereal}
      print(result)
      # {'banana': 2, 'apple': 4, 'rice': 3, 'corn': 7}
    
  • Check if a key exists

      # check if a key exists
      fruits = {"banana": 2, "apple": 4}
      print("apple" in fruits)
      print("corn" in fruits)
      # True
      # False
    
  • Remove empty items

      # remove empty items
      fruits = {"banana": 2, "apple": None}
      dict1 = {key: value for (key, value) in fruits.items() if value is not None}
      print(dict1)
      # {'banana': 2}
    
  • Dictionary comprehension

      # dic comprehension
      aDict = {str(i): i for i in range(5)}
      print(aDict)
      # {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4}
    

Conclusion

In conclusion, understanding the various data structures in Python, such as tuples, sets, and dictionaries, is crucial for efficient data management and manipulation. Each data structure has its unique properties and use cases.

Tuples are immutable and can be used as keys in dictionaries, making them suitable for configurations and ensuring data integrity.

Sets are ideal for operations involving unique elements and provide efficient methods for set operations like union and intersection.

Dictionaries offer a flexible way to store key-value pairs, allowing for fast lookups and data retrieval. By mastering these data structures, you can write more efficient and effective Python code, tailored to the specific needs of your applications.

Reference source (original document): Documents/2025-5/M01W02 - [v2] Advanced Data Structure (IoU, NMS, and Histogram)/AIO2025_AdvancedDataStructure_v2.pdf

0
Subscribe to my newsletter

Read articles from Quang Trịnh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Quang Trịnh
Quang Trịnh