🎉 75% of content is free forever — Unlock Premium from $10/mo →
CW
NEWSLIVESearch All Content
💼 Servicesℹ️ About✉️ ContactView Pricing Plansfrom $10

Python Lists — The Complete Guide to Python's Most Versatile Data Structure

Python BasicsLists🟢 Free Lesson

Advertisement

Python Lists — The Complete Guide

💡 Lists are the most widely used data structure in Python. This comprehensive guide covers everything from basic creation to advanced techniques, giving you complete mastery over Python's most versatile collection type.

Learning Objectives

By the end of this tutorial, you will be able to:

  • Create lists using various methods and understand when to use each
  • Use indexing and slicing to access and manipulate list elements
  • Apply all built-in list methods confidently
  • Use all related built-in functions: len(), min(), max(), sum(), sorted(), reversed(), enumerate(), zip(), map(), filter(), any(), all()
  • Write basic and intermediate list comprehensions
  • Understand nested lists and 2D data structures
  • Recognize performance implications of different operations
  • Avoid common pitfalls that trip up Python developers

What Are Lists?

A list is an ordered, mutable collection in Python. Think of it as a container that holds multiple items in a specific sequence.

python
mixed = [42, "hello", 3.14, True, None, [1, 2, 3]]
print(mixed)
# Output: [42, 'hello', 3.14, True, None, [1, 2, 3]]

Key Characteristics

CharacteristicDescriptionExample
OrderedElements maintain their insertion order[1, 2, 3] is different from [3, 2, 1]
MutableElements can be changed after creationlst[0] = 99 works fine
DynamicCan grow or shrink at runtimelst.append(4) adds an element
HeterogeneousCan mix different types[1, "two", 3.0] is valid
Duplicates allowedSame value can appear multiple times[1, 1, 2, 3] is valid
Zero-indexedFirst element is at index 0lst[0] gets the first item

Creating Lists

1. Literal Syntax (Most Common)

python
empty = []
fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "two", 3.0, True]

2. The list() Constructor

python
chars = list("Python")        # ['P', 'y', 't', 'h', 'o', 'n']
numbers = list(range(1, 6))    # [1, 2, 3, 4, 5]
from_tuple = list((10, 20, 30))  # [10, 20, 30]

3. List Multiplication

python
zeros = [0] * 5         # [0, 0, 0, 0, 0]
pattern = [0, 1] * 4    # [0, 1, 0, 1, 0, 1, 0, 1]

# WARNING: Be careful with mutable objects
nested = [[0]] * 3
nested[0][0] = 99
print(nested)  # [[99], [99], [99]] — All sublists are the same object!

4. List Comprehension

python
squares = [x**2 for x in range(5)]
print(squares)  # [0, 1, 4, 9, 16]

evens = [x for x in range(10) if x % 2 == 0]
print(evens)  # [0, 2, 4, 6, 8]

Indexing and Slicing

python
fruits = ["apple", "banana", "cherry", "date", "elderberry"]
#           0        1        2        3         4

print(fruits[0])   # apple
print(fruits[2])   # cherry
print(fruits[-1])  # elderberry

# Slicing
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(numbers[2:5])     # [2, 3, 4]
print(numbers[:4])      # [0, 1, 2, 3]
print(numbers[6:])      # [6, 7, 8, 9]
print(numbers[::2])     # [0, 2, 4, 6, 8]
print(numbers[::-1])    # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Slice Assignment (Mutating Slices)

python
letters = ['a', 'b', 'c', 'd', 'e']
letters[1:3] = ['B', 'C', 'D']  # Replace 2 elements with 3
print(letters)  # ['a', 'B', 'C', 'D', 'd', 'e']

letters[1:1] = ['X', 'Y']  # Insert before index 1
print(letters)  # ['a', 'X', 'Y', 'B', 'C', 'D', 'd', 'e']

letters[2:5] = []  # Remove elements at indices 2, 3, 4
print(letters)  # ['a', 'X', 'B', 'd', 'e']

All List Methods

Adding Elements

MethodDescriptionTime Complexity
append(x)Add x to the endO(1) amortized
extend(iterable)Add all items from iterableO(k)
insert(i, x)Insert x at position iO(n)
python
# append() — adds a single element to the end
fruits = ["apple", "banana"]
fruits.append("cherry")
print(fruits)  # ['apple', 'banana', 'cherry']

