A list is Python's most versatile data structure: an ordered, changeable collection that can hold items of different data types. Lists are written as a comma-separated sequence of values enclosed in square brackets, such as [10, 20, 30] or ["apple", 42, 3.14, True]. They allow a single variable name to refer to a collection of many values, which is essential for handling data such as marks of a class, names of students, or prices of products.
The single most important property of lists is that they are mutable: elements can be added, removed, changed and reordered after the list is created. This is in sharp contrast to strings, which are immutable. Because lists are mutable, they can be modified in place, and when a list is passed to a function, the function can alter the original list. Lists therefore demand careful thinking about aliasing and references.
As sequences, lists support the familiar operations of indexing, slicing, concatenation, repetition and membership testing, just like strings. On top of these, lists provide a rich set of methods such as append(), insert(), remove(), pop(), sort(), reverse() and index(). The chapter also covers list comprehension, a concise Python idiom for building new lists from existing ones, and common list-processing programs such as finding the largest value, computing sums and searching for elements.
A list is created by enclosing items in square brackets and separating them with commas.
marks = [85, 92, 78, 66, 90]
names = ["Aarav", "Meera", "Karan"]
mixed = [10, "Hello", 3.14, True]
empty = []
nested = [[1, 2], [3, 4]]
Important properties:
Like strings, lists use zero-based indexing. Positive indices count from the start, negative indices count from the end.
lst = [10, 20, 30, 40, 50]
print(lst[0]) # 10
print(lst[3]) # 40
print(lst[-1]) # 50
print(lst[-2]) # 40
Slicing works the same way as for strings and returns a new list.
lst = [10, 20, 30, 40, 50]
print(lst[1:4]) # [20, 30, 40]
print(lst[:3]) # [10, 20, 30]
print(lst[::2]) # [10, 30, 50]
Unlike strings, list elements can be changed in place using index assignment, and items can be added or removed.
lst = [1, 2, 3]
lst[0] = 100 # [100, 2, 3]
lst[1:3] = [200, 300] # replace a slice
print(lst) # [100, 200, 300]
This mutability is the main difference from strings, and it is what makes lists so flexible for data storage and processing.
A for loop can traverse a list either by value or by index.
lst = [10, 20, 30]
for item in lst: # by value
print(item)
for i in range(len(lst)): # by index
print(i, lst[i])
Traversal is used for computing totals, averages, maximums and other aggregate operations.
Lists support several operators:
print([1, 2] + [3, 4]) # [1, 2, 3, 4]
print([0] * 3) # [0, 0, 0]
print(3 in [1, 2, 3]) # True
print(5 not in [1, 2]) # True
The following built-in functions work on lists:
marks = [85, 92, 78]
print(len(marks)) # 3
print(max(marks)) # 92
print(min(marks)) # 78
print(sum(marks)) # 255
print(sorted(marks, reverse=True)) # [92, 85, 78]
List methods provide powerful ways to modify and inspect lists.
lst = [3, 1, 2]
lst.append(4) # [3, 1, 2, 4]
lst.insert(0, 0) # [0, 3, 1, 2, 4]
lst.sort() # [0, 1, 2, 3, 4]
lst.reverse() # [4, 3, 2, 1, 0]
popped = lst.pop() # popped = 0
lst.remove(2) # removes 2
Unlike strings, methods like sort() and reverse() modify the list in place and return None, so they must not be assigned to a variable.
A nested list is a list whose elements are themselves lists. This is the natural way to represent two-dimensional data such as a matrix or a table of records.
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix[0]) # [1, 2, 3]
print(matrix[1][2]) # 6
print(len(matrix)) # 3 (number of rows)
Nested lists can be processed with nested loops, exactly as in the flow-of-control chapter.
A list comprehension is a concise way to create a new list by applying an expression to each element of an existing iterable, optionally filtering with a condition.
squares = [x ** 2 for x in range(1, 6)]
print(squares) # [1, 4, 9, 16, 25]
evens = [x for x in range(1, 11) if x % 2 == 0]
print(evens) # [2, 4, 6, 8, 10]
upper = [ch.upper() for ch in "hello"]
print(upper) # ['H', 'E', 'L', 'L', 'O']
The general form is [expression for variable in iterable if condition]. The if clause is optional and filters the elements.
marks = [85, 92, 78, 66, 90]
average = sum(marks) / len(marks)
print("Average:", average)
lst = [12, 45, 3, 78, 34]
largest = lst[0]
for num in lst:
if num > largest:
largest = num
print("Largest:", largest)
lst = [10, 20, 30, 40]
target = int(input("Enter value to search: "))
if target in lst:
print("Found at index", lst.index(target))
else:
print("Not found")
| Operation | List Example | Result |
|---|---|---|
| Indexing | [10,20][0] | 10 |
| Slicing | [10,20,30][1:] | [20, 30] |
| Concatenation | [1]+[2] | [1, 2] |
| Repetition | [0]*3 | [0, 0, 0] |
| Membership | 2 in [1,2] | True |
| Mutation | lst[0]=9 | Allowed (mutable) |
| Method | Action | Example |
|---|---|---|
| append(x) | Add x at end | [1].append(2) -> [1,2] |
| insert(i, x) | Insert x at index i | [1,3].insert(1,2) -> [1,2,3] |
| pop(i) | Remove and return item | [1,2,3].pop() -> 3 |
| remove(x) | Remove first occurrence of x | [1,2,1].remove(1) -> [2,1] |
| sort() | Sort in place | [3,1].sort() -> [1,3] |
| reverse() | Reverse in place | [1,2].reverse() -> [2,1] |
Lists are the workhorse data structure of Python: ordered, mutable and able to hold any mixture of data. They reuse the elegant sequence concepts of indexing, slicing and operators from strings, while adding the crucial ability to change contents in place through a powerful set of methods. Nested lists model two-dimensional data, and list comprehension provides a concise, readable way to generate new lists. Mastery of lists unlocks the processing of collections of data, which is at the heart of nearly every real program. The next chapter covers tuples, the immutable cousin of lists, and dictionaries, which organise data as key-value pairs.