List Slicing & Comprehensions

Difficulty: Intermediate

Slicing is one of Python's most powerful features for extracting portions of sequences. The slice syntax is list[start:stop:step], where start is the inclusive beginning index, stop is the exclusive ending index, and step is the stride between elements. All three parameters are optional: omitting start defaults to 0, omitting stop defaults to the length of the list, and omitting step defaults to 1. Slicing always returns a new list, never modifies the original.

The step parameter unlocks advanced slicing patterns. A step of 2 selects every other element, a step of 3 selects every third, and so on. A negative step reverses the traversal direction, which is why list[::-1] is the idiomatic way to reverse a list. When using a negative step, the start index should be greater than the stop index. You can also assign to a slice to replace a range of elements in a single operation: list[1:4] = [10, 20] replaces indices 1, 2, 3 with two new values.

List comprehensions provide a concise, readable way to create new lists by transforming or filtering elements from an existing iterable. The basic syntax is [expression for item in iterable]. This is equivalent to a for loop that appends to an empty list, but it is more Pythonic, often faster (the loop runs at C speed internally), and reads as a single declarative statement rather than an imperative sequence of steps.

Conditional comprehensions add filtering by appending an if clause: [expression for item in iterable if condition]. Only elements that satisfy the condition are included in the result. You can also use if-else within the expression itself for transformations: [x if condition else y for item in iterable]. The placement of if matters: after 'for' it filters, within the expression it transforms.

Nested comprehensions let you work with multi-dimensional data or generate combinations. The syntax [expression for outer in iterable1 for inner in iterable2] is equivalent to nested for loops. The outer loop comes first, then the inner loop. While powerful, nested comprehensions can become unreadable beyond two levels. If you find yourself nesting three or more loops, switch to regular for loops for clarity.

Code examples

Basic Slicing

nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

print(nums[2:5])
print(nums[:4])
print(nums[6:])
print(nums[::2])
print(nums[::-1])
print(nums[1:8:3])

Slicing creates a new list from start (inclusive) to stop (exclusive) with the given step. Omitted values use sensible defaults. Negative step reverses the direction.

Slice Assignment

letters = ['a', 'b', 'c', 'd', 'e']

# Replace a range
letters[1:3] = ['X', 'Y', 'Z']
print(letters)

# Delete via empty slice assignment
letters[1:4] = []
print(letters)

Slice assignment replaces the specified range with the given elements. The replacement can have a different length than the slice being replaced. Assigning an empty list effectively deletes those elements.

List Comprehensions

# Basic comprehension
squares = [x  2 for x in range(1, 6)]
print(squares)

# With condition (filter)
evens = [x for x in range(10) if x % 2 == 0]
print(evens)

# With if-else (transform)
labels = ["even" if x % 2 == 0 else "odd" for x in range(5)]
print(labels)

# From string
uppers = [c.upper() for c in "hello" if c != 'l']
print(uppers)

List comprehensions are a concise way to build lists. The if clause after 'for' filters elements. An if-else before 'for' transforms each element. Comprehensions can work with any iterable, including strings.

Nested Comprehensions

# Flatten a 2D list
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
print(flat)

# Generate a multiplication table (3x3)
table = [[i * j for j in range(1, 4)] for i in range(1, 4)]
for row in table:
    print(row)

To flatten a 2D list, the outer loop iterates over rows and the inner loop over elements. For creating a 2D structure, the outer comprehension produces rows and the inner comprehension produces columns.

Key points

Concepts covered

Slicing, List Comprehensions, Conditional Comprehensions, Nested Comprehensions