Lists & Tuples
📖 Concept
Lists and tuples are Python's primary ordered sequence types. Lists are mutable (can be modified after creation), while tuples are immutable (cannot be changed). This distinction has important implications for performance, safety, and usage patterns.
When to use each:
| Use Case | List | Tuple |
|---|---|---|
| Collection of similar items | Yes | Possible but less common |
| Record of different fields | Possible but less common | Yes |
| Dictionary key | No (unhashable) | Yes (hashable) |
| Function return value (multiple) | Possible | Yes (idiomatic) |
| Needs modification | Yes | No (create new tuple) |
| Memory efficiency | Less | More |
| Thread safety | No (needs locking) | Yes (immutable) |
List comprehensions are a Pythonic way to create lists from existing iterables. They're more readable and often faster than equivalent for loops with .append().
# Syntax: [expression for item in iterable if condition]
squares = [x**2 for x in range(10)]
evens = [x for x in range(20) if x % 2 == 0]
Slicing is Python's powerful way to extract subsequences: sequence[start:stop:step]. It works on lists, tuples, strings, and any sequence type.
Unpacking lets you assign sequence elements to multiple variables in one line: a, b, c = [1, 2, 3]. The * operator captures remaining elements.
💻 Code Example
1# ============================================================2# List creation and operations3# ============================================================4# Creating lists5empty = []6numbers = [1, 2, 3, 4, 5]7mixed = [1, "hello", 3.14, True, None] # Any types8nested = [[1, 2], [3, 4], [5, 6]]910# List from other iterables11from_range = list(range(5)) # [0, 1, 2, 3, 4]12from_string = list("hello") # ['h', 'e', 'l', 'l', 'o']13from_generator = list(x**2 for x in range(5)) # [0, 1, 4, 9, 16]1415# ============================================================16# List methods (modify in-place)17# ============================================================18fruits = ["apple", "banana"]1920fruits.append("cherry") # Add to end → ['apple', 'banana', 'cherry']21fruits.insert(1, "blueberry") # Insert at index → ['apple', 'blueberry', 'banana', 'cherry']22fruits.extend(["date", "fig"]) # Add multiple items2324fruits.remove("banana") # Remove by value (first occurrence)25popped = fruits.pop() # Remove and return last item26popped_at = fruits.pop(0) # Remove and return at index2728fruits.sort() # Sort in-place (returns None!)29fruits.sort(reverse=True) # Sort descending30fruits.reverse() # Reverse in-place3132idx = fruits.index("cherry") # Find index of value33count = fruits.count("cherry") # Count occurrences3435# IMPORTANT: sort() returns None, not the sorted list!36# BAD: sorted_list = my_list.sort() # sorted_list is None!37# GOOD: sorted_list = sorted(my_list) # Returns new sorted list3839# ============================================================40# Slicing [start:stop:step]41# ============================================================42nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]4344print(nums[2:5]) # [2, 3, 4] — index 2 to 4 (stop is exclusive)45print(nums[:3]) # [0, 1, 2] — first 3 elements46print(nums[7:]) # [7, 8, 9] — from index 7 to end47print(nums[-3:]) # [7, 8, 9] — last 3 elements48print(nums[::2]) # [0, 2, 4, 6, 8] — every 2nd element49print(nums[::-1]) # [9, 8, 7, ..., 0] — reversed50print(nums[1:8:2]) # [1, 3, 5, 7] — every 2nd from index 1 to 75152# Slice assignment (lists only — tuples are immutable)53nums[2:5] = [20, 30, 40] # Replace slice54print(nums) # [0, 1, 20, 30, 40, 5, 6, 7, 8, 9]5556# Delete slice57del nums[2:5]58print(nums) # [0, 1, 5, 6, 7, 8, 9]5960# ============================================================61# List comprehensions62# ============================================================63# Basic comprehension64squares = [x**2 for x in range(10)]65print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]6667# With condition (filter)68even_squares = [x**2 for x in range(10) if x % 2 == 0]69print(even_squares) # [0, 4, 16, 36, 64]7071# With if-else (transform, not filter)72labels = ["even" if x % 2 == 0 else "odd" for x in range(5)]73print(labels) # ['even', 'odd', 'even', 'odd', 'even']7475# Nested comprehension (flattening)76matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]77flat = [num for row in matrix for num in row]78print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]7980# Matrix transpose with nested comprehension81transposed = [[row[i] for row in matrix] for i in range(3)]82print(transposed) # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]8384# ============================================================85# Unpacking86# ============================================================87# Basic unpacking88a, b, c = [1, 2, 3]89print(a, b, c) # 1 2 39091# Star unpacking (Python 3)92first, *middle, last = [1, 2, 3, 4, 5]93print(first) # 194print(middle) # [2, 3, 4]95print(last) # 59697head, *tail = [1, 2, 3, 4, 5]98print(head) # 199print(tail) # [2, 3, 4, 5]100101# Swap variables102x, y = 10, 20103x, y = y, x # Swap without temp variable!104105# Ignore values with _106_, second, _, fourth, _ = [10, 20, 30, 40, 50]107print(second, fourth) # 20 40108109# ============================================================110# Tuples — immutable sequences111# ============================================================112point = (3, 4)113rgb = (255, 128, 0)114single = (42,) # Note the comma! (42) is just 42 in parentheses115116# Tuple unpacking in functions117def get_user():118 return "Alice", 30, "NYC" # Returns a tuple (parens optional)119120name, age, city = get_user()121122# Named tuples — tuples with field names123from collections import namedtuple124Point = namedtuple('Point', ['x', 'y'])125p = Point(3, 4)126print(p.x, p.y) # 3 4 (access by name)127print(p[0], p[1]) # 3 4 (access by index)128129# Tuples as dictionary keys (lists can't be keys)130locations = {131 (40.7128, -74.0060): "New York",132 (51.5074, -0.1278): "London",133}134print(locations[(40.7128, -74.0060)]) # "New York"135136# ============================================================137# Copying: shallow vs deep138# ============================================================139import copy140141original = [[1, 2], [3, 4]]142shallow = original.copy() # or list(original) or original[:]143deep = copy.deepcopy(original)144145original[0][0] = 99146147print(shallow) # [[99, 2], [3, 4]] — inner lists are shared!148print(deep) # [[1, 2], [3, 4]] — completely independent
🏋️ Practice Exercise
Exercises:
Use list comprehension to generate a list of all Pythagorean triples (a, b, c) where a, b, c <= 30 and a^2 + b^2 = c^2.
Implement a function
rotate_list(lst, k)that rotates a list by k positions to the right.[1,2,3,4,5]rotated by 2 →[4,5,1,2,3]. Use slicing.Write a function that takes a list of strings and returns only the palindromes, sorted by length. Use list comprehension.
Demonstrate the difference between shallow copy and deep copy with a nested list. Modify the inner list and show which copy is affected.
Use unpacking to swap two variables, extract the first and last elements of a list, and split a list into head and tail.
Create a 5x5 identity matrix using nested list comprehensions. Then transpose it.
Implement a simple stack (LIFO) and queue (FIFO) using only list operations (
append,pop).
⚠️ Common Mistakes
Confusing
sort()(in-place, returns None) withsorted()(returns new list). Writingresult = my_list.sort()givesresult = None.Modifying a list while iterating:
for item in lst: if condition: lst.remove(item)skips items. Use list comprehension or iterate over a copy.Creating a list of lists with
[[]] * 5— this creates 5 references to the SAME list. Use[[] for _ in range(5)]for independent inner lists.Forgetting the comma in single-element tuples:
t = (42)is justint(42), not a tuple. Uset = (42,)ort = 42,.Using
.append()when you mean.extend():[1,2].append([3,4])gives[1, 2, [3, 4]], not[1, 2, 3, 4]. Use.extend()or+to concatenate.
💼 Interview Questions
🎤 Mock Interview
Practice a live interview for Lists & Tuples