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 4print(fruits[0]) # apple
print(fruits[1]) # banana
print(fruits[4]) # grapeNegative 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 0Negative 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 rangeSlicing — 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 copyThe 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] — reversedChanging 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 individuallyappend() 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")) # 2Raises 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)) # 0sort() — 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 listreverse() — 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 valuesChecking if an item exists
fruits = ["apple", "banana", "mango"]
print("banana" in fruits) # True
print("grape" in fruits) # False
print("grape" not in fruits) # TrueLooping 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. mangoNested 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 2Loop 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 9A 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.0Summary
| Method | What 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 |