Lists
Prerequisites: Variables, data types, operators, loops, conditionals, strings
1. What is a List?
A list is an ordered, mutable collection of items. Items can be of different data types. Lists are one of the most versatile data structures in Python.
# A list can hold different types
mixed = [1, "hello", 3.14, True]
2. Creating Lists
2.1 Using Square Brackets []
empty = []
numbers = [1, 2, 3, 4, 5]
names = ["Alice", "Bob", "Charlie"]
mixed = [1, "two", 3.0, True]
print(numbers)
print(names)
Output:
[1, 2, 3, 4, 5]
['Alice', 'Bob', 'Charlie']
2.2 Using list Function
# Convert string to list
L1 = list("Hello")
print(L1)
# Convert range to list
L2 = list(range(1, 6))
print(L2)
# Convert tuple to list
L3 = list((10, 20, 30))
print(L3)
Output:
['H', 'e', 'l', 'l', 'o']
[1, 2, 3, 4, 5]
[10, 20, 30]
2.3 Using List Comprehension
squares = [x**2 for x in range(1, 6)]
print(squares)
evens = [x for x in range(1, 11) if x % 2 == 0]
print(evens)
Output:
[1, 4, 9, 16, 25]
[2, 4, 6, 8, 10]
3. Indexing
3.1 Positive Indexing (starts at 0)
L = [10, 20, 30, 40, 50]
print(L[0]) # 10
print(L[2]) # 30
print(L[4]) # 50
Output:
10
30
50
3.2 Negative Indexing (starts at -1 from the end)
L = [10, 20, 30, 40, 50]
print(L[-1]) # 50
print(L[-3]) # 30
print(L[-5]) # 10
Output:
50
30
10
3.3 Index Table
List: 10 20 30 40 50
Index: 0 1 2 3 4
Neg: -5 -4 -3 -2 -1
4. Slicing: L[start:stop:step]
Works exactly like string slicing.
L = [10, 20, 30, 40, 50, 60, 70]
print(L[2:5]) # [30, 40, 50]
print(L[:3]) # [10, 20, 30]
print(L[3:]) # [40, 50, 60, 70]
print(L[::2]) # [10, 30, 50, 70]
print(L[::-1]) # [70, 60, 50, 40, 30, 20, 10] (reversed)
print(L[1:6:2]) # [20, 40, 60]
Output:
[30, 40, 50]
[10, 20, 30]
[40, 50, 60, 70]
[10, 30, 50, 70]
[70, 60, 50, 40, 30, 20, 10]
[20, 40, 60]
5. List Operations
5.1 Concatenation (+)
L1 = [1, 2, 3]
L2 = [4, 5, 6]
L3 = L1 + L2
print(L3)
Output:
[1, 2, 3, 4, 5, 6]
5.2 Repetition (*)
L = [0] * 5
print(L)
L2 = [1, 2] * 3
print(L2)
Output:
[0, 0, 0, 0, 0]
[1, 2, 1, 2, 1, 2]
5.3 Membership (in / not in)
L = [10, 20, 30, 40, 50]
print(30 in L) # True
print(35 in L) # False
print(100 not in L) # True
Output:
True
False
True
5.4 Comparison
print([1, 2, 3] == [1, 2, 3]) # True
print([1, 2, 3] == [3, 2, 1]) # False
print([1, 2] < [1, 3]) # True (compares element by element)
Output:
True
False
True
6. Traversing a List
6.1 Using for loop (direct)
L = [10, 20, 30, 40, 50]
for item in L:
print(item, end=" ")
Output:
10 20 30 40 50
6.2 Using for loop with index
L = [10, 20, 30, 40, 50]
for i in range(len(L)):
print(f"L[{i}] = {L[i]}")
Output:
L[0] = 10
L[1] = 20
L[2] = 30
L[3] = 40
L[4] = 50
7. Lists are MUTABLE
Unlike strings, you can change list elements in place.
L = [10, 20, 30, 40, 50]
# Change single element
L[0] = 99
print(L)
# Change a slice
L[1:3] = [200, 300]
print(L)
# Delete using del
del L[4]
print(L)
Output:
[99, 20, 30, 40, 50]
[99, 200, 300, 40, 50]
[99, 200, 300, 40]
Important, aliasing vs copying:
# Aliasing (both variables point to SAME list)
A = [1, 2, 3]
B = A # B is an alias, not a copy
B[0] = 99
print(A) # [99, 2, 3] -- A is also changed!
# Copying (independent copy)
A = [1, 2, 3]
B = A[:] # B is a copy (using slicing)
# or: B = list(A)
# or: B = A.copy
B[0] = 99
print(A) # [1, 2, 3] -- A is unchanged
Output:
[99, 2, 3]
[1, 2, 3]
8. Nested Lists
A list can contain other lists as elements.
matrix = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
# Access element: matrix[row][col]
print(matrix[0]) # [1, 2, 3] (first row)
print(matrix[1][2]) # 6 (row 1, col 2)
print(matrix[2][0]) # 7 (row 2, col 0)
# Traverse nested list
for row in matrix:
for item in row:
print(item, end=" ")
print
Output:
[1, 2, 3]
6
7
1 2 3
4 5 6
7 8 9
9. List Methods
9.1 len, Number of elements
L = [10, 20, 30]
print(len(L))
Output:
3
9.2 list, Convert to list
print(list("ABC"))
print(list(range(5)))
print(list((1, 2, 3)))
Output:
['A', 'B', 'C']
[0, 1, 2, 3, 4]
[1, 2, 3]
9.3 append, Add element at end
Syntax: list.append(element)
L = [1, 2, 3]
L.append(4)
print(L)
L.append([5, 6]) # adds list as single element
print(L)
Output:
[1, 2, 3, 4]
[1, 2, 3, 4, [5, 6]]
9.4 extend, Add all elements of iterable
Syntax: list.extend(iterable)
L = [1, 2, 3]
L.extend([4, 5, 6])
print(L)
L.extend("AB")
print(L)
Output:
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6, 'A', 'B']
Key difference: append adds the argument as a single element; extend adds each element of the argument individually.
9.5 insert, Insert element at specific position
Syntax: list.insert(index, element)
L = [10, 20, 40, 50]
L.insert(2, 30) # insert 30 at index 2
print(L)
L.insert(0, 5) # insert at beginning
print(L)
Output:
[10, 20, 30, 40, 50]
[5, 10, 20, 30, 40, 50]
9.6 count, Count occurrences of element
Syntax: list.count(element)
L = [1, 2, 3, 2, 4, 2, 5]
print(L.count(2))
print(L.count(9))
Output:
3
0
9.7 index, Find position of first occurrence
Syntax: list.index(element[, start[, end]])
L = [10, 20, 30, 20, 40]
print(L.index(20)) # 1 (first occurrence)
print(L.index(20, 2)) # 3 (search from index 2)
# print(L.index(99)) # ValueError: 99 is not in list
Output:
1
3
9.8 remove, Remove first occurrence of element
Syntax: list.remove(element)
L = [10, 20, 30, 20, 40]
L.remove(20) # removes first 20
print(L)
# L.remove(99) # ValueError: list.remove(x): x not in list
Output:
[10, 30, 20, 40]
9.9 pop, Remove and return element at index
Syntax: list.pop([index])
L = [10, 20, 30, 40, 50]
item = L.pop # removes and returns last element
print(item)
print(L)
item = L.pop(1) # removes and returns element at index 1
print(item)
print(L)
Output:
50
[10, 20, 30, 40]
20
[10, 30, 40]
Difference between del, remove, and pop:
del L[i] |
L.remove(val) |
L.pop(i) |
|
|---|---|---|---|
| Works by | Index | Value | Index |
| Returns | Nothing | Nothing | Removed element |
| If not found | IndexError | ValueError | IndexError |
9.10 reverse, Reverse list in place
Syntax: list.reverse
L = [1, 2, 3, 4, 5]
L.reverse
print(L)
Output:
[5, 4, 3, 2, 1]
9.11 sort, Sort list in place
Syntax: list.sort([key][, reverse])
L = [30, 10, 50, 20, 40]
L.sort
print(L)
L.sort(reverse=True)
print(L)
names = ["Charlie", "Alice", "Bob"]
names.sort
print(names)
Output:
[10, 20, 30, 40, 50]
[50, 40, 30, 20, 10]
['Alice', 'Bob', 'Charlie']
9.12 sorted, Return new sorted list (does not change original)
Syntax: sorted(iterable[, key][, reverse])
L = [30, 10, 50, 20, 40]
L2 = sorted(L)
print(L2)
print(L) # original unchanged
Output:
[10, 20, 30, 40, 50]
[30, 10, 50, 20, 40]
Key difference: sort modifies the original list and returns None; sorted returns a new list and keeps the original unchanged.
9.13 min, max, sum
L = [10, 20, 5, 40, 15]
print(min(L))
print(max(L))
print(sum(L))
print(sum(L) / len(L)) # mean/average
Output:
5
40
90
18.0
10. List vs String
| Feature | List | String |
|---|---|---|
| Type | list |
str |
| Mutable? | Yes | No |
| Elements | Any type | Characters only |
| Syntax | [1, 2, 3] |
"abc" |
| Change element | L[0] = 99 |
Not allowed |
| Methods | append, extend, sort, etc. |
upper, lower, split, etc. |
| Common | Indexing, slicing, in, +, *, len |
Same |
11. List Comprehension
A concise way to create lists.
Syntax: [expression for item in iterable if condition]
# Squares of 1 to 5
squares = [x**2 for x in range(1, 6)]
print(squares)
# Even numbers from 1 to 20
evens = [x for x in range(1, 21) if x % 2 == 0]
print(evens)
# First letter of each word
words = ["Hello", "World", "Python"]
initials = [w[0] for w in words]
print(initials)
# Convert all to uppercase
names = ["alice", "bob", "charlie"]
upper_names = [n.upper for n in names]
print(upper_names)
Output:
[1, 4, 9, 16, 25]
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
['H', 'W', 'P']
['ALICE', 'BOB', 'CHARLIE']
12. Practice Programs
Program 1: Find max, min, mean of list
L = eval(input("Enter a list: "))
print("Maximum:", max(L))
print("Minimum:", min(L))
print("Mean:", sum(L) / len(L))
Sample Run:
Enter a list: [10, 20, 30, 40, 50]
Maximum: 50
Minimum: 10
Mean: 30.0
Without built-in functions:
L = eval(input("Enter a list: "))
maximum = minimum = L[0]
total = 0
for item in L:
if item > maximum:
maximum = item
if item < minimum:
minimum = item
total += item
print("Maximum:", maximum)
print("Minimum:", minimum)
print("Mean:", total / len(L))
Program 2: Linear search in list
L = eval(input("Enter a list: "))
item = int(input("Enter element to search: "))
found = False
for i in range(len(L)):
if L[i] == item:
print(f"Element {item} found at index {i}")
found = True
break
if not found:
print(f"Element {item} not found in list")
Sample Run:
Enter a list: [10, 20, 30, 40, 50]
Enter element to search: 30
Element 30 found at index 2
Program 3: Count frequency of elements
L = eval(input("Enter a list: "))
checked = []
for item in L:
if item not in checked:
print(f"{item} appears {L.count(item)} time(s)")
checked.append(item)
Sample Run:
Enter a list: [1, 2, 3, 2, 1, 3, 3]
1 appears 2 time(s)
2 appears 2 time(s)
3 appears 3 time(s)
Program 4: Remove duplicates
L = eval(input("Enter a list: "))
# Method 1: Using new list
result = []
for item in L:
if item not in result:
result.append(item)
print("Without duplicates:", result)
# Method 2: Using set (order may not be preserved in older Python)
# print(list(set(L)))
Sample Run:
Enter a list: [1, 2, 3, 2, 4, 1, 5]
Without duplicates: [1, 2, 3, 4, 5]
Program 5: Swap even and odd index elements
L = eval(input("Enter a list: "))
print("Original:", L)
for i in range(0, len(L) - 1, 2):
L[i], L[i + 1] = L[i + 1], L[i]
print("After swap:", L)
Sample Run:
Enter a list: [1, 2, 3, 4, 5, 6]
Original: [1, 2, 3, 4, 5, 6]
After swap: [2, 1, 4, 3, 6, 5]
Program 6: Flatten nested list
nested = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
flat = []
for sublist in nested:
for item in sublist:
flat.append(item)
print("Nested:", nested)
print("Flat:", flat)
Output:
Nested: [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
Flat: [1, 2, 3, 4, 5, 6, 7, 8, 9]
Using list comprehension:
nested = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
flat = [item for sublist in nested for item in sublist]
print("Flat:", flat)
Program 7: Sort list in ascending/descending
L = eval(input("Enter a list: "))
print("Ascending:", sorted(L))
print("Descending:", sorted(L, reverse=True))
Sample Run:
Enter a list: [30, 10, 50, 20, 40]
Ascending: [10, 20, 30, 40, 50]
Descending: [50, 40, 30, 20, 10]
Program 8: Merge two sorted lists
L1 = eval(input("Enter first sorted list: "))
L2 = eval(input("Enter second sorted list: "))
merged = []
i = j = 0
while i < len(L1) and j < len(L2):
if L1[i] <= L2[j]:
merged.append(L1[i])
i += 1
else:
merged.append(L2[j])
j += 1
# Add remaining elements
merged.extend(L1[i:])
merged.extend(L2[j:])
print("Merged:", merged)
Sample Run:
Enter first sorted list: [1, 3, 5, 7]
Enter second sorted list: [2, 4, 6, 8]
Merged: [1, 2, 3, 4, 5, 6, 7, 8]
Program 9: Second largest element
L = eval(input("Enter a list: "))
largest = second = float('-inf')
for item in L:
if item > largest:
second = largest
largest = item
elif item > second and item != largest:
second = item
if second == float('-inf'):
print("No second largest element")
else:
print("Second largest:", second)
Sample Run:
Enter a list: [10, 20, 30, 40, 50]
Second largest: 40
Simpler approach:
L = eval(input("Enter a list: "))
unique = list(set(L))
unique.sort
print("Second largest:", unique[-2])
Program 10: Split list into even and odd numbers
L = eval(input("Enter a list: "))
even = []
odd = []
for item in L:
if item % 2 == 0:
even.append(item)
else:
odd.append(item)
print("Even numbers:", even)
print("Odd numbers:", odd)
Sample Run:
Enter a list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Even numbers: [2, 4, 6, 8, 10]
Odd numbers: [1, 3, 5, 7, 9]
Using list comprehension:
L = eval(input("Enter a list: "))
even = [x for x in L if x % 2 == 0]
odd = [x for x in L if x % 2 != 0]
print("Even:", even)
print("Odd:", odd)
13. Common Mistakes
| Mistake | Why it is wrong | Correct way |
|---|---|---|
L.append([4,5]) expecting [1,2,3,4,5] |
append adds as single element |
Use L.extend([4,5]) |
L2 = L expecting a copy |
Creates alias (same object) | L2 = L[:] or L2 = L.copy |
L.sort and using return value |
sort returns None |
Use sorted(L) if you need the return |
L.remove(99) without checking |
Raises ValueError if not found | Check if 99 in L: first |
| Modifying list while iterating | Unexpected behavior / skipped items | Iterate over a copy or use list comprehension |
L.pop(99) with invalid index |
IndexError | Check len(L) first |
$1$2 Quick Tips
-
Mutable vs Immutable is the most asked conceptual question. Know that lists are mutable (can be changed in place) unlike strings and tuples.
-
Know the difference between
appendandextend, a very frequent exam question. -
Know the difference between
sortandsorted,sortchanges original, returns None;sortedreturns new list. -
Aliasing trap:
B = Adoes not create a copy. Both point to the same list. UseB = A[:]for a true copy. Exams love to test this. -
List comprehension is a favorite for 1-2 mark questions. Be comfortable reading and writing them.
-
del,remove,pop, know when to use which.popis the only one that returns the removed element. -
For output-prediction questions: Trace through the code step by step, keeping track of the list's state after each operation.
Prefer watching over reading?
Subscribe for free.