“Use a tuple because it is faster.”
That advice sounds confident until someone asks the question that actually matters: Will this data change?

You are working on a small portfolio project after a community-college class, at a public library, or at home on a Windows laptop. Your program stores a list of tasks, a few fixed settings, and the coordinates of a result. A tutorial tells you that tuples are faster than lists, so you replace every pair of brackets with parentheses. The code still runs. But now you have made some data harder to update without solving the problem your program actually has.
Lists and tuples are both Python sequences. They support indexing, slicing, and iteration. The useful distinction for a beginner is not a universal speed ranking. It is whether the collection is expected to change and what the choice communicates to the next person reading the code.
First review question: what is allowed to change?
Start with two versions of the same information:
study_topics = ["variables", "loops", "functions"]
fixed_coordinates = (40.7128, -74.0060)The list represents a sequence that could grow as your study plan changes. The tuple represents a pair of values that belong together and should not be reassigned item by item in this example. The values are hypothetical data; the coordinate is used only to illustrate a fixed pair.
The official Python tutorial documents list methods such as append(), insert(), remove(), and sort(). Lists are built for changing their contents.
study_topics = ["variables", "loops", "functions"]
study_topics.append("testing")
study_topics.remove("loops")
print(study_topics)Output:
['variables', 'functions', 'testing']A tuple does not support item assignment:
fixed_coordinates = (40.7128, -74.0060)
fixed_coordinates[0] = 40.7306Python raises a TypeError because a tuple is immutable. The Python tutorial shows this behavior and explains that tuples cannot have individual items reassigned.
That error is not automatically a disadvantage. It can be useful feedback. If the coordinates are meant to stay together for the life of the calculation, an accidental assignment should be rejected rather than silently changing the record.
Second review question: is this a changing collection or a fixed record?
A list often represents a group of similar items that the program will process or update:
open_tasks = [
"read the error message",
"rewrite the function",
]
open_tasks.append("run the test")
print(open_tasks)A tuple often represents a small fixed group of values that are accessed together:
screen_size = (1920, 1080)
width, height = screen_size
print(f"Width: {width}")
print(f"Height: {height}")This is a useful design conversation in a beginner project. If your code will add or remove tasks, a list describes that life cycle. If a value is a pair of dimensions, a coordinate, or a fixed return shape, a tuple may describe the intention more clearly.
Neither choice makes the program automatically professional. The point is to make the data’s expected behavior visible.
What both types let you do
Lists and tuples are both sequences. You can access positions and slices in the same general way:
list_version = ["draft", "review", "publish"]
tuple_version = ("draft", "review", "publish")
print(list_version[0])
print(tuple_version[0])
print(list_version[1:])
print(tuple_version[1:])Output:
draft
draft
['review', 'publish']
('review', 'publish')The outer type of the slice remains different. A list slice returns a list; a tuple slice returns a tuple. The Python sequence documentation describes common operations shared by lists and tuples, including indexing, slicing, membership testing, and iteration.
That common behavior is why beginners can sometimes use either type at first. The choice becomes important when the program or another reader needs to know whether reassignment is part of the design.
A code-review conversation about a portfolio project
Imagine a reviewer looking at this code:
project_steps = ("plan", "build", "test")
project_steps += ("document",)
print(project_steps)The code works because it creates a new tuple and binds the name project_steps to it. It does not change the original tuple in place. A reviewer might ask:
Are these steps fixed, or will the project add and remove steps as work changes?
If the answer is “the workflow changes during the project,” a list is probably clearer:
project_steps = ["plan", "build", "test"]
project_steps.append("document")
print(project_steps)If the answer is “this is a fixed sequence used as a constant example,” the tuple can communicate that intention. The important thing is that the type matches the expected life cycle instead of being selected from an isolated performance claim.
If you are working through a class assignment or building a first GitHub project, this is also a documentation decision. A future reader should not have to guess whether changing the collection is expected or a bug.
Do not use mutability as a promise of complete safety
A tuple cannot reassign its own items, but it can contain a mutable object such as a list:
project = ("Vandutz practice", ["lists", "tuples"])
project[1].append("testing")
print(project)Output:
('Vandutz practice', ['lists', 'tuples', 'testing'])The tuple still contains the same list object, and that list can change. The official tutorial calls out this distinction: tuples are immutable, but they can contain mutable objects.
This is why “tuples are immutable” should not be expanded into “everything inside a tuple can never change.” When the distinction matters, describe both levels: the tuple’s positions cannot be reassigned, but a contained list may still be modified.
When does the performance claim matter?
Lists and tuples have different implementations and behaviors, but “tuples are faster” is not a complete decision rule. The actual effect depends on the operation, data size, program, Python implementation, and measurement method. A beginner should not change a working data model merely to pursue an unmeasured speed claim.
If performance is genuinely the problem, create a small benchmark that represents your workload. For ordinary beginner code, the clearer question is usually whether the data should be modified and whether the type makes that intention obvious.
A code review that says “this is a tuple because the values are fixed” is more useful than one that says “this is a tuple because tuples are faster.” The first explanation describes the program. The second may be true in some narrow measurement and irrelevant to the decision.
Why hashability appears in this discussion
You may hear that tuples can be used as dictionary keys while lists cannot. The reason is related to hashability, not a general ranking of data structures.
locations = {
(40.7128, -74.0060): "New York example",
(41.8781, -87.6298): "Chicago example",
}
print(locations[(40.7128, -74.0060)])Output:
New York exampleA list cannot be used as a dictionary key:
locations = {
[40.7128, -74.0060]: "New York example"
}This raises TypeError: unhashable type: 'list'. The Python documentation explains that immutable sequences such as tuples can support hashing, but a tuple containing an unhashable value cannot be hashed.
valid_key = ("language", "Python")
print(hash(valid_key))
invalid_key = (["language"], "Python")
print(hash(invalid_key))The first value can be hashed. The second cannot because it contains a list. You do not need to memorize this as a slogan. Ask what the dictionary key must represent and whether every part of it is stable enough to support that role.
Three situations: choose and explain
Imagine that a classmate asks you to choose a structure for each case. There is no universal answer without knowing the intended behavior, but these are reasonable starting points:
| Situation | Likely starting choice | Reason to verify |
|---|---|---|
| A queue of tasks that grows as the project changes | List | The contents are expected to be added, removed, or reordered. |
| A width-and-height pair returned by a calculation | Tuple | The two values form one fixed record for the caller. |
| A set of values used as dictionary-key components | Tuple, if all contents are hashable | The key must be stable and hashable; test the actual contents. |
| A collection that should never change, but contains nested lists | Review carefully | The outer tuple does not make nested lists immutable. |
The table is a starting point, not a replacement for understanding the data. If the first situation later becomes a fixed snapshot that is passed around without modification, the design may change. If the second situation needs named fields and validation, another structure may be more expressive.
The beginner’s answer should survive a review
If a teammate or instructor asks “Why a tuple here?”, try to answer with the data’s behavior:
- “This list changes as the user adds tasks.”
- “This tuple is a fixed pair returned by the calculation.”
- “This tuple is used as a dictionary key, and all of its contents are hashable.”
- “The tuple prevents item reassignment, but the nested list is still intentionally mutable.”
Those answers are stronger than “I read that tuples are faster.” They give another person something they can check in the code.
That habit is relevant beyond a classroom. The U.S. Bureau of Labor Statistics describes software developers as designing applications and QA analysts and testers as identifying problems and reporting defects. Choosing a data structure does not guarantee employment and is not a substitute for broader training. It does give a beginner a small opportunity to practice explaining a design choice and checking whether the implementation matches the requirement.
A final review exercise
Read these three declarations and write one sentence explaining each choice before running the code:
weekly_tasks = ["study", "practice", "review"]
resolution = (1920, 1080)
cache_key = ("python", "lists", 205)A reasonable explanation would be:
weekly_tasksis a list because the schedule may change.resolutionis a tuple because the width and height form a fixed pair in this example.cache_keyis a tuple because its stable, hashable components can identify one stored result.
Now change the requirements. If tasks can no longer be added, or if a resolution must be edited frequently, would the type still communicate the right behavior? Good Python design is not about defending the first choice forever. It is about making the choice easy to revisit when the requirements change.
Use this decision before you choose
- Will the contents change? Start with a list when the program needs to add, remove, or reorder items.
- Does the data represent a fixed group? Consider a tuple when the positions and values should travel together without item reassignment.
- Will it be a dictionary key or set element? Check hashability of every nested value instead of assuming every tuple works.
- Are you choosing for a measured performance problem? Benchmark the real operation before changing a clear design.
- Can you explain the choice in one sentence? If not, inspect the requirement again.
Lists and tuples are not competing winners in every situation. A list usually describes a changing collection. A tuple usually describes an immutable sequence or fixed record. The better choice is the one that tells the truth about how the data will be used, makes mistakes visible, and gives the next reader a reason they can verify.
For the loops that process these collections, continue with the Python for loop guide. When the same data rule needs to be reused, see the Python functions guide. For dictionary-key behavior and related errors, continue with the Python dictionaries guide.

Alex Carter is the editorial name behind Vandutz Academy, a programming blog for beginners. Alex reviews and tests the examples and explanations published on the site, with a focus on making Python, JavaScript, web development, and developer tools easier to understand.