What it is

Python lists are dynamic arrays. You can add items in place with methods like append(), insert(), and extend(), or create a new list using concatenation and unpacking. Core list operations are summarized in the list methods documentation.

Why it matters

Choosing the right way to add elements affects:

  • Readability: single item vs many, at the end vs at a position.
  • Performance: append is fast; inserting near the front shifts items.
  • Correctness: mutating a list in place vs returning a new list avoids unintended side effects.

How to use it

1) Add one item to the end (in place)

nums = [1, 2, 3]
nums.append(4)         # [1, 2, 3, 4]
# Note: append() returns None and mutates the list.

2) Insert at a specific position (in place)

letters = ['a', 'c', 'd']
letters.insert(1, 'b') # ['a', 'b', 'c', 'd']  inserts at index 1

3) Add multiple items from any iterable (in place)

items = ['apple', 'banana']
items.extend(['cherry', 'date'])  # end of list
items.extend(('elderberry', 'fig'))  # tuples work too
items.extend({ 'g', 'h' })  # adds each element of the set (order arbitrary)

4) Concatenate to create a new list (no mutation)

base = [1, 2]
new_list = base + [3]       # base unchanged
# or unpacking syntax:
new_list2 = [*base, 3]
front_added = [0, *base]    # add to the front without mutating base

5) Copy-then-modify (explicit no-mutation pattern)

orig = [10, 20]
copy = orig.copy()
copy.append(30)    # orig is still [10, 20]

6) Add inside a nested list

matrix = [['abc', '2'], ['cds', '333'], ['efg']]
matrix[2].append('444')  # [['abc','2'], ['cds','333'], ['efg','444']]

7) Insert multiple items via slice assignment (in place)

nums = [1, 4, 5]
nums[1:1] = [2, 3]   # insert before index 1 → [1, 2, 3, 4, 5]
nums[len(nums):] = [6, 7]  # append many → [1, 2, 3, 4, 5, 6, 7]

8) Shorthand for extend (in place)

nums = [1, 2]
nums += [3, 4]  # like extend; mutates the existing list

Limits and trade-offs

  • Mutation vs copy: append(), insert(), extend(), and += mutate the list. Use +, unpacking ([*lst, x]), or copy()-then-modify to avoid side effects.
  • Performance:
    • append(): amortized O(1)
    • extend(k): O(k)
    • insert(i, x): O(n) (shifts elements)
    • lst + other or [*lst, *other]: O(n + m) to build a new list
  • Iteration safety: Don’t add or remove from a list while iterating over it; build a new list or collect changes first.
  • Append vs extend: append(obj) adds the object as a single element; extend(iterable) adds each element of the iterable.
  • Dicts and sets: Extending with a dict iterates its keys; sets are unordered, so result order isn’t guaranteed.

FAQs

  • How do I add to the front? Use insert(0, x) to mutate, or [x, *lst] to create a new list.
  • Why does append() return None? It mutates in place; the return value signals there’s no new list to use.
  • Is += different from extend()? For lists, += behaves like extend() and mutates the list.
  • How do I add multiple elements at a position? Use slice assignment: lst[i:i] = iterable.
  • Can I add while looping? Avoid mutating during iteration; build a result list instead, e.g., result = [*lst, extra] after the loop.