Python - Data Structures: Lists, Tuples, Sets, and Dictionary

Software Engineer
A Data structure is a way to organize and group data for easy access.
Types of Data Structures
List
A list is an ordered collection of data. A list is created using square brackets. Lists might contain items of different types but they have the same type. Lists are mutable i.e., you can change their content.
# Creating a list
my_list1 = []
my_list2 = [1, 2, 3, 4, 5]
my_list3 = [1, 1, 'b', 'd', 5]
Items in a list are usually zero-indexed meaning you start from the index 0.
This is useful in accessing items in a list. For example:
my_list = [1, 2, 3, 4, 5]
# Get the first item in the list
print(my_list[0]) # output: 1
You can also access elements in a list from the last element. To do this you can use a negative index. For example:
my_list = [1, 2, 3, 4, 5]
# Access the last element
print(my_list[-1]) # output: 5
print(my_list[-3]) # output: 3
To access the other elements from the last we incremented the index from -1.
Slicing with lists
Slicing enables us to access a wide range of elements in a list. When using slicing it is important to remember that the start index is inclusive and the stop index is exclusive.
Syntax
The colon : operator is used in slicing.
my_list[start: stop: step]
Example:
my_list = [1, 1, 2 ,3, 5, 8]
print(my_list[2:4:1]) # output [2, 3]
In the above example the item on the index 2 is included while the time on the index 4 is excluded.
Leaving one of the values in slicing results in it using the default value which is 0.
Example:
my_list = [1, 1, 2, 3, 5, 8]
print(my_list[:4]) # output [1, 1, 2, 3]
print(my_list[4:]) # output [5, 8]
print(my_list[::] # output [1, 1, 2, 3, 5, 8]
You can also use slicing to reverse a list. You can just use a negative index in the step argument.
Example:
my_list = [1, 1, 2, 3, 5, 8]
print(my_list[::-1]) # output [8, 5, 3, 2, 1]
print(my_list[::-3]) # output [8, 1]
print(my_list[:1:-2]) # output [8, 3]
Note: When the step is negative it starts from the back moving forward. When it is
-2, it simply means2steps.
You can add items to a list using the list.append() method.
my_list = [1, 1, 2, 3, 5, 8]
my_list.append(12)
print(my_list) # output [1, 1, 2, 3, 5, 8]
Since lists are mutable you can change the values by using the index and the value to be replaced with.
my_list = [1, 1, 2, 3, 5, 8, 12]
my_list [6] = 13
print(my_list) # output [1, 1, 2, 3, 5, 8, 13]
List Comprehensions
List comprehensions are an easy way to create lists. To understand this we will create a list of cubes using a for loop.
Syntax
my_list = [expression for item in list]
cubes = []
for i in range(10)
cubes.append(i**3)
print(cubes)
# output: [0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
This can be done using list comprehensions using only one line. Let's convert that to use a list comprehension:
cubes = [i**3 for i in range(10)]
print(cubes)
# output: [0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
Tuples
Tuples consist of a number of values separated by commas. A tuple is immutable meaning it cannot be changed. To create a tuple you can use the parenthesis ().
# Creates an empty tuple
my_tuple = ()
# Creates a tuple with one element
my_tuple1 = (1,)
Note When creating a tuple with one element you have to add a comma after the eleement for it to be interpreted as a tuple.
In some cases a tuple may not have the parenthesis
().
Items in a tuple are accessed through unpacking or indexing. By using unpacking you can assign data to multiple variables without having to access them one by one and make multiple assignment statements.
Example:
length, width, height = 10, 20, 30
print("The dimensions are {} x {} x {}".format(length, width, height))
# output: The dimensions are 10 x 20 x 30
Sets
A set is an unordered data structure that is used to store unique elements. You can use curly braces {} or set() to create a set with the items separated by a comma.
my_set = {"alpha", "beta", "omega", "omega"}
print(my_set) # output {'alpha', 'beta', 'omega'}
Note: An empty set is created using the
set()not{}
Set objects also support mathematical operations like union, intersection, difference and symmetric difference.
# Demonstrate set operatrions
a = set('caracteres')
b = set('alakazam')
# Union
print(a | b) # letters in or b and both
# output: {'s', 'm', 'z', 'c', 'e', 'r', 't', 'a', 'l', 'k'}
# Intersection
print(a & b) # letters in a and b
# output: {'a'}
# Difference
print(a - b) # letters in a but not in b
# output: {'s', 'c', 'r', 't', 'e'}
# Symmetric difference
print(a ^ b) # letters in a or b but not both
# output: {'s', 'k', 'l', 'z', 'm', 'c', 'r', 't', 'e'}
Dictionary
A dictionary is a mutable data type that stores key-value pairs. The keys are unique within the dictionary. A dictionary is created using a pair of curly braces {} then you can add a comma-separated key:value pairs to the dictionary.
# Simple dictionary
person = {'name': 'John Doe', 'age': 20, 'city': 'New York'}
print(person)
#output: {'name': 'John Doe', 'age': 20, 'city': 'New York'}
Accessing values using keys
person = {'name': 'John Doe', 'age': 20, 'city': 'New York'}
# Accessing values using keys
print(person["name"]) # output: John Doe
print(person["age"]) # output: 20
Adding and updating entries
person = {'name': 'John Doe', 'age': 20, 'city': 'New York'}
# Adding and updating entries
person["email"] = "john.doe@example.com" # Adding a new key-value pair
person["age"] = 21 # Updating the value of an existing key
Removing entries
Remove entries using del or pop:
person = {'name': 'John Doe', 'age': 21, 'city': 'New York', 'email': 'john.doe@example.com'}
del person["city"] # Remove key-value pairs with the key 'city'
print(person)
# output: {'name': 'John Doe', 'age': 21, 'email': 'john.doe@example.com'}
email = person.pop("email") # Remove the key-value pair with key "email" and return its value
print(person) # output: {'name': 'John Doe', 'age': 21}
print(email) # output: john.doe@example.com
Looping through a dictionary
person = {'name': 'John Doe', 'age': 21}
# Looping through keys
for key in person:
print(key, person[key])
# output: name John Doe
# age 21
# Looping through values
for value in person.values():
print(values)
# output: John Doe
# 21
# Looping through key-value pairs
for key in person.items():
print(key, value)
# output: John Doe
# 21
Dictionary methods
person = {'name': 'John Doe', 'age': 21}
# Get the value for a key, with a default if the key is not present
age = person.get("age", "Not specified")
print(age) # Output: 21
# Get a list of keys
keys = person.keys()
print(keys) # dict_keys(['name', 'age'])
# Get a list of values
values = person.values()
print(values) # dict_values(['John Doe', 21])
# Get a list of key-value pairs
items = person.items()
print(items) # dict_items([('name', 'John Doe'), ('age', 21)])
Dictionary comprehensions
squares = {x: x*x for x in range(1, 6)}
print(squares) # Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Having a strong foundation in data structures is essential in programming as it helps in solving harder problems and in creating, accessing, and manipulating data in complex systems.



