Python · Syntax · Beginner
List & Tuple Methods
Master all list methods and learn the key differences between lists and tuples.
Quick topic start and explanations before exercises (exercises below):
Tuples & Unpacking
#List & Tuple Methods Reference
#Exercises:
append vs extend
#You have a list `result = [1, 2, 3]`. Write two separate expressions: 1. Use `append` to add the list `[4, 5]` as a single item. 2. Starting fresh from `[1, 2, 3]`, use `extend` to add `[4, 5]` as individual items. Print both results and explain the difference.
result = [1, 2, 3] # 1. Use append to add [4, 5] as a SINGLE item # 2. Start fresh and use extend to add [4, 5] as INDIVIDUAL items result2 = [1, 2, 3]
Solution
result = [1, 2, 3]
result.append([4, 5])
print(result) # [1, 2, 3, [4, 5]] — nested list
result2 = [1, 2, 3]
result2.extend([4, 5])
print(result2) # [1, 2, 3, 4, 5] — individual items
Insert at Position
#Write a function `insert_after(lst, target, value)` that inserts `value` immediately after the first occurrence of `target` in `lst`. If `target` is not found, append `value` at the end. Example: `insert_after([1, 2, 4, 5], 2, 3)` → `[1, 2, 3, 4, 5]`.
def insert_after(lst, target, value):
pass
print(insert_after([1, 2, 4, 5], 2, 3)) # [1, 2, 3, 4, 5]
print(insert_after([1, 2, 3], 99, 0)) # [1, 2, 3, 0]
Solution
def insert_after(lst, target, value):
result = lst[:]
if target in result:
idx = result.index(target)
result.insert(idx + 1, value)
else:
result.append(value)
return result
print(insert_after([1, 2, 4, 5], 2, 3)) # [1, 2, 3, 4, 5]
print(insert_after([1, 2, 3], 99, 0)) # [1, 2, 3, 0]
Remove Duplicates (ordered)
#Write a function `remove_dupes(lst)` that removes duplicate elements from a list while preserving the original order of first appearances. Example: `remove_dupes([3, 1, 2, 1, 3, 4])` → `[3, 1, 2, 4]`. Do not use sets directly (they do not preserve order).
def remove_dupes(lst):
pass
print(remove_dupes([3, 1, 2, 1, 3, 4])) # [3, 1, 2, 4]
print(remove_dupes([1, 1, 1])) # [1]
Solution
def remove_dupes(lst):
seen = set()
result = []
for item in lst:
if item not in seen:
seen.add(item)
result.append(item)
return result
print(remove_dupes([3, 1, 2, 1, 3, 4])) # [3, 1, 2, 4]
print(remove_dupes([1, 1, 1])) # [1]
Sort by Key
#Write a function `sort_by_length(words)` that returns a new list of words sorted by their length (shortest first). Words of equal length should remain in their original relative order. Example: `sort_by_length(["banana", "fig", "apple", "kiwi"])` → `["fig", "kiwi", "apple", "banana"]`.
def sort_by_length(words):
pass
print(sort_by_length(["banana", "fig", "apple", "kiwi"]))
# ["fig", "kiwi", "apple", "banana"]
Solution
def sort_by_length(words):
return sorted(words, key=len)
print(sort_by_length(["banana", "fig", "apple", "kiwi"]))
# ["fig", "kiwi", "apple", "banana"]
Stack with List
#Implement a simple stack using a list. Write a class `Stack` with methods: `push(item)`, `pop()` (returns and removes top item), `peek()` (returns top item without removing), `is_empty()`, and `size()`. Use only list methods — no imports needed.
class Stack:
def __init__(self):
self._data = []
def push(self, item):
pass
def pop(self):
pass
def peek(self):
pass
def is_empty(self):
pass
def size(self):
pass
s = Stack()
s.push(1)
s.push(2)
s.push(3)
print(s.peek()) # 3
print(s.pop()) # 3
print(s.size()) # 2
print(s.is_empty()) # False
Solution
class Stack:
def __init__(self):
self._data = []
def push(self, item):
self._data.append(item)
def pop(self):
return self._data.pop()
def peek(self):
return self._data[-1]
def is_empty(self):
return len(self._data) == 0
def size(self):
return len(self._data)
s = Stack()
s.push(1)
s.push(2)
s.push(3)
print(s.peek()) # 3
print(s.pop()) # 3
print(s.size()) # 2
print(s.is_empty()) # False
Safe Copy
#The following code has a bug. Fix it so that modifying `b` does not affect `a`: ```python a = [1, 2, 3] b = a b.append(99) print(a) # should still be [1, 2, 3] ``` Explain in a comment why the original code fails.
a = [1, 2, 3] b = a # BUG: both point to the same list b.append(99) print(a) # should still be [1, 2, 3], but prints [1, 2, 3, 99] # Fix the code above so that modifying b does not affect a
Solution
a = [1, 2, 3]
b = a.copy() # creates a new independent list
b.append(99)
print(a) # [1, 2, 3] — unchanged
print(b) # [1, 2, 3, 99]
# Alternative: b = a[:] or b = list(a)
Tuple Unpacking
#Write a function `swap(a, b)` that returns the two values swapped, using tuple unpacking in one line. Then write a function `unpack_first_last(lst)` that returns a tuple `(first, last)` using star unpacking. Example: `unpack_first_last([10, 20, 30, 40])` → `(10, 40)`.
def swap(a, b):
pass
def unpack_first_last(lst):
pass
print(swap(1, 2)) # (2, 1)
print(unpack_first_last([10, 20, 30, 40])) # (10, 40)
Solution
def swap(a, b):
return b, a
def unpack_first_last(lst):
first, *_, last = lst
return first, last
print(swap(1, 2)) # (2, 1)
print(unpack_first_last([10, 20, 30, 40])) # (10, 40)
Find Index Safely
#Write a function `find_index(lst, value)` that returns the index of `value` in `lst`, or `-1` if not found. Do NOT use `.index()` directly (it raises ValueError). Example: `find_index([10, 20, 30], 20)` → `1`, `find_index([10, 20, 30], 99)` → `-1`.
def find_index(lst, value):
pass
print(find_index([10, 20, 30], 20)) # 1
print(find_index([10, 20, 30], 99)) # -1
Solution
def find_index(lst, value):
try:
return lst.index(value)
except ValueError:
return -1
print(find_index([10, 20, 30], 20)) # 1
print(find_index([10, 20, 30], 99)) # -1
Most Frequent
#Write a function `most_frequent(lst)` that returns the element that appears most often in the list. If there is a tie, return the one that appears first. Example: `most_frequent([1, 2, 2, 3, 1, 2])` → `2`, `most_frequent([5, 5, 3, 3])` → `5`.
def most_frequent(lst):
pass
print(most_frequent([1, 2, 2, 3, 1, 2])) # 2
print(most_frequent([5, 5, 3, 3])) # 5 (first on tie)
Solution
def most_frequent(lst):
counts = {}
for item in lst:
counts[item] = counts.get(item, 0) + 1
return max(lst, key=lambda x: counts[x])
print(most_frequent([1, 2, 2, 3, 1, 2])) # 2
print(most_frequent([5, 5, 3, 3])) # 5 (first on tie)
Flatten One Level
#Write a function `flatten(lst)` that takes a list of lists and returns a single flat list with all elements. Example: `flatten([[1, 2], [3, 4], [5]])` → `[1, 2, 3, 4, 5]`. Use `extend` or a list comprehension.
def flatten(lst):
pass
print(flatten([[1, 2], [3, 4], [5]])) # [1, 2, 3, 4, 5]
print(flatten([[10, 20], [30], [40, 50]])) # [10, 20, 30, 40, 50]
Solution
def flatten(lst):
result = []
for sub in lst:
result.extend(sub)
return result
# One-liner:
def flatten_v2(lst):
return [x for sub in lst for x in sub]
print(flatten([[1, 2], [3, 4], [5]])) # [1, 2, 3, 4, 5]
print(flatten([[10, 20], [30], [40, 50]])) # [10, 20, 30, 40, 50]