DocsHub
Data Structures

Lists

Learn how to create, access, modify, and work with lists in Python.

Lists

A list is an ordered collection of items. It can hold anything — numbers, strings, booleans, even other lists — all in one place. Items stay in the order you put them, and you can change the list anytime — add things, remove things, rearrange things.

fruits = ["apple", "banana", "mango"]
numbers = [1, 2, 3, 4, 5]
mixed = ["Ali", 22, True, 3.14]

Lists are one of the most used things in all of Python. Understanding them well makes everything else easier.


Creating a list

# empty list
items = []

# list with values
names = ["Ali", "Sara", "Omar"]

# list of numbers
scores = [88, 92, 79, 95]

# mixed types
profile = ["Ali", 22, True]

# list from range
numbers = list(range(1, 6))
print(numbers)   # [1, 2, 3, 4, 5]

Accessing items — indexing

Every item in a list has a position called an index. Python starts counting from 0.

fruits = ["apple", "banana", "mango", "orange", "grape"]
#           0         1         2        3         4
print(fruits[0])   # apple
print(fruits[1])   # banana
print(fruits[4])   # grape

Negative indexing — count from the end:

print(fruits[-1])   # grape  — last item
print(fruits[-2])   # orange — second to last
print(fruits[-5])   # apple  — same as index 0

Negative indexing is useful when you want the last item but do not know the length.

Accessing an index that does not exist raises an IndexError:

fruits = ["apple", "banana", "mango"]
print(fruits[5])   # IndexError: list index out of range

Slicing — getting multiple items

Slicing lets you grab a portion of a list. The result is a new list.

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

print(fruits[1:4])    # ['banana', 'mango', 'orange']
print(fruits[0:3])    # ['apple', 'banana', 'mango']
print(fruits[2:])     # ['mango', 'orange', 'grape'] — from index 2 to end
print(fruits[:3])     # ['apple', 'banana', 'mango'] — from start to index 3
print(fruits[:])      # ['apple', 'banana', 'mango', 'orange', 'grape'] — full copy

The format is list[start:stop] — start is included, stop is not.

Step in slicing:

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

print(numbers[::2])     # [0, 2, 4, 6, 8] — every second item
print(numbers[1::2])    # [1, 3, 5, 7, 9] — every second item starting at 1
print(numbers[::-1])    # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] — reversed

Changing items

Lists are mutable — you can change their contents after creating them.

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

fruits[1] = "grape"
print(fruits)   # ['apple', 'grape', 'mango']

Change multiple items using a slice:

numbers = [1, 2, 3, 4, 5]
numbers[1:3] = [20, 30]
print(numbers)   # [1, 20, 30, 4, 5]

List methods

This is where lists get really powerful. Python gives you a set of built-in methods to work with lists.


append() — add one item to the end

fruits = ["apple", "banana"]

fruits.append("mango")
print(fruits)   # ['apple', 'banana', 'mango']

insert() — add an item at a specific position

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

fruits.insert(1, "grape")
print(fruits)   # ['apple', 'grape', 'banana', 'mango']

insert(index, value) — pushes everything from that index forward.


extend() — add multiple items to the end

fruits = ["apple", "banana"]
more_fruits = ["mango", "grape", "orange"]

fruits.extend(more_fruits)
print(fruits)   # ['apple', 'banana', 'mango', 'grape', 'orange']

The difference between append and extend:

fruits = ["apple", "banana"]

fruits.append(["mango", "grape"])
print(fruits)   # ['apple', 'banana', ['mango', 'grape']] — list inside a list

fruits = ["apple", "banana"]

fruits.extend(["mango", "grape"])
print(fruits)   # ['apple', 'banana', 'mango', 'grape'] — items added individually

append() adds the thing itself — even if it is a list. extend() unpacks it and adds each item individually.


remove() — remove by value

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

fruits.remove("banana")
print(fruits)   # ['apple', 'mango', 'banana']

remove() only removes the first occurrence. If the value is not in the list, it raises a ValueError.


pop() — remove by index and return it

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

removed = fruits.pop(1)
print(removed)   # banana
print(fruits)    # ['apple', 'mango']

With no argument, pop() removes and returns the last item:

last = fruits.pop()
print(last)    # mango
print(fruits)  # ['apple']

del — remove by index or slice

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

del fruits[1]
print(fruits)   # ['apple', 'mango', 'orange', 'grape']

del fruits[1:3]
print(fruits)   # ['apple', 'grape']

clear() — remove everything

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

fruits.clear()
print(fruits)   # []

index() — find the position of a value

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

print(fruits.index("banana"))   # 1
print(fruits.index("mango"))    # 2

Raises ValueError if the value is not found.


count() — count how many times a value appears

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

print(numbers.count(2))   # 3
print(numbers.count(9))   # 0

sort() — sort the list in place

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

numbers.sort()
print(numbers)   # [1, 1, 2, 3, 4, 5, 6, 9]

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

Sort strings alphabetically:

names = ["Omar", "Ali", "Sara", "Fatima"]

names.sort()
print(names)   # ['Ali', 'Fatima', 'Omar', 'Sara']

sort() changes the list itself — it does not return a new list. If you want a sorted copy without changing the original, use sorted() instead:

numbers = [3, 1, 4, 1, 5]
sorted_numbers = sorted(numbers)

print(numbers)         # [3, 1, 4, 1, 5] — unchanged
print(sorted_numbers)  # [1, 1, 3, 4, 5] — new sorted list

reverse() — reverse the list in place

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

fruits.reverse()
print(fruits)   # ['mango', 'banana', 'apple']

copy() — make a shallow copy

original = [1, 2, 3]
copy = original.copy()

copy.append(4)

print(original)   # [1, 2, 3] — unchanged
print(copy)       # [1, 2, 3, 4]

Without .copy(), both variables point to the same list:

original = [1, 2, 3]
copy = original        # not a copy — same list

copy.append(4)

print(original)   # [1, 2, 3, 4] — changed too!
print(copy)       # [1, 2, 3, 4]

Useful built-in functions for lists

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

print(len(numbers))    # 8  — number of items
print(min(numbers))    # 1  — smallest value
print(max(numbers))    # 9  — largest value
print(sum(numbers))    # 31 — total of all values

Checking if an item exists

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

print("banana" in fruits)      # True
print("grape" in fruits)       # False
print("grape" not in fruits)   # True

Looping over a list

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

for fruit in fruits:
    print(fruit)

With index using enumerate():

for index, fruit in enumerate(fruits, start=1):
    print(f"{index}. {fruit}")

Output:

1. apple
2. banana
3. mango

Nested lists

A list can contain other lists. This is useful for representing grids, tables, or matrices.

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

print(matrix[0])      # [1, 2, 3] — first row
print(matrix[1][2])   # 6 — row 1, column 2

Loop over a nested list:

for row in matrix:
    for item in row:
        print(item, end=" ")
    print()

Output:

1 2 3
4 5 6
7 8 9

A real example

A simple student gradebook:

students = ["Ali", "Sara", "Omar", "Fatima"]
scores =   [88,    95,     72,     61]

passing = []
failing = []

for student, score in zip(students, scores):
    if score >= 70:
        passing.append(student)
    else:
        failing.append(student)

print(f"Passing: {passing}")
print(f"Failing: {failing}")
print(f"Class average: {sum(scores) / len(scores):.1f}")

Output:

Passing: ['Ali', 'Sara', 'Omar']
Failing: ['Fatima']
Class average: 79.0

Summary

MethodWhat it does
append(x)Add x to the end
insert(i, x)Add x at index i
extend(list)Add all items from another list
remove(x)Remove first occurrence of x
pop(i)Remove and return item at index i
clear()Remove all items
index(x)Return index of x
count(x)Count occurrences of x
sort()Sort in place
reverse()Reverse in place
copy()Return a shallow copy

On this page