Lists are Python’s workhorse for ordered collections. They are mutable (you can add, remove, and change items), support indexing and slicing, and work with loops and comprehensions. This guide covers how to create, access, and modify lists, and how to avoid common mistakes. If you have not yet read Data types, start there for the big picture; then use this page for day‑to‑day list usage and Lists vs tuples when you need to choose between them.

1. What a list is and when to use it

A list is an ordered, mutable sequence of values. Order is preserved (the first item stays first until you change it), and you can store any mix of types—integers, strings, other lists, and so on. Use a list when you need a sequence that changes over time: building up results in a loop, reading lines from a file, or holding a queue of tasks. For fixed data that should not change, use a tuple; for unique unordered items, use a set.

2. Creating lists

Use square brackets for literal lists and list() to build a list from another iterable (e.g. a string or range):

# Empty list
my_list = []

# List with items
fruits = ["apple", "banana", "orange"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]

# From another iterable
chars = list("abc")       # ['a', 'b', 'c']
from_range = list(range(5))  # [0, 1, 2, 3, 4]

3. Accessing elements by index

Indices start at 0. Use negative indices to count from the end: -1 is the last item, -2 the second‑to‑last. Accessing an index that does not exist raises IndexError: list index out of range.

fruits = ["apple", "banana", "orange"]

print(fruits[0])    # "apple" (first)
print(fruits[1])    # "banana" (second)
print(fruits[-1])   # "orange" (last)
print(fruits[-2])   # "banana" (second from end)

To loop over a list and also get the index, use enumerate or range(len(...)).

4. Slicing lists

Slicing returns a new list: list[start:stop:step]. start is included, stop is excluded. Omitted start defaults to 0, omitted stop to the end. See Slicing for more.

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

print(numbers[2:5])     # [2, 3, 4]
print(numbers[:3])      # [0, 1, 2] (first 3)
print(numbers[3:])      # [3, 4, 5, 6, 7, 8, 9]
print(numbers[::2])     # [0, 2, 4, 6, 8] (every 2nd)
print(numbers[::-1])    # [9, 8, ..., 0] (reversed)

5. Adding and removing items

append(x) adds one item at the end. insert(i, x) inserts at index i. extend(iterable) adds all items from another sequence. To remove: remove(x) removes the first occurrence of x (raises ValueError if not found); pop(i) removes and returns the item at index i (default last); clear() removes all.

fruits = ["apple", "banana"]
fruits.append("orange")           # ["apple", "banana", "orange"]
fruits.insert(1, "grape")         # ["apple", "grape", "banana", "orange"]
fruits.extend(["kiwi", "mango"])  # adds kiwi, mango

fruits.remove("banana")   # removes first "banana"
last = fruits.pop()       # removes and returns last item
fruits.clear()             # []

6. Useful list methods

count(x) returns how many times x appears. index(x) returns the index of the first occurrence (raises ValueError if not found). sort() and reverse() modify the list in place; for a sorted copy use sorted(list).

numbers = [3, 1, 4, 1, 5, 9, 2, 6]
numbers.count(1)           # 2
numbers.index(4)          # 2
numbers.sort()            # [1, 1, 2, 3, 4, 5, 6, 9]
numbers.sort(reverse=True)
len(numbers)              # 8

7. Concatenation, repetition, and membership

+ concatenates two lists (creating a new list). * n repeats the list n times. in and not in test membership. Multiplying a list by a float causes a TypeError; use integers only.

list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined = list1 + list2      # [1, 2, 3, 4, 5, 6]
repeated = list1 * 3          # [1, 2, 3, 1, 2, 3, 1, 2, 3]
print(2 in list1)             # True

8. List comprehensions

Comprehensions build a list in one expression. They are often clearer and faster than a loop with append. For more patterns see List comprehensions.

squares = [x ** 2 for x in range(5)]           # [0, 1, 4, 9, 16]
evens = [x for x in range(10) if x % 2 == 0]   # [0, 2, 4, 6, 8]

9. Nested lists

Lists can contain other lists (e.g. a matrix). Access with matrix[row][col]. To flatten one level, use a comprehension: [item for row in matrix for item in row].

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

10. Copying lists: shallow vs reference

Assigning new_list = my_list does not copy the list; both names point to the same object. Changing one changes the other. To get a new list with the same items, use my_list.copy(), list(my_list), or my_list[:]. These are shallow copies: if the list contains mutable items (e.g. other lists), those inner objects are shared. For full independence use copy.deepcopy()—see copy vs deepcopy.

original = [1, 2, 3]
ref = original
ref[0] = 99
print(original)   # [99, 2, 3]

copy = original.copy()
copy[0] = 100
print(original)   # [99, 2, 3] (unchanged)

11. Common patterns and pitfalls

Use max(list), min(list), sum(list) for numeric lists. To check if a list is empty, prefer if not my_list: over if len(my_list) == 0:. Do not use a list as a default argument (e.g. def f(x=[])); the same list is reused across calls. Use def f(x=None): x = x or [] instead. See Default arguments and Functions.

12. Next steps

Use lists with loops and conditionals. For key–value data use dictionaries; for immutable sequences use tuples. When you see IndexError or AttributeError (e.g. calling append on a non‑list), check the type of the variable and our Errors section.