beginnerPython Framework • Core Concepts

List Operations & Slicing

Join 1.2k+ learners

Append: Adding to the End

append() is the most common way to add items. It adds ONE element to the end of the list in O(1) time. The list grows dynamically—no need to specify size upfront.

Python
tasks = ["wake up", "code"] # Add single items tasks.append("lunch") tasks.append("more code") print(tasks) # ['wake up', 'code', 'lunch', 'more code'] # Common pattern: build list in loop results = [] for i in range(5): results.append(i ** 2) print(results) # [0, 1, 4, 9, 16]

Extend: Adding Multiple Items

extend() adds ALL items from an iterable (list, tuple, string) to the end. It unpacks the iterable, unlike append which adds it as a single element.

Python
base = [1, 2, 3] # extend() - adds each element base.extend([4, 5, 6]) print(base) # [1, 2, 3, 4, 5, 6] # Compare with append() base.append([7, 8]) # Adds list AS element! print(base) # [1, 2, 3, 4, 5, 6, [7, 8]] # extend with string (adds each char!) letters = [] letters.extend("abc") print(letters) # ['a', 'b', 'c']

Insert: Adding at Any Position

insert(index, item) places an element at a specific position. All elements after shift right. Slower than append() because of the shifting—O(n) worst case.

Python
queue = ["Alice", "Charlie", "David"] # Insert at index 1 queue.insert(1, "Bob") print(queue) # ['Alice', 'Bob', 'Charlie', 'David'] # Insert at beginning (index 0) queue.insert(0, "VIP") print(queue) # ['VIP', 'Alice', 'Bob', ...] # Insert at end (same as append) queue.insert(len(queue), "Last") # Negative index: insert before that position nums = [1, 2, 4] nums.insert(-1, 3) # [1, 2, 3, 4]

Remove: Delete by Value

remove(value) finds and deletes the FIRST occurrence of a value. Raises ValueError if not found. Use 'if x in list' to check first, or try/except.

Python
colors = ["red", "blue", "red", "green"] # Remove first 'red' colors.remove("red") print(colors) # ['blue', 'red', 'green'] # Safe removal if "yellow" in colors: colors.remove("yellow") # Remove all occurrences while "red" in colors: colors.remove("red") print(colors) # ['blue', 'green'] # Or use list comprehension colors = [c for c in colors if c != "red"]

Pop: Remove by Index & Return

pop(index) removes AND returns the item at that index. Default is -1 (last item). Useful when you need the removed value. O(1) for last, O(n) for others.

Python
stack = [10, 20, 30, 40, 50] # Pop last (default) - O(1) last = stack.pop() print(last) # 50 print(stack) # [10, 20, 30, 40] # Pop first - O(n) (shifts all) first = stack.pop(0) print(first) # 10 # Pop middle mid = stack.pop(1) # removes 30 print(stack) # [20, 40] # Use as stack (LIFO) stack = [] stack.append(1) stack.append(2) print(stack.pop()) # 2

Clear & Delete

clear() empties the list completely. Use 'del' to remove by index, slice, or delete the entire list variable. These are destructive operations!

Python
nums = [1, 2, 3, 4, 5] # Delete single item del nums[2] # Remove index 2 print(nums) # [1, 2, 4, 5] # Delete slice del nums[1:3] # Remove indices 1-2 print(nums) # [1, 5] # Clear all (keeps variable) nums.clear() print(nums) # [] # Delete variable entirely del nums # print(nums) # NameError: nums not defined

Basic Slicing: [start:end]

Slicing extracts a portion using [start:end]. Start is inclusive, end is exclusive. Omit start for beginning (0), omit end for the rest. Creates a NEW list!

Python
letters = ['a', 'b', 'c', 'd', 'e', 'f'] # Basic slice print(letters[1:4]) # ['b', 'c', 'd'] # From start print(letters[:3]) # ['a', 'b', 'c'] # To end print(letters[3:]) # ['d', 'e', 'f'] # Full copy copy = letters[:] # Out of bounds is OK! print(letters[2:100]) # ['c', 'd', 'e', 'f']

Negative Index Slicing

Negative indices count from the end: -1 is last, -2 is second-to-last. Combine with slicing for powerful end-relative extractions.

Python
data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # Last 3 elements print(data[-3:]) # [7, 8, 9] # All except last 2 print(data[:-2]) # [0, 1, 2, 3, 4, 5, 6, 7] # From -5 to -2 (exclusive) print(data[-5:-2]) # [5, 6, 7] # Middle portion print(data[2:-2]) # [2, 3, 4, 5, 6, 7] # Negative to positive print(data[-7:5]) # [3, 4] (indices 3 to 4)

Step Slicing: [start:end:step]

Add a third parameter for step size. Step of 2 takes every other item. Step of 3 takes every third. Powerful for sampling and patterns.

Python
nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # Every 2nd element print(nums[::2]) # [0, 2, 4, 6, 8] # Every 3rd element print(nums[::3]) # [0, 3, 6, 9] # Every 2nd from index 1 print(nums[1::2]) # [1, 3, 5, 7, 9] # Every 2nd in range print(nums[2:8:2]) # [2, 4, 6] # Practical: get odd indices odds = nums[1::2] # [1, 3, 5, 7, 9]

Reverse with Slicing: [::-1]

A negative step goes backwards. [::-1] is the Pythonic way to reverse any sequence. It creates a reversed copy without modifying the original.

