Intermediate Python Programming Applications
Advanced Data Structures
Beyond Basic Lists and Dictionaries
You already know how to store data in Python lists and dictionaries. Now, let's explore more powerful ways to work with them. We'll also cover two other essential built-in data structures: sets and tuples. Choosing the right data structure is crucial for writing clean, efficient, and readable code. It's the difference between a program that works and a program that works well.
Concise Code with List Comprehensions
Imagine you need to create a list of the first ten perfect squares. You could use a standard for loop:
squares = []
for i in range(10):
squares.append(i * i)
# squares is now [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
This works perfectly fine, but it takes up three lines. Python offers a more compact and often more readable alternative called for creating lists from other sequences. Here is the same logic in a single line:
squares = [i * i for i in range(10)]
The structure is:
[expression for item in iterable].
You can also add a condition to filter the items. Let's create a list of squares for only the even numbers.
even_squares = [i * i for i in range(10) if i % 2 == 0]
# even_squares is now [0, 4, 16, 36, 64]
Specialized Tools: Sets and Tuples
Lists are general-purpose, but sometimes you need a more specialized tool. That's where sets and tuples come in.
A set is an unordered collection of unique elements. They are perfect for two main jobs: removing duplicate values from a list and testing for membership (i.e., checking if an item is in the collection).
numbers = [1, 2, 2, 3, 4, 4, 4, 5]
unique_numbers = set(numbers)
# unique_numbers is {1, 2, 3, 4, 5}
print(3 in unique_numbers) # Outputs: True, and it's very fast!
Sets also support powerful mathematical operations like union, intersection, and difference. Only objects that are can be stored in a set, which means their value cannot change during their lifetime. This includes numbers, strings, and tuples, but not lists or dictionaries.
A tuple, on the other hand, is an ordered, immutable collection. Once you create a tuple, you cannot change, add, or remove its elements. This property, called immutability, makes them ideal for representing fixed data sequences, like coordinates or RGB color values.
# A tuple representing a point in 2D space
point = (10, 20)
# Trying to change an element will raise an error
# point[0] = 15 # TypeError: 'tuple' object does not support item assignment
# Tuples are often used as dictionary keys because they are hashable
locations = {
(35.68, 139.69): "Tokyo",
(40.71, -74.00): "New York"
}
The Collections Module
Python's collections module provides even more specialized container types for when the built-in ones aren't quite enough. Let's look at two of the most useful: namedtuple and deque.
A namedtuple gives you the immutability and memory efficiency of a regular tuple, but with the ability to access elements by name instead of just by index. This makes your code more self-documenting.
from collections import namedtuple
# Define a new namedtuple type called 'Point'
Point = namedtuple('Point', ['x', 'y'])
# Create an instance of it
p1 = Point(10, 20)
# Access elements by name or index
print(p1.x) # Outputs: 10
print(p1[1]) # Outputs: 20
A (pronounced 'deck') stands for 'double-ended queue'. It's like a list but is highly optimized for adding and removing elements from both the front and the back. While appending to the end of a list is fast, adding to the beginning is slow because all other elements must be shifted. A deque solves this problem.
from collections import deque
d = deque(['b', 'c', 'd'])
# Add to the right (like list.append)
d.append('e')
# Add to the left (fast!)
d.appendleft('a')
# d is now deque(['a', 'b', 'c', 'd', 'e'])
# Remove from the right
d.pop()
# Remove from the left
d.popleft()
# d is now deque(['b', 'c', 'd'])
Deques are excellent for implementing queues and stacks, or for keeping a list of the 'last N' items seen.
Ready to test your knowledge?
Which list comprehension correctly creates a list of the squares of odd numbers from 0 to 9?
What are the two primary characteristics of a Python set?
By mastering these advanced data structures, you can write more expressive, efficient, and Pythonic code tailored to the problem at hand.