Easy examples of Python data structures
Is it better to use a list or a dictionary?
Well as always it depends on what you have to do. Python offers a variety of built-in data structures that are fundamental for programming. Understanding these structures will help you write more organized and optimized code. Let’s dive right in.
1. Lists
A list in Python is like an array in other languages but with more flexibility. It’s mutable and it can contain items of different types.
# Initializing a list
my_list = [1, 2, 3, 4, 5]
print("My list:", my_list)
# 1. Accessing elements
print("Accessing the first element:", my_list[0])
# 2. Slicing
print("Slicing from index 1 to 3:", my_list[1:3])
# 3. Length of the list
print("Length of the list:", len(my_list))
# 4. Adding elements
# Append - Adds to the end of the list
my_list.append("car")
print("After append:", my_list)
# Insert - Adds at a specific index
my_list.insert(0, 0)
print("After insert at index 0:", my_list)
# Extend - Adds multiple items at once
my_list.extend([7, 8])
print("After extend:", my_list)
# 5. Removing elements
# Remove - Removes the first occurrence of a value
my_list.remove(3)
print("After removing 3:", my_list)
# Pop - Removes and returns the element at the given index
popped = my_list.pop(2)
print("Popped element at index 2:", popped, "List now:", my_list)
# 6. Checking for membership
print("Is 5 in list?", 5 in my_list)
# 7. Indexing
print("Index of 5:", my_list.index(5))
# 8. Counting occurrences
my_list.append(5)
print("Count of 5:", my_list.count(5))
# 9. Sorting
# We will get TypeError: '<' not supported between instances of 'str' and 'int' if we try to sort a list with int and str so let's remove 'car'
my_list.remove('car')
print("After removing 'car':", my_list)
sorted_list = sorted(my_list) # This creates a new list
print("Sorted list:", sorted_list)
my_list.sort() # This sorts in-place
print("List after in-place sort:", my_list)
# 10. Reversing
my_list.reverse()
print("Reversed list:", my_list)
# 11. Copying
copy_list = my_list.copy()
print("Copied list:", copy_list)
# 12. List comprehension
# Here's an example creating a new list with squares
squares = [x**2 for x in my_list]
print("List comprehension for squares:", squares)
# 13. Clearing the list
my_list.clear()
print("List after clear:", my_list)
# 14. Joining elements into a string
my_list = ['a', 'b', 'c']
joined = ''.join(my_list)
print("Joined string:", joined)
Lists are perfect when you need a sequence where order matters or when you’re dealing with a collection that might change in size. Note that operations like sorted() or copy() create new lists, leaving the original one unchanged.
2. Tuples
Tuples are similar to lists but are immutable. They’re great for representing fixed collections of items.
# Initializing a tuple
my_tuple = (1, 2, 3, 4, 5)
print("My tuple:", my_tuple)
# 1. Accessing elements
print("Accessing the first element:", my_tuple[0])
# 2. Slicing
print("Slicing from index 1 to 3:", my_tuple[1:3])
# 3. Length of the tuple
print("Length of the tuple:", len(my_tuple))
# 4. Counting occurrences
print("Count of 2:", my_tuple.count(2))
# 5. Finding the index of an element
print("Index of 3:", my_tuple.index(3))
# 6. Checking for membership
print("Is 5 in tuple?", 5 in my_tuple)
# 7. Concatenation (creating a new tuple)
new_tuple = my_tuple + (6, 7)
print("After concatenation:", new_tuple)
# 8. Repetition (creating a new tuple)
repeated_tuple = my_tuple * 2
print("After repetition:", repeated_tuple)
# 9. Unpacking
a, b, c, *rest = my_tuple
print("Unpacking:", a, b, c, rest)
# 10. Conversion to list (to perform mutable operations)
list_from_tuple = list(my_tuple)
list_from_tuple.append(6)
print("Converted to list and appended:", list_from_tuple)
# 11. Conversion back to tuple
back_to_tuple = tuple(list_from_tuple)
print("Converted back to tuple:", back_to_tuple)
# 12. Tuple comprehension (in Python, this results in a generator, not a tuple) but we can immediately convert it to a tuple
squared_tuple = tuple(x**2 for x in back_to_tuple)
print("Tuple comprehension for squares:", squared_tuple)
Tuples are good when you need to ensure data integrity, like in functions returning multiple values. As said they are immutable but you can create new tuples from existing ones or convert them to lists for mutable operations.
3. Dictionaries
Dictionaries stores key-value pairs, where keys must be unique, and values can be of any type. They are mutable so you can change to their content.
# Initializing a dictionary
my_dict = {'name': 'Alice', 'age': 30, 'city': 'New York'}
print("My dict:", my_dict)
# 1. Accessing elements
print("Accessing 'name':", my_dict['name'])
# 2. Getting a value with .get() method (safer, returns None if key not found)
print("Getting 'age':", my_dict.get('age'))
print("Getting 'non-existent':", my_dict.get('non-existent', 'Not found'))
# 3. Length of the dictionary
print("Length of dictionary:", len(my_dict))
# 4. Adding or updating an item
my_dict['job'] = 'Data Engineer' # Adding a new key-value pair
my_dict['age'] = 31 # Updating an existing key
print("After adding 'job' and updating 'age':", my_dict)
# 5. Removing items
# pop() removes the item and returns its value
removed_value = my_dict.pop('city')
print("Removed 'city':", removed_value, "Dictionary now:", my_dict)
# popitem() removes and returns the last inserted key-value pair
last_item = my_dict.popitem()
print("Popped last item:", last_item, "Dictionary now:", my_dict)
# del keyword can also remove a key
del my_dict['age']
print("After deleting 'age':", my_dict)
# 6. Checking for key existence
print("Is 'name' in dictionary?", 'name' in my_dict)
# 7. Keys, Values, and Items methods
print("Keys:", my_dict.keys())
print("Values:", my_dict.values())
print("Items:", my_dict.items())
# 8. Updating dictionary with another dictionary
my_dict.update({'city': 'San Francisco', 'job': 'Data Scientist'})
print("After update:", my_dict)
# 9. Clearing the dictionary
my_dict.clear()
print("After clear:", my_dict)
# 10. Dictionary comprehension
new_dict = {x: x**2 for x in range(5)}
print("Dictionary comprehension for squares:", new_dict)
# 11. Nested dictionaries
nested_dict = {'person': {'name': 'Bob', 'age': 25}, 'location': {'city': 'Paris'}}
print("My nested dict:", nested_dict)
print("Nested dictionary access:", nested_dict['person']['name'])
# 12. Merging dictionaries
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
merged_dict = dict1 | dict2 # Merges, dict2's 'b' overwrites dict1's
print("Dict 1:", dict1, "Dict 2:", dict2, "Merged dict:", merged_dict)
# 13. Copying
# Shallow copy
# Ok for not nested dictionaries
copy_dict1 = dict1.copy()
print("Copied dict1:", copy_dict1)
dict1['a'] = 2
print("Original dict1 after update:", dict1)
print("Copied dict1:", copy_dict1)
# Not ok for nested dictionaries
copy_nested_dict = nested_dict.copy()
print("Copied dict:", copy_nested_dict)
nested_dict['person']['name'] = 'Alice'
print("Original dict after update:", nested_dict)
print("Copied dict:", copy_nested_dict)
# Deep copy
import copy
deep_nested_dict = copy.deepcopy(nested_dict)
print("Deep copied dict:", deep_nested_dict)
nested_dict['person']['name'] = 'James'
print("Original dict after update:", nested_dict)
print("Deep copied dict:", deep_nested_dict)
Dictionaries are good when you need fast lookups by key, which is particularly useful for configuration settings or caching. Note that when you are working with nested dictionaries you need copy.deepcopy() to have an actual copy of your dictionary.
4. Sets
Sets in Python are collections of unique, unordered elements. They’re useful for operations like union, intersection, or when you need to eliminate duplicate values from a list.
# Initializing a set
my_set = {1, 2, 3, 4, 5}
print("My set:", my_set)
# 1. Adding elements
my_set.add(6)
print("After adding 6:", my_set)
# 2. Removing elements
# remove() - raises KeyError if the element is not found
my_set.remove(4)
print("After removing 4:", my_set)
# discard() - does nothing if the element is not found
my_set.discard(4) # This won't raise an error since 4 is already removed
print("After discarding 4 (which was already removed):", my_set)
# pop() - removes and returns an arbitrary element
popped = my_set.pop()
print("Popped element:", popped, "Set now:", my_set)
# 3. Length of the set
print("Length of the set:", len(my_set))
# 4. Checking for membership
print("Is 2 in set?", 2 in my_set)
# 5. Union of sets
set1 = {1, 2, 3}
set2 = {3, 4, 5}
union_set = set1.union(set2) # or set1 | set2
print("Set 1:", set1, "set 2:", set2, "Union of set1 and set2:", union_set)
# 6. Intersection of sets
intersection_set = set1.intersection(set2) # or set1 & set2
print("Set 1:", set1, "set 2:", set2, "Intersection of set1 and set2:", intersection_set)
# 7. Difference of sets
difference_set = set1.difference(set2) # or set1 - set2
print("Set 1:", set1, "set 2:", set2, "Set1 minus set2:", difference_set)
# 8. Symmetric difference (elements in either set but not in both)
sym_diff_set = set1.symmetric_difference(set2) # or set1 ^ set2
print("Set 1:", set1, "set 2:", set2, "Symmetric difference:", sym_diff_set)
# 9. Updating sets
set1.update(set2) # Adds all items from set2 into set1
print("Set 1:", set1, "set 2:", set2, "Set1 after update:", set1)
# 10. Clearing the set
set1.clear()
print("After clear:", set1)
# 11. Set comprehension
squared_set = {x**2 for x in range(5)}
print("Set comprehension for squares:", squared_set)
# 12. Copying a set
set1 = {1, 2, 3}
copy_set = set1.copy()
print("Copied set:", copy_set)
# 13. Subsets and supersets
set1 = {1, 2, 3}
set2 = {1, 2, 3, 4, 5}
print("Set 1:", set1, "set 2:", set2, "Is set1 subset of set2?", set1.issubset(set2)) # or set1 <= set2
print("Set 1:", set1, "set 2:", set2, "Is set2 superset of set1?", set2.issuperset(set1)) # or set2 >= set1
# 14. Disjoint sets (sets with no common elements)
set3 = {6, 7, 8}
print("Set 1:", set1, "set 2:", set2, "set 3:", set3, "Are set1 and set3 disjoint?", set1.isdisjoint(set3))
Sets are your go-to when you need to check for membership or perform mathematical set operations. Since sets are unordered, you can’t rely on the order of elements or use indexing to access elements.
Conclusion
Each of these data structures serves unique purposes in Python programming. Lists for ordered, changeable items; tuples for fixed collections; dictionaries for key-value mappings; and sets for unique, unordered data. Choosing the right structure can significantly impact your code’s performance and readability.
Outro
I hope the story was interesting and thank you for taking the time to read it. On my Blogspot you can find the same post in Italian. Let me know if you have any question and if you like the content that I create feel free to buy me a coffee.