Python
original = [1, 2, 3, 4, 5] # Reverse entire list reversed_list = original[::-1] print(reversed_list) # [5, 4, 3, 2, 1] print(original) # [1, 2, 3, 4, 5] unchanged! # Reverse string text = "Python" print(text[::-1]) # "nohtyP" # Reverse portion print(original[3:0:-1]) # [4, 3, 2] # Check palindrome word = "radar" if word == word[::-1]: print("Palindrome!")

Slice Assignment: Replace Sections

Assign to a slice to replace multiple elements at once. The replacement can be a different length—the list adjusts automatically!

Python
nums = [0, 1, 2, 3, 4, 5] # Replace slice with same length nums[1:4] = [10, 20, 30] print(nums) # [0, 10, 20, 30, 4, 5] # Replace with fewer (shrinks list) nums[1:4] = [99] print(nums) # [0, 99, 4, 5] # Replace with more (expands list) nums[1:2] = [7, 8, 9] print(nums) # [0, 7, 8, 9, 4, 5] # Insert without replacing nums[2:2] = [100, 200] # Insert at index 2 print(nums) # [0, 7, 100, 200, 8, 9, 4, 5]

Finding Elements: index() & count()

index(value) returns the position of first match (or ValueError). count(value) tells how many times it appears. Both perform O(n) scans.

Python
items = ['a', 'b', 'c', 'b', 'd', 'b'] # Find first occurrence pos = items.index('b') print(pos) # 1 # Find within range pos = items.index('b', 2) # Start at index 2 print(pos) # 3 # Count occurrences count = items.count('b') print(count) # 3 # Find all positions positions = [i for i, x in enumerate(items) if x == 'b'] print(positions) # [1, 3, 5]

Sorting: sort() vs sorted()

sort() modifies list in-place, returns None. sorted() returns NEW sorted list, original unchanged. Both accept key= and reverse= parameters.

Python
nums = [3, 1, 4, 1, 5, 9, 2, 6] # In-place sort nums.sort() print(nums) # [1, 1, 2, 3, 4, 5, 6, 9] # Descending nums.sort(reverse=True) print(nums) # [9, 6, 5, 4, 3, 2, 1, 1] # sorted() keeps original original = [3, 1, 2] new_list = sorted(original) print(original) # [3, 1, 2] - unchanged print(new_list) # [1, 2, 3] # Custom key words = ['banana', 'pie', 'apple'] words.sort(key=len) print(words) # ['pie', 'apple', 'banana']

Reverse: reverse() vs [::-1]

reverse() flips list in-place (O(n), no extra space). [::-1] creates reversed copy. reversed() returns an iterator for memory efficiency.

Python
nums = [1, 2, 3, 4, 5] # In-place reverse nums.reverse() print(nums) # [5, 4, 3, 2, 1] # Slicing (creates copy) nums = [1, 2, 3, 4, 5] rev_copy = nums[::-1] print(nums) # [1, 2, 3, 4, 5] original print(rev_copy) # [5, 4, 3, 2, 1] copy # reversed() iterator (memory efficient) for item in reversed(nums): print(item) # 5, 4, 3, 2, 1 # Convert iterator to list rev_list = list(reversed(nums))

Practical: Rotating a List

Rotate elements left or right using slicing. Left rotation: first elements go to end. Right rotation: last elements go to beginning.

Python
nums = [1, 2, 3, 4, 5] # Rotate left by 2 k = 2 left_rotated = nums[k:] + nums[:k] print(left_rotated) # [3, 4, 5, 1, 2] # Rotate right by 2 right_rotated = nums[-k:] + nums[:-k] print(right_rotated) # [4, 5, 1, 2, 3] # In-place rotation (using reverse trick) def rotate_left(arr, k): k = k % len(arr) arr[:k], arr[k:] = arr[k:], arr[:k] # Deque is more efficient for rotations from collections import deque d = deque([1, 2, 3, 4, 5]) d.rotate(-2) # Left by 2 print(list(d)) # [3, 4, 5, 1, 2]

Practical: Chunking a List

Split a list into fixed-size chunks using slicing. Useful for batch processing, pagination, or dividing work.

Python
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # Chunk into groups of 3 chunk_size = 3 chunks = [data[i:i+chunk_size] for i in range(0, len(data), chunk_size)] print(chunks) # [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]] # Split into n equal parts def split_list(lst, n): size = len(lst) // n return [lst[i*size:(i+1)*size] for i in range(n)] parts = split_list(data, 3) print(parts) # [[1,2,3], [4,5,6], [7,8,9]]

Performance Summary

Know your complexities for efficient code. Append/pop from end: O(1). Insert/remove/pop(0): O(n). Slicing: O(k). Use deque for O(1) operations at both ends.

Python
# TIME COMPLEXITY CHEAT SHEET # # Operation | Time | Notes # -------------------|----------|------------------ # list[i] | O(1) | Direct access # list.append(x) | O(1) | Amortized # list.pop() | O(1) | From end # list.pop(0) | O(n) | Shifts all! # list.insert(i, x) | O(n) | Shifts right # list.remove(x) | O(n) | Search + shift # x in list | O(n) | Linear scan # list[a:b] | O(b-a) | Copy slice # list.sort() | O(n log n) | TimSort # list.reverse() | O(n) | In-place

Master this concept

Hands-on practice is the fastest way to learn. Head over to our interactive workspace to solve this topic's challenge.

Launch Editor