Python · Syntax · Beginner

List & Tuple Methods

10 tasks

Master all list methods and learn the key differences between lists and tuples.

List Methods

#
A list is an ordered, **mutable** sequence — you can change it after creation. Python provides a rich set of in-place methods that modify the list directly. ## Adding elements ```python fruits = ["apple", "banana"] fruits.append("cherry") # add one element at the end print(fruits) # ["apple", "banana", "cherry"] fruits.extend(["date", "elderberry"]) # add all elements from an iterable print(fruits) # ["apple", "banana", "cherry", "date", "elderberry"] fruits.insert(1, "avocado") # insert at index 1 print(fruits) # ["apple", "avocado", "banana", "cherry", "date", "elderberry"] ``` **Key difference**: `append(x)` adds `x` as a single item; `extend(iterable)` unpacks and adds each element individually. `list.append([1,2])` gives `[..., [1,2]]`, while `list.extend([1,2])` gives `[..., 1, 2]`. ## Removing elements ```python nums = [1, 2, 3, 2, 4] nums.remove(2) # removes the FIRST occurrence of value 2 print(nums) # [1, 3, 2, 4] popped = nums.pop() # removes and returns the LAST element print(popped) # 4 print(nums) # [1, 3, 2] popped = nums.pop(0) # removes and returns element at index 0 print(popped) # 1 print(nums) # [3, 2] nums.clear() # removes all elements print(nums) # [] ``` ## Searching ```python items = ["a", "b", "c", "b"] print(items.index("b")) # 1 — index of FIRST match (raises ValueError if not found) print(items.count("b")) # 2 — count of all matches print("c" in items) # True — use `in` for simple membership check ``` ## Sorting and reversing ```python nums = [3, 1, 4, 1, 5, 9, 2, 6] nums.sort() # sorts in place, ascending print(nums) # [1, 1, 2, 3, 4, 5, 6, 9] nums.sort(reverse=True) # sorts in place, descending print(nums) # [9, 6, 5, 4, 3, 2, 1, 1] words = ["banana", "apple", "cherry"] words.sort(key=len) # sort by string length print(words) # ["apple", "banana", "cherry"] nums.reverse() # reverses in place (does not sort) ``` `sort()` modifies in place and returns `None`. Use `sorted(lst)` if you need a new sorted list without changing the original. ## Copying ```python original = [1, 2, 3] copy1 = original.copy() # shallow copy copy2 = original[:] # also a shallow copy copy1.append(99) print(original) # [1, 2, 3] — unchanged print(copy1) # [1, 2, 3, 99] ``` Never do `copy = original` — that creates an **alias**, not a copy.

Tuples & Unpacking

#
A tuple is an ordered, **immutable** sequence. Once created, its contents cannot change. Use tuples for data that should not be modified. ## Tuple basics ```python point = (3, 7) rgb = (255, 128, 0) single = (42,) # single-element tuple — note the trailing comma! empty = () print(type(point)) # <class 'tuple'> print(point[0]) # 3 print(len(rgb)) # 3 ``` Tuple without parentheses also works: ```python coords = 10, 20 # same as (10, 20) ``` ## List vs Tuple: when to use which | List `[]` | Tuple `()` | |---|---| | Mutable — can add/remove/change | Immutable — fixed after creation | | Use for collections that grow/shrink | Use for fixed records (coordinates, RGB, DB rows) | | Slightly more memory overhead | Slightly faster access, less memory | | Cannot be used as dict key | Can be used as dict key | ```python # List: growing collection shopping = [] shopping.append("milk") shopping.append("eggs") # Tuple: fixed record person = ("Alice", 30, "engineer") name, age, role = person # unpacking ``` ## Tuple unpacking ```python x, y = (10, 20) print(x) # 10 print(y) # 20 # Swap variables without a temp variable a, b = 1, 2 a, b = b, a print(a, b) # 2 1 # Extended unpacking first, *rest = [1, 2, 3, 4, 5] print(first) # 1 print(rest) # [2, 3, 4, 5] *start, last = [1, 2, 3, 4, 5] print(start) # [1, 2, 3, 4] print(last) # 5 ``` ## Tuple in for loops ```python pairs = [(1, "one"), (2, "two"), (3, "three")] for number, word in pairs: print(f"{number} = {word}") # 1 = one # 2 = two # 3 = three ``` This is how `enumerate()` and `dict.items()` work under the hood — they return tuples. ## Returning multiple values from a function ```python def min_max(numbers): return min(numbers), max(numbers) # returns a tuple lo, hi = min_max([3, 1, 4, 1, 5, 9]) print(lo, hi) # 1 9 ``` Functions returning multiple values always return a tuple. Unpacking is the idiomatic way to receive them.

List & Tuple Methods Reference

#
## List methods | Method | What it does | Returns | |---|---|---| | `lst.append(x)` | Add `x` to end | `None` | | `lst.extend(iterable)` | Add all items from iterable | `None` | | `lst.insert(i, x)` | Insert `x` at index `i` | `None` | | `lst.pop()` | Remove and return last item | item | | `lst.pop(i)` | Remove and return item at index `i` | item | | `lst.remove(x)` | Remove first occurrence of `x` | `None` | | `lst.clear()` | Remove all items | `None` | | `lst.index(x)` | Index of first `x` (raises ValueError) | int | | `lst.count(x)` | Count occurrences of `x` | int | | `lst.sort(key=None, reverse=False)` | Sort in place | `None` | | `lst.reverse()` | Reverse in place | `None` | | `lst.copy()` | Shallow copy | new list | ## Standalone functions for lists | Function | What it does | |---|---| | `sorted(lst, key=None, reverse=False)` | Returns new sorted list | | `reversed(lst)` | Returns reverse iterator | | `len(lst)` | Number of elements | | `min(lst)` / `max(lst)` | Minimum / maximum value | | `sum(lst)` | Sum of numeric elements | | `list(iterable)` | Convert to list | ## Tuple operations | Operation | Example | Result | |---|---|---| | Create | `t = (1, 2, 3)` | — | | Access | `t[0]` | `1` | | Slice | `t[1:]` | `(2, 3)` | | Unpack | `a, b, c = t` | a=1, b=2, c=3 | | Star unpack | `first, *rest = t` | first=1, rest=[2,3] | | Concatenate | `(1, 2) + (3, 4)` | `(1, 2, 3, 4)` | | Repeat | `(0,) * 3` | `(0, 0, 0)` | | `len(t)` | `len((1, 2, 3))` | `3` | | `x in t` | `2 in (1, 2, 3)` | `True` | | Convert | `list(t)` / `tuple(lst)` | — | ## append vs extend ```python lst = [1, 2] lst.append([3, 4]) # → [1, 2, [3, 4]] ← list as single item lst = [1, 2] lst.extend([3, 4]) # → [1, 2, 3, 4] ← items added individually ``` ## sort vs sorted ```python nums = [3, 1, 2] nums.sort() # modifies nums in place, returns None print(nums) # [1, 2, 3] nums = [3, 1, 2] new = sorted(nums) # returns new list, nums unchanged print(nums, new) # [3, 1, 2] [1, 2, 3] ```
01

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
02

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]
03

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]
04

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"]
05

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
06

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)
07

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)
08

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
09

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)
10

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]