# append a list as a single element
fruits.append(["date", "elderberry"])
print(fruits)  # ['apple', 'banana', 'cherry', ['date', 'elderberry']]

# extend() — adds multiple elements from an iterable
fruits = ["apple", "banana"]
fruits.extend(["cherry", "date"])
print(fruits)  # ['apple', 'banana', 'cherry', 'date']

# extend vs append
a = [1, 2]
a.extend([3, 4])  # Adds 3 and 4 as separate elements
print(a)  # [1, 2, 3, 4]

b = [1, 2]
b.append([3, 4])  # Adds [3, 4] as a single element
print(b)  # [1, 2, [3, 4]]

# insert() — adds element at a specific position
names = ["Alice", "Bob", "David"]
names.insert(2, "Charlie")  # Insert "Charlie" at index 2
print(names)  # ['Alice', 'Bob', 'Charlie', 'David']

names.insert(0, "Zara")  # Insert at the beginning
print(names)  # ['Zara', 'Alice', 'Bob', 'Charlie', 'David']

Removing Elements

MethodDescriptionTime Complexity
remove(x)Remove first occurrence of xO(n)
pop(i)Remove and return element at index iO(n) for i≠-1, O(1) for i=-1
del lst[i]Remove element at index iO(n)
clear()Remove all elementsO(n)
python
# remove() — removes first occurrence of a value
colors = ["red", "blue", "green", "blue"]
colors.remove("blue")
print(colors)  # ['red', 'green', 'blue']

# pop() — removes and returns element at index
stack = [10, 20, 30, 40, 50]
last = stack.pop()
print(last)   # 50
print(stack)  # [10, 20, 30, 40]

second = stack.pop(1)
print(second)  # 20

# del — keyword for removing elements
data = [10, 20, 30, 40, 50]
del data[2]       # Remove element at index 2
del data[1:3]     # Remove a slice
del data[:]       # Clear the list

# clear() — remove all elements
items = [1, 2, 3, 4, 5]
items.clear()
print(items)  # []

Searching

MethodDescriptionTime Complexity
index(x)Return index of first occurrence of xO(n)
count(x)Count occurrences of xO(n)
x in lstCheck if x is in the listO(n)
python
# index() — find position of an element
primes = [2, 3, 5, 7, 11, 13, 17]
print(primes.index(7))   # 3
print(primes.index(13))  # 5

# count() — how many times does a value appear?
data = [1, 2, 2, 3, 2, 4, 2]
print(data.count(2))  # 4
print(data.count(5))  # 0

# The 'in' operator
fruits = ["apple", "banana", "cherry"]
print("banana" in fruits)   # True
print("grape" in fruits)    # False

Sorting

Method/FunctionDescriptionReturns
lst.sort()Sort list in-placeNone
sorted(lst)Return new sorted listNew list
lst.sort(key=fn)Sort with custom keyNone
lst.sort(reverse=True)Sort descendingNone
reversed(lst)Return reverse iteratorIterator
lst.reverse()Reverse in-placeNone
python
# sort() — in-place sorting
scores = [85, 92, 78, 95, 88]
scores.sort()
print(scores)  # [78, 85, 88, 92, 95]

scores.sort(reverse=True)
print(scores)  # [95, 92, 88, 85, 78]

# sorted() — returns a new sorted list
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
new_sorted = sorted(numbers)
print(numbers)     # [3, 1, 4, 1, 5, 9, 2, 6] — unchanged
print(new_sorted)  # [1, 1, 2, 3, 4, 5, 6, 9]

# Sorting with a key function
words = ["banana", "apple", "cherry", "date"]
words.sort(key=len)  # Sort by string length
print(words)  # ['date', 'apple', 'banana', 'cherry']

# Case-insensitive sorting
names = ["charlie", "Alice", "bob"]
names.sort(key=str.lower)
print(names)  # ['Alice', 'bob', 'charlie']

# Sort by specific attribute
students = [("Alice", 85), ("Bob", 92), ("Charlie", 78)]
students.sort(key=lambda student: student[1])
print(students)  # [('Charlie', 78), ('Alice', 85), ('Bob', 92)]

# reversed() — returns an iterator
nums = [1, 2, 3]
rev = reversed(nums)
print(list(rev))  # [3, 2, 1]
print(nums)       # [1, 2, 3] — unchanged

# reverse() — in-place reversal
nums = [1, 2, 3]
nums.reverse()
print(nums)  # [3, 2, 1]

Other Methods

python
# copy() — create a shallow copy
original = [1, 2, 3, [4, 5]]
copied = original.copy()
copied[0] = 99
print(original)  # [1, 2, 3, [4, 5]] — unchanged

# But shallow copy has caveats with nested objects
copied[3][0] = 99
print(original)  # [1, 2, 3, [99, 5]] — nested list is shared!

Related Built-In Functions

len() — Number of Elements

python
numbers = [4, 2, 7, 1, 9, 3]
print(len(numbers))  # 6

words = ["apple", "banana", "cherry"]
print(len(words))    # 3

print(len([]))       # 0

min() and max() — Minimum and Maximum

python
numbers = [4, 2, 7, 1, 9, 3]
print(min(numbers))  # 1
print(max(numbers))  # 9

# With strings (lexicographic)
words = ["apple", "banana", "cherry"]
print(min(words))  # 'apple'
print(max(words))  # 'cherry'

# With key function
students = [("Alice", 85), ("Bob", 92), ("Charlie", 78)]
print(min(students, key=lambda s: s[1]))  # ('Charlie', 78)
print(max(students, key=lambda s: s[1]))  # ('Bob', 92)

sum() — Sum of Elements

python
numbers = [1, 2, 3, 4, 5]
print(sum(numbers))  # 15

# With start value
print(sum(numbers, 10))  # 25

# Sum of booleans (True=1, False=0)
booleans = [True, False, True, True, False]
print(sum(booleans))  # 3

sorted() — Return New Sorted List

python
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print(sorted(numbers))  # [1, 1, 2, 3, 4, 5, 6, 9]

# With key
words = ["banana", "apple", "cherry"]
print(sorted(words, key=len))  # ['apple', 'banana', 'cherry']

# With reverse
print(sorted(numbers, reverse=True))  # [9, 6, 5, 4, 3, 2, 1, 1]

reversed() — Return Reverse Iterator

python
numbers = [1, 2, 3, 4, 5]
rev = reversed(numbers)
print(list(rev))  # [5, 4, 3, 2, 1]
print(numbers)    # [1, 2, 3, 4, 5] — unchanged

# Useful in for loops
for num in reversed([1, 2, 3, 4, 5]):
    print(num, end=" ")
# 5 4 3 2 1

enumerate() — Index and Value Pairs

python
fruits = ["apple", "banana", "cherry"]

for index, fruit in enumerate(fruits):
    print(f"{index}: {fruit}")
# 0: apple
# 1: banana
# 2: cherry

# With custom start
for index, fruit in enumerate(fruits, start=1):
    print(f"{index}. {fruit}")
# 1. apple
# 2. banana
# 3. cherry

zip() — Combine Multiple Iterables

python
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
grades = ["A", "A+", "B+"]

# Zip two lists
for name, score in zip(names, scores):
    print(f"{name}: {score}")

# Zip three lists
for name, score, grade in zip(names, scores, grades):
    print(f"{name}: {score} ({grade})")

# Convert to list of tuples
pairs = list(zip(names, scores))
print(pairs)  # [('Alice', 85), ('Bob', 92), ('Charlie', 78)]

map() — Apply Function to Each Element

python
numbers = [1, 2, 3, 4, 5]

# Square each number
squared = list(map(lambda x: x**2, numbers))
print(squared)  # [1, 4, 9, 16, 25]

# With multiple iterables
a = [1, 2, 3]
b = [10, 20, 30]
sums = list(map(lambda x, y: x + y, a, b))
print(sums)  # [11, 22, 33]

# Convert strings to integers
str_nums = ["1", "2", "3", "4", "5"]
int_nums = list(map(int, str_nums))
print(int_nums)  # [1, 2, 3, 4, 5]

filter() — Keep Elements Where Function Returns True

python
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Keep even numbers
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # [2, 4, 6, 8, 10]

# Keep strings longer than 3 characters
words = ["hi", "hello", "hey", "howdy", "yo"]
long_words = list(filter(lambda w: len(w) > 3, words))
print(long_words)  # ['hello', 'howdy']

# Filter out None values
data = [1, None, 2, None, 3]
clean = list(filter(None, data))
print(clean)  # [1, 2, 3]

any() and all() — Boolean Checks

python
numbers = [0, 1, 2, 3, 4]
print(any(numbers))  # True — at least one truthy value
print(all(numbers))  # False — not all truthy (0 is falsy)

numbers = [1, 2, 3, 4, 5]
print(all(numbers))  # True — all truthy

# With conditions
words = ["hello", "world", "python"]
print(all(len(w) > 3 for w in words))  # True
print(any(len(w) > 10 for w in words))  # False

# Check if any element meets condition
students = [("Alice", 85), ("Bob", 92), ("Charlie", 78)]
print(any(score >= 90 for _, score in students))  # True
print(all(score >= 90 for _, score in students))  # False

List Comprehensions

Basic Syntax

python
squares = [x**2 for x in range(10)]
print(squares)  # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Filtering with Conditions

python
evens = [x for x in range(20) if x % 2 == 0]
print(evens)  # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

long_words = [word.upper() for word in ["hi", "hello", "hey", "howdy"] if len(word) > 2]
print(long_words)  # ['HELLO', 'HOWDY']

Nested Comprehensions

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

identity = [[1 if i == j else 0 for j in range(3)] for i in range(3)]
print(identity)  # [[1, 0, 0], [0, 1, 0], [0, 0, 1]]

Conditional Expressions (Ternary)

python
labels = ["even" if x % 2 == 0 else "odd" for x in range(5)]
print(labels)  # ['even', 'odd', 'even', 'odd', 'even']

Nested Lists

python
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

print(matrix[0][0])  # 1
print(matrix[1][2])  # 6

# Matrix addition
A = [[1, 2], [3, 4]]
B = [[5, 6], [7, 8]]
C = [[A[i][j] + B[i][j] for j in range(2)] for i in range(2)]
print(C)  # [[6, 8], [10, 12]]

# Transpose
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = [[row[i] for row in matrix] for i in range(3)]
print(transposed)  # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

Deep Copy vs Shallow Copy

python
import copy

original = [[1, 2, 3], [4, 5, 6]]

# Shallow copy — nested objects are shared
shallow = original.copy()
shallow[0][0] = 99
print(original[0][0])  # 99 — original is affected!

# Deep copy — everything is copied
original = [[1, 2, 3], [4, 5, 6]]
deep = copy.deepcopy(original)
deep[0][0] = 99
print(original[0][0])  # 1 — original is safe

Lists vs Other Sequences

Lists vs Tuples

FeatureList []Tuple ()
MutableYesNo
Syntax[1, 2, 3](1, 2, 3)
PerformanceSlightly slowerSlightly faster
Use caseDynamic collectionsFixed records
Dictionary keyNoYes (if hashable)

Lists vs Generators

FeatureListGenerator
MemoryStores all elementsProduces on demand
IterationMultiple timesSingle pass
IndexingSupports lst[i]No random access
python
import sys

# List — all elements stored in memory
squares_list = [x**2 for x in range(1_000_000)]

# Generator — produces values on demand
squares_gen = (x**2 for x in range(1_000_000))

print(sys.getsizeof(squares_list))  # ~8,448,728 bytes
print(sys.getsizeof(squares_gen))   # ~208 bytes

Common Patterns

Unpacking

python
first, second, *rest = [1, 2, 3, 4, 5]
print(first)   # 1
print(rest)    # [3, 4, 5]

first, _, third, *_ = [1, 2, 3, 4, 5]
print(third)  # 3

# Unpacking in function arguments
def greet(name, age):
    return f"{name} is {age} years old"

person = ["Alice", 30]
print(greet(*person))  # "Alice is 30 years old"

Removing Duplicates (Preserving Order)

python
def remove_duplicates(lst):
    seen = set()
    result = []
    for item in lst:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result

data = [3, 1, 2, 3, 1, 4, 2, 5]
print(remove_duplicates(data))  # [3, 1, 2, 4, 5]

# Simpler approach (Python 3.7+)
unique = list(dict.fromkeys(data))
print(unique)  # [3, 1, 2, 4, 5]

Flattening Nested Lists

python
nested = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
flat = [item for sublist in nested for item in sublist]
print(flat)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

from itertools import chain
flat = list(chain.from_iterable(nested))
print(flat)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

Performance Considerations

OperationTime ComplexityNotes
append(x)O(1) amortizedFast
pop() (from end)O(1)Fast
pop(0) (from start)O(n)Slow — all elements shift
insert(0, x)O(n)Slow — all elements shift
x in lstO(n)Linear search
lst[i]O(1)Random access is fast
len(lst)O(1)Length is cached
sort()O(n log n)Timsort algorithm
copy()O(n)Must copy all elements

When to Use collections.deque

python
from collections import deque

# deque is optimized for append/popleft operations
dq = deque([1, 2, 3])
dq.appendleft(0)  # O(1) — fast regardless of size

# List — O(n) for insert at start
lst = [1, 2, 3]
lst.insert(0, 0)  # Slow for large lists

Common Mistakes

1. Mutable Default Arguments

python
# WRONG
def add_item(item, lst=[]):
    lst.append(item)
    return lst

print(add_item(1))  # [1]
print(add_item(2))  # [1, 2] — unexpected!

# CORRECT
def add_item(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

print(add_item(1))  # [1]
print(add_item(2))  # [2]

2. Modifying While Iterating

python
# WRONG
numbers = [1, 2, 3, 4, 5, 6]
for num in numbers:
    if num % 2 == 0:
        numbers.remove(num)

# CORRECT
numbers = [1, 2, 3, 4, 5, 6]
numbers = [num for num in numbers if num % 2 != 0]

3. == vs is for Lists

python
a = [1, 2, 3]
b = [1, 2, 3]
c = a

print(a == b)   # True — same values
print(a is b)   # False — different objects
print(a is c)   # True — same object

4. Forgetting sort() Returns None

python
numbers = [3, 1, 4, 1, 5]
result = numbers.sort()
print(result)  # None!

# Use sorted() to get a new list
sorted_numbers = sorted(numbers)

Practice Exercises

Exercise 1: Remove Duplicates

python
def remove_duplicates(lst):
    seen = set()
    result = []
    for item in lst:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result

print(remove_duplicates([1, 2, 2, 3, 4, 4, 5]))  # [1, 2, 3, 4, 5]
print(remove_duplicates(["a", "b", "a", "c", "b"]))  # ['a', 'b', 'c']

Exercise 2: Rotate a List

python
def rotate_right(lst, k):
    if not lst:
        return lst
    k = k % len(lst)
    return lst[-k:] + lst[:-k]

print(rotate_right([1, 2, 3, 4, 5], 2))  # [4, 5, 1, 2, 3]
print(rotate_right([1, 2, 3, 4, 5], 7))  # [4, 5, 1, 2, 3]

Exercise 3: Find Common Elements

python
def common_elements(lst1, lst2):
    return list(set(lst1) & set(lst2))

print(common_elements([1, 2, 3, 4, 5], [3, 4, 5, 6, 7]))  # [3, 4, 5]
print(common_elements(["a", "b", "c"], ["b", "c", "d"]))  # ['b', 'c']

Key Takeaways

  1. Lists are ordered, mutable, and can hold any data type — Python's most versatile collection
  2. Use literal syntax [] — faster and more Pythonic than list()
  3. append() vs extend() — append adds one element, extend adds multiple
  4. sort() modifies in-place, sorted() returns a new list — choose based on whether you need to preserve the original
  5. List comprehensions are concise and fast — use them for simple transformations and filters
  6. Watch out for shallow copies with nested lists — use copy.deepcopy() when needed
  7. Avoid mutable default arguments — always use None as the default
  8. Consider performance — insert(0, x) is O(n), use deque for frequent start insertions
  9. Use in for membership testing — but remember it's O(n) for lists
  10. Built-in functions like len(), min(), max(), sum(), sorted(), enumerate(), zip(), map(), filter(), any(), all() make list operations elegant and efficient
—
☆☆☆☆☆
0 ratings

Rate & Feedback

Need Expert Python Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement