Advanced Lists and Tuples
In the last lesson, we learned basic list operations. Now let's explore some more "Pythonic" concepts — the thrill of list comprehensions (one line doing the work of five), and tuples (the "immutable list") and when to use them. After this, your code will increasingly look like that of a true Python programmer.
1. Advanced List Sorting
In Lesson 10, we learned the basics of sort() and sorted(). They also accept a key parameter to specify "what rule to sort by."
# Sort by string length
words = ["Python", "Java", "JavaScript", "C", "Go"]
sorted_by_len = sorted(words, key=len)
print(sorted_by_len) # ['C', 'Go', 'Java', 'Python', 'JavaScript']
# Sort by last character
words = ["banana", "apple", "cherry", "date"]
sorted_by_last = sorted(words, key=lambda w: w[-1])
print(sorted_by_last) # ['banana', 'date', 'apple', 'cherry']
# Sort by a specific element in a tuple
scores = [("Zhang San", 85), ("Li Si", 92), ("Wang Wu", 78)]
sorted_scores = sorted(scores, key=lambda s: s[1], reverse=True)
print(sorted_scores) # [('Li Si', 92), ('Zhang San', 85), ('Wang Wu', 78)]
Tip: The
keyparameter is extremely useful — you can pass any function that takes one argument and returns a value.sorted()will use this return value for sorting. Thelambdaabove is an anonymous function, covered in detail later.
Example: Generating a Leaderboard (Difficulty: Star-Star)
# Game leaderboard — sort by score descending
players = [
("Player 1", 3500),
("Player 2", 5200),
("Player 3", 2800),
("Player 4", 4100),
]
# Sort by score descending
ranked = sorted(players, key=lambda p: p[1], reverse=True)
print("=== Leaderboard ===")
for i, (name, score) in enumerate(ranked, 1):
print(f"#{i}: {name} — {score} points")
Output:
=== Leaderboard ===
#1: Player 2 — 5200 points
#2: Player 4 — 4100 points
#3: Player 1 — 3500 points
#4: Player 3 — 2800 points
2. List Comprehensions
List comprehensions are one of Python's most beloved features — generating a new list with a single line of code.
Basic Syntax
[expression for variable in iterable]
Traditional vs. Comprehension
# Generate squares of 0~9 — traditional way
squares = []
for i in range(10):
squares.append(i ** 2)
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# Using list comprehension — one line
squares = [i ** 2 for i in range(10)]
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Comprehension with Conditions
# Filter even numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = [n for n in numbers if n % 2 == 0]
print(evens) # [2, 4, 6, 8, 10]
# Convert strings to uppercase
words = ["hello", "world", "python"]
upper_words = [w.upper() for w in words]
print(upper_words) # ['HELLO', 'WORLD', 'PYTHON']
# Filter words with length >= 5
words = ["cat", "elephant", "dog", "giraffe", "ant"]
long_words = [w for w in words if len(w) >= 5]
print(long_words) # ['elephant', 'giraffe']
Tip: Comprehensions are concise, but don't overuse them. If the logic is complex (e.g., nested loops or multiple conditions), a regular for loop is more readable. Conciseness does not equal readability.
Example: Data Processing (Difficulty: Star-Star)
# Raw data — may contain empty values and extra whitespace
raw_data = [" Zhang San ", "", " Li Si ", " Wang Wu ", "", " Zhao Liu "]
# One-step cleaning with comprehension: strip + filter empty
cleaned = [name.strip() for name in raw_data if name.strip()]
print(cleaned) # ['Zhang San', 'Li Si', 'Wang Wu', 'Zhao Liu']
# Numeric processing
temps_c = [0, 10, 20, 30, 40]
temps_f = [c * 9 / 5 + 32 for c in temps_c]
print(temps_f) # [32.0, 50.0, 68.0, 86.0, 104.0]
3. What is a Tuple
Tuples are defined with parentheses (). They are similar to lists, but with a key difference — tuples are immutable; once created, they cannot be modified.
# Define tuples
point = (3, 5)
color = (255, 0, 0)
empty = ()
single = (42,) # Note: single-element tuples must have a comma!
print(point) # (3, 5)
print(type(point)) # <class 'tuple'>
Tuples are Immutable
point = (3, 5)
# point[0] = 10 ← Error! Tuples cannot be modified
print(point[0]) # 3 — can read, cannot modify
Why Tuples are Needed
Immutability brings two benefits:
1. Can be used as dictionary keys (lists cannot, because they're mutable)
# Tuples can be dictionary keys
locations = {
(35.68, 139.76): "Tokyo",
(31.23, 121.47): "Shanghai",
}
print(locations[(35.68, 139.76)]) # Tokyo
# Lists cannot be keys
# d = {[1, 2]: "error"} ← Would error!
2. Represents data that shouldn't be modified
# Coordinates, colors, configurations — "unchanging" data is suitable for tuples
RGB_RED = (255, 0, 0) # Red value should not be modified
DEFAULT_CONFIG = ("localhost", 8080, "admin")
Tip: When to use tuples vs. lists? A simple rule: use lists if data needs modification, use tuples if it doesn't. Functions that return multiple values typically use tuples.
4. Tuple Unpacking
One of the most useful tuple features — unpacking, assigning tuple elements directly to multiple variables:
point = (3, 5)
x, y = point # Unpacking
print(x) # 3
print(y) # 5
# Swapping variables — essentially tuple unpacking
a, b = 10, 20
a, b = b, a # Right side constructs tuple (20, 10), then unpacks
print(a, b) # 20 10
# Function returning multiple values
def get_min_max(numbers):
return min(numbers), max(numbers)
result = get_min_max([3, 1, 4, 1, 5])
print(result) # (1, 5)
low, high = get_min_max([3, 1, 4, 1, 5])
print(f"Min: {low}, Max: {high}") # Min: 1, Max: 5
Using _ to Ignore Unwanted Values
data = ("Zhang San", 25, "Beijing", "Engineer")
name, _, city, _ = data # Use _ to mean "I don't care about this"
print(f"{name} lives in {city}") # Zhang San lives in Beijing
Example: Coordinate Calculation (Difficulty: Star-Star)
# Define two points
p1 = (1, 2)
p2 = (4, 6)
# Unpack for distance calculation
x1, y1 = p1
x2, y2 = p2
distance = ((x2 - x1) 2 + (y2 - y1) 2) ** 0.5
print(f"Distance: {distance:.2f}") # 5.00
# Using enumerate for indexed iteration
fruits = ["apple", "banana", "orange"]
for i, fruit in enumerate(fruits, 1):
print(f"{i}. {fruit}")
Output:
Distance: 5.00
1. apple
2. banana
3. orange
5. List vs. Tuple Selection Guide
| Feature | List | Tuple |
|---|---|---|
| Mutable | ✅ Can add/delete/change | ❌ Immutable |
| Speed | Slightly slower | Slightly faster |
| Memory | Slightly larger | Slightly smaller |
| Can be dict key | ❌ | ✅ |
| Use case | Frequently modified data | Fixed, unchanged data |
| Typical uses | Shopping cart, to-do list, dynamic data | Coordinates, colors, function return values |
Tip: A practical habit: If you're unsure which to use, start with a list. Lists are more flexible in most scenarios. When you find that some data truly shouldn't be modified, switch to a tuple.
Common Use Cases
- Leaderboard sorting: Use
sorted(key=lambda ...)to sort complex data by custom rules. - Data cleaning: Use list comprehensions to filter, transform, and clean data in one line.
- Coordinates and geometry: Use tuples for points, rectangles, RGB colors, etc.
- Multi-return functions: Functions return
(min, max)tuples; callers unpack directly. - Enumerated iteration:
enumerate()returns(index, element)tuples, unpacked directly.
FAQ
(42) and (42,)?(42) are interpreted as mathematical grouping, not a tuple — type((42)) returns <class 'int'>. (42,) is a tuple. So single-element tuples must include a comma: (42,).key parameter in sorted() work? Give a practical example.sorted(words, key=len). Sort by the second element of tuples in a list: sorted(data, key=lambda x: x[1]). Sort by dictionary values: sorted(dict.items(), key=lambda x: x[1]). The key is understanding that key accepts a function that maps each element to a sort key.Summary
sorted()'skeyparameter specifies sort rules; combined withlambdait's very flexible- List comprehension
[expression for variable in iterable if condition]creates a new list in one line - Tuples use
()syntax, are immutable, and can be used as dictionary keys - Single-element tuples must have a comma:
(42,)— otherwise it's an integer - Tuple unpacking assigns multiple values to multiple variables; variable swapping leverages this
- Lists for mutable data, tuples for fixed data
Exercises
-
Beginner (Difficulty: Star): Use a list comprehension to generate the squares of all numbers between 1 and 20 that are divisible by 3. Hint:
[expression for n in range(...) if condition] -
Intermediate (Difficulty: Star-Star): Given a name list
names = [" alice ", "BOB", " Charlie", " david "], use a list comprehension in one step: strip whitespace + capitalize first letter and lowercase the rest. Hint:strip()for whitespace,title()orcapitalize()for case. -
Advanced (Difficulty: Star-Star-Star): Write a function
analyze_numbers(*args)that accepts any number of numeric arguments and returns a tuple(max, min, average, count_above_average). Hint: Use*argsfor variable-length arguments; use a list comprehension to count values above the average.



