Data structures is a format that is used for organizing, managing, and storing data in computer's memory so that it can be accessed and modified efficiently. Data structures act as containers that hold multiple values at once. Choosing the right data structure affects how fast your program runs, how much memory it uses, and how readable the code is.
Python has four highly optimized built-in data structures: lists, dictionaries, tuples and sets.
List([])
A list is an ordered collection that can hold items of any type, and it can grow, shrink, or be modified after creation. It is mainly used to store items where order matters, and you expect to add, remove or change items over time.
Example of a list
shopping_list = ['Bread','Sugar','Rice','Milk']
print(shopping_list) # ['Bread','Sugar','Rice','Milk']
Indexing a List
A list can be accessed using an index which is its position number. List indexing is zero-based, meaning the first item on the list is at index 0, then second item is at index 1. Python also supports negative indexing to count backward from the end of the list.
shopping_list = ['Bread','Sugar','Rice','Milk']
# pos indexing 0 1 2 3
# neg indexing -4 -3 -2 -1
Positive indexing
Starts at 0 from the left side
shopping_list = ['Bread','Sugar','Rice','Milk']
print(shopping_list[0]) # 'Bread' (first item)
print(shopping_list[1]) # 'Sugar' (second item)
Negative indexing
Starts at -1 from the right side. This is perfect when you want the item but you do not know how long the list is.
shopping_list = ['Bread','Sugar','Rice','Milk']
print(shopping_list[-1]) # 'Milk' (last item)
print(shopping_list[-2]) # 'Rice' ( second-last-item)
Changing an item by index
shopping_list = ['Bread','Sugar','Rice','Milk']
shopping_list[3] = 'Fresh Milk'
shopping_list[1] = 'Honey'
print(shopping_list) # ['Bread','Honey','Rice','Fresh Milk']
Slicing a list
List slicing is the technique used to extract a subset of a list instead of just a single item. Slicing uses the syntax list[start:stop:step].It creates a brand new list without altering the original list.
Slicing parameters
start- the index where the slice begins(this item is included)stop- the index where the slice ends( this item is not included)step- this is optional it determines the increment, i.e a step of 2 skips every other item.There are some shortcuts used, if you leave a parameter blank, Python assumes you mean the very beginning or the end.
Example of slicing
numbers = [10, 20, 30, 40, 50, 60, 70, 80, 90]
# 0 1 2 3 4 5 6 7 8
print(numbers[1:4]) # [20, 30, 40]
print(numbers[:3]) # [10, 20, 30]
print(numbers[4:]) # [50, 60, 70, 80, 90]
print(numbers[::2]) #every 2nd item [10, 30, 50, 70, 90]
print(numbers[::-1]) # from the last item to the first
List Methods
List methods are built-in functions that allow one to manipulate, modify, or search lists directly.
Let's assume we start with an initial list :
students = ['Amos','Faith','Wanjiku','Brian','Kevin']
Adding Items
-
.append(item)- adds a single item to the end of the list.
students.append('Dennis')
print(students) # ['Amos','Faith','Wanjiku','Brian','Kevin','Dennis']
-
.extend(items)- used to add multiple items or append all items from another list.
students.extend(['Peter','Mercy'])
print(students)# ['Amos','Faith','Wanjiku','Brian','Kevin','Dennis','Peter','Mercy']
-
insert(index,item)- inserts an item at a specific position, shifting everything to the right.
students.insert(1, 'Grace')
print(students) # ['Amos','Grace','Faith','Wanjiku','Brian','Kevin','Dennis','Peter','Mercy']
Removing Items
-
.pop(index)- removes and returns the item at the given index. if no index is provided, it removes the very last item.
print(students.pop(0)) # removes and returns 'Amos'
print(students.pop()) # removes and returns 'Mercy'
-
.remove(item)- searches the first occurrence of a specific value and deletes it. Throws aValueErrorif the value is not there.
students.remove('Brian')
print(students) # removes 'Brian' from the list
-
del- this is a python keyword that deletes an item by its index position. Del can delete multiple items using slices and it raises anIndexErrorif the index does not exist.
del students[:3]
print(students) # removes from start up to position 3 'Grace', 'Faith', 'Wanjiku
-
.clear()- removes all items leaving the list empty.
students.clear()
print(students) # []
Ordering a list
-
.sort- sorts items of the list in place(ascending by default, alphabetically for strings, ascending for numbers). Setreverse=Trueto sort descending.
numbers = [3,1,7,4,9,5]
numbers.sort()
print(numbers) # [1,3,4,5,7,9]
numbers = [3,1,7,4,9,5]
numbers.sort(reverse=True)
print(numbers) # [9,7,5,4,3,1]
The list can also be sorted by the length of the characters in strings.
students = ['Amos','Wanjiku','Faith','Dennis']
students.sort(key=len)
print(students) # ['Amos','Faith','Dennis','Wanjiku']
-
.reverse()- reverses the order of items in the list in place.
numbers.reverse()
print(numbers) # [5,9,4,7,1,3]
-
.copy()- returns a backup copy of the list incase you remove the wrong item, there is another list.
numbers_backup = numbers.copy() # creates a shallow copy.
Tuples (())
A tuple looks like a list but is immutable meaning once created it cannot be modified. This makes tuples slightly faster than lists and safer to use when you want to guarantee the data won't change.
Tuples is used for fixed collections of related values, like coordinates, RGB colors, or function return values.
Example of a tuple
student = ('Njeri',19,'Kisumu')
name,age,city = student # unpacking the tuple
print(f"{name} is {age} years old, from {city}") # Njeri is 19 years old, from Kisumu
Accessing & Slicing Tuples
Tuples supports indexing and slicing.
print(student[0]) # 'Njeri' indexing
print(student[:1]) # ('Njeri', 19) slicing
Immutability - tuples cannot change
students[1] = 25 # CRASH! tuples can't be modified.
Dictionaries ({key: value})
A dictionary stores data as key-value pairs, giving instant lookups by key. It is used to store structured database records, caching and JSON data handling. Use dictionary when you need to look things up by a meaningful key rather than the numeric position like mapping usernames to profiles.
Example of a dictionary
contacts = {'Amina': '0712345678','Bob':'0798765432','Faith': '0799404040'}
Accessing Data
Use square brackets [] to enclose the key that needs to be fetched.
print(contacts['Amina']) # 0712345678
Use .get() to fetch if you are not sure the key exists. It will return None if the key is missing.
print(contacts.get('Brian')) # None
print(contacts.get('Bob')) # 0798765432
Adding & Updating Data
contacts['Njeri'] = '0700111122' # adds a new key
contacts['Amina'] = '0711000000' # updates an existing key
Removing Data
-
del dict[key]- deletes the key-value pair entirely.
del contacts['Amina'] # removes 'Amina': '0711000000'
-
.pop(key)- removes the key and returns its value.
contacts.pop('Faith') #removes 'Faith' and returns '0799404040'
-
.clear()- empties the entire dictionary.
contacts.clear() # {}
Looping through Dictionaries
Dictionaries can be iterated through keys, values, or both at the same time.
prices = {'Sugar': 150, 'Rice': 180, 'Milk': 65, 'Bread': 120}
# loop through the keys only
for key in prices:
print(key)
# loop through the values only
for value in prices.value():
print(value)
# loop through both keys and values using .items()
for key, value in prices.items():
print(f"{key} is {value}")
Dictionary Methods
-
keys()- returns a list-like view of all keys.
prices.keys() #['Sugar','Rice','Milk','Bread']
-
.values()- returns a list-like view of all values.
prices.values() # [150,180,65,120]
-
.items()- returns a view of all key-value tuples.
prices.items() # [('Sugar',150), ('Rice',180),('Milk', 65), ('Bread',120)]
Sets ({})
A set stores unique, unordered items. Duplicates are automatically discarded, and sets are optimized for fast membership tests. Sets support mathematical operations, which is useful for comparing collections.
# creating an empty set
empty_set = set()
routes = {'Route 46','Route 34','Route 46','Route 11','Route 11'}
print(routes) # {'Route 34','Route 46','Route 11'} # remove duplicates
Modifying a Set
.add(item)- adds a single item..remove(item)- removes a specific item. Crashes with aKeyErrorif the item is missing..discard(item)- safely removes an item. If the item does not exist, it does not crash.
routes = {'Route 46','Route 34'}
routes.add('Route 11') # {'Route 46','Route 34','Route 11'}
routes.remove('Route 34') # {'Route 46','Route 11'}
route.add('Route 46') # does nothing , 'Route 46' already exists.
route.discard('Route 55') # does nothing because 'Route 55' does not exist (it does not crash)
'Route 46' in routes # True - fast lookup in sets.
Mathematical Operations
Sets in python are optimized for mathematical set operations, which are useful in programming.
a = {1, 2, 3}
b = {2, 3, 4}
# union(|) - combines elements from both sides
print(a | b) # {1,2,3,4}
# intersection(&) - finds items present in both sets
print(a & b) # {2,3}
# difference(-) - finds items in `a` that are not in `b`
print(a - b) # {1}
# symmetric difference(^) - finds items that are in one of the sets not both
print(a ^ b) # {1,4}
Quick Comparison
| Structure | Ordered | Mutable | Duplicates | Access by |
|---|---|---|---|---|
| List | Yes | Yes | Allowed | Index |
| Tuple | Yes | No | Allowed | Index |
| Dictionary | No | Yes | Unique Keys | Key |
| Set | No | Yes | Not Allowed | Membership |
Comprehensions
Comprehensions in Python are a concise, elegant way to create new collections (lists, dictionaries, or sets) from existing iterables in a single line of code. they are not a separate data structures, they are just fast, readable way to build the ones above.
Syntax:[expression for item in iterable if condition]
squares = [n 2 for n in range(6)]
# [0, 1, 4, 9, 16, 25]
# adding if filter
evens_only = [n for n in range(10) if n % 2 == 0]
# [0, 2, 4, 6, 8]
square_map = {n: n 2 for n in range(5)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# dictionaries
unique_lengths = {len(word) for word in ["hi", "hey", "hello", "yo"]}
# {2, 3, 5}
Conclusion
Most Python programs are lists, tuples, dictionaries and sets working together, understanding strengths of each one is often valuable than knowing advanced syntax. As a general rule: reach for a list when order and flexibility matter, a tuple when the data shouldn't change, a dictionary when you need fast lookups by a meaningful key, and a set when uniqueness or fast membership checks matter most. Getting this choice right early on tends to make the rest of your code simpler.
Top comments (0)