Python Lists & Comprehensions

๐Ÿ Python 3.12+ ๐ŸŸข Chapter 11 of 65 ๐Ÿ“‚ Phase 3: Strings and Collections ๐Ÿ“… 2026 Edition
๐Ÿ“Œ Covered in this chapter: Creation ยท Indexing ยท CRUD ยท Sorting ยท Copying (Shallow vs Deep) ยท Nested Lists ยท List Comprehensions
Master Python lists: dynamic array architecture, appending, inserting, removing, sorting, shallow vs deep copying, nested 2D matrices, and list comprehensions.
1What is a List? Creation & Dynamic Array Architecture

A list (list) in Python is an ordered, mutable, heterogeneous collection of items enclosed in square brackets ([...]).

  • Ordered: Elements maintain the exact sequence in which they were added.
  • Mutable: You can add, replace, sort, or delete elements in place without creating a new object.
  • Heterogeneous: A single list can contain mixed data types (integers, strings, floats, booleans, and other lists).
๐Ÿ’ป Example 1: Creating Lists with Mixed Data Types
# 1. Creating empty and populated lists
empty_list = []
numbers = [10, 20, 30, 40, 50]
mixed_list = ["Balaji", 25, 99.5, True, ["Python", "JS"]]

# 2. Inspecting length and items
print("Numbers list:", numbers)
print("Total elements:", len(numbers))
print("Mixed list:", mixed_list)
๐Ÿ” Under the Hood (CPython):

In CPython, a list is implemented as a dynamic array of pointer references. When the list grows beyond its current capacity, CPython automatically reallocates a larger memory buffer with amortized $O(1)$ append time.

2Adding Items: append(), insert(), extend()

Python provides three primary methods to insert new data into a list:

  • list.append(x): Adds item x to the very end of the list in fast $O(1)$ time.
  • list.insert(index, x): Inserts item x at a specific index, shifting existing items to the right ($O(N)$ time).
  • list.extend(iterable): Unpacks and appends all items from another list or iterable to the end.
๐Ÿ’ป Example 2: Adding Elements with append, insert, extend
fruits = ["Apple", "Banana"]
print("Initial list:", fruits)

# 1. append() - Adds to the end
fruits.append("Mango")
print("After append('Mango'):", fruits)

# 2. insert() - Inserts at index 1
fruits.insert(1, "Orange")
print("After insert(1, 'Orange'):", fruits)

# 3. extend() - Merges multiple items from another list
more_fruits = ["Grapes", "Pineapple"]
fruits.extend(more_fruits)
print("After extend():", fruits)
๐Ÿ” append() vs extend() Trap:

If you call fruits.append(["Grapes", "Pineapple"]), it adds the whole list as a single nested sub-list element! Use extend() when you want to unpack and add individual elements.

3Updating & Removing Items: pop(), remove(), del, clear()

Modify or remove items from a list using index reassignment or deletion methods:

  • list[index] = new_val: Replaces the value at specified index.
  • list.remove(val): Searches and removes the first occurrence of val (raises ValueError if missing).
  • list.pop(index): Removes and returns the item at index (default removes last item).
  • del list[index]: Deletes item at index or a slice of items.
  • list.clear(): Empties all items from the list.
๐Ÿ’ป Example 3: Updating and Removing Elements
tasks = ["Email client", "Write code", "Bug fix", "Deploy app"]
print("Initial tasks:", tasks)

# 1. Update task at index 0
tasks[0] = "Check Slack messages"
print("After update tasks[0]:", tasks)

# 2. remove() by value
tasks.remove("Bug fix")
print("After remove('Bug fix'):", tasks)

# 3. pop() removes and returns last item
completed_task = tasks.pop()
print(f"Popped task: '{completed_task}' | Remaining: {tasks}")

# 4. del keyword for specific index
del tasks[0]
print("After del tasks[0]:", tasks)
๐Ÿ” Which removal method to use?
  • Use .remove(val) when you know the value.
  • Use .pop(i) when you know the index and need the returned value.
  • Use del list[start:stop] to delete a range of items.
4Sorting Lists: sort() vs sorted()

Python provides two ways to sort collections using the highly optimized Timsort algorithm ($O(N \log N)$ time complexity):

  • list.sort(): Sorts the list in-place (modifies original list, returns None).
  • sorted(iterable): Built-in function that returns a new sorted list without modifying the original!
๐Ÿ’ป Example 4: Sorting In-Place (sort) vs Non-Destructive (sorted)
scores = [45, 99, 12, 78, 63, 85]

# 1. sorted() returns a NEW sorted list:
ascending_scores = sorted(scores)
descending_scores = sorted(scores, reverse=True)

print("Original scores list:", scores)
print("New sorted list (ascending):", ascending_scores)
print("New sorted list (descending):", descending_scores)

# 2. .sort() mutates the list IN PLACE:
scores.sort()
print("\nOriginal scores after .sort():", scores)
๐Ÿ” Common Beginner Bug:

Never write scores = scores.sort()! Because .sort() mutates in-place, it returns None, which will overwrite your variable with None.

5Copying Lists: Shallow Copy vs Reference Alias Trap

When you write list_b = list_a, Python does NOT copy the list. It creates a reference alias pointing to the exact same memory address! Modifying list_b will unintentionally corrupt list_a.

To make an independent clone, create a shallow copy with .copy() or [:]:

๐Ÿ’ป Example 5: List Copying and Reference Isolation
# โŒ REFERENCE ALIAS BUG:
original = [1, 2, 3]
alias = original
alias.append(99)
print("Reference Alias Demo:")
print("Original:", original)  # [1, 2, 3, 99] (CORRUPTED!)
print("Alias:   ", alias)

# โœ… INDEPENDENT SHALLOW COPY:
source = [10, 20, 30]
cloned = source.copy()  # or source[:]
cloned.append(999)

print("\nIndependent Copy Demo:")
print("Source:", source)  # [10, 20, 30] (Safe and untouched!)
print("Cloned:", cloned)  # [10, 20, 30, 999]
๐Ÿ” Deep Copy Note:

If your list contains nested sub-lists (e.g. [[1, 2], [3, 4]]), use import copy; copy.deepcopy(matrix) to clone nested child objects recursively.

6Python List Comprehensions ([expr for x in iterable if cond])

List comprehensions offer a concise, readable, and faster syntax to create new lists by transforming and filtering existing sequences in a single line.

Syntax: [ expression for item in iterable if condition ]
๐Ÿ’ป Example 6: List Comprehensions Filtering & Transformation
# Traditional 5-line for-loop approach:
squares_traditional = []
for x in range(1, 11):
    if x % 2 == 0:
        squares_traditional.append(x ** 2)

# โœ… Modern 1-line List Comprehension:
squares_comprehension = [x ** 2 for x in range(1, 11) if x % 2 == 0]

print("Traditional Loop Result:", squares_traditional)
print("Comprehension Result:   ", squares_comprehension)

# Filtering names with length >= 5:
names = ["Alex", "Balaji", "Chloe", "David", "Elizabeth"]
long_names = [n.upper() for n in names if len(n) >= 6]
print("Uppercase Long Names (len >= 6):", long_names)
๐Ÿ” Performance Advantage:

List comprehensions execute at C-speed in the Python Virtual Machine (PVM) without the overhead of repeated .append() attribute lookups.

โš ๏ธ Common Developer Pitfall: Modifying a List While Looping Over It

Never delete items from a list while iterating over it (for x in lst: if x==2: lst.remove(x)). Deleting elements shifts remaining indices left, skipping elements! Instead, iterate over a copy: for x in lst.copy(): or use a list comprehension.

๐Ÿ’ป Hands-on Interactive Practice Challenge

Given a list of numbers from 1 to 20, create a new list containing only the cubes (x**3) of odd numbers using a list comprehension.

Python 3 Practice Challenge โ–ถ Run in Compiler
numbers = list(range(1, 21))

# List comprehension: cubes of odd numbers
odd_cubes = [x ** 3 for x in numbers if x % 2 != 0]

print("Numbers 1-20:", numbers)
print("Cubes of Odd Numbers:", odd_cubes)
Run This Challenge in Online Python IDE โ†’
โ“ Frequently Asked Questions (FAQ)

Q What is the time complexity of append() vs insert(0, x)?

append() is O(1) constant time because it places the item at the end. insert(0, x) is O(N) linear time because all existing N elements must be shifted in memory.

Q How do I remove all occurrences of an item from a list?

Use a list comprehension: cleaned = [x for x in my_list if x != target_val] or a while loop: while target in my_list: my_list.remove(target).

Q Can a list contain another list inside it?

Yes! Python lists can be nested to any depth, enabling 2D matrices (grid = [[1, 2], [3, 4]]), 3D tensors, and tree structures.

OC
Written by Our Compiler Technical Editorial Team
Reviewed for accuracy & tested on Python 3.12+ runtime ยท Last updated August 2026