Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
36: Tuples and Immutability
A few years ago, I was reviewing a pull request for a logistics project where a junior dev was handling GPS coordinates. They were using lists to store the (latitude, longitude) pairs for a set of delivery waypoints. It seemed fine at first, but a few weeks later, we hit a bug that was a nightmare to track down. A helper function, designed to calculate distance, was accidentally modifying the longitude of the original waypoint list using an index assignment. Because lists are mutable, the coordinates were changing silently in the background, and suddenly our trucks were being routed into the middle of the Atlantic Ocean.
That's the exact moment where you realize that "being able to change things" isn't always a feature—sometimes, it's a liability. This is why we have tuples.
The Guardrails of Immutability
On the surface, a tuple looks like a list that uses parentheses () instead of square brackets []. But the fundamental difference is that tuples are immutable. Once you define a tuple, you cannot add, remove, or change its elements. If you try to assign a new value to an index, Python will throw a TypeError immediately.
# This is a list (Mutable)
coordinates_list = [40.7128, -74.0060]
coordinates_list[0] = 40.7306 # Works perfectly fine
# This is a tuple (Immutable)
coordinates_tuple = (40.7128, -74.0060)
coordinates_tuple[0] = 40.7306 # Raises TypeError: 'tuple' object does not support item assignment
I like to think of tuples as a way of signaling intent. When I see a tuple in a codebase, I know that the developer intended for that data to remain constant throughout its lifecycle. It's a contract that prevents the "Atlantic Ocean" bug I mentioned earlier.
Unpacking and Returning Multiple Values
One of the most "Pythonic" uses of tuples is unpacking. You've probably seen functions that return more than one value; in reality, Python is actually returning a single tuple, which you can then "unpack" into individual variables in one line.
def get_user_stats():
# Simulating a database call
return ("Alice", 2500, "Gold") # Returning a tuple
# Unpacking the tuple directly into variables
username, score, rank = get_user_stats()
print(f"{username} has a score of {score} and is ranked {rank}.")
This is significantly cleaner than accessing indices like stats[0] and stats[1], which makes the code harder to read and maintain. If you only need some of the values, I usually recommend using an underscore _ for the ones you intend to ignore, which tells other engineers that the omission is intentional.
Tuples as Dictionary Keys
Here is a technical detail that often trips people up: because tuples are immutable, they are "hashable." This means you can use a tuple as a key in a dictionary, whereas a list would cause a TypeError.
Imagine you're building a grid-based game. You can't use a list [x, y] as a key to store what's at that position, but a tuple (x, y) works perfectly. This allows you to map specific coordinate pairs to values without worrying that the coordinates will change and "lose" the reference in your dictionary.
📋 Practical Task
Exercise: Implementing a Fixed-Coordinate Route Guard
You are building a navigation system for a drone. The drone has a set of "No-Fly Zone" centers that must never be altered during the program's execution. If these coordinates were changed, the drone could accidentally enter restricted airspace.
Your Task:
- Create a list of tuples called
NO_FLY_ZONES. Each tuple should contain two floats representing(latitude, longitude). Add at least three different zones. - Write a function called
check_proximity(current_location, zones).current_locationshould be a tuple.- The function should loop through the
zonesand print "Warning: Near Restricted Airspace!" if thecurrent_locationmatches any of the tuples in theNO_FLY_ZONESlist exactly.
- Inside your script, intentionally try to change the latitude of the first No-Fly Zone (e.g.,
NO_FLY_ZONES[0][0] = 12.34) and wrap this in atry/exceptblock to catch theTypeError, printing a message that confirms the data is protected.
There are no comments for now.