Lists — Organizing and Storing Sequences of Data

Lists are one of the most **versatile, powerful, and frequently used data structures in Python**.

Chapter 3: Data Structures

Sub-chapter: Lists — Organizing and Storing Sequences of Data

Lists are one of the most versatile, powerful, and frequently used data structures in Python.
They allow you to store ordered collections of items (of any type), modify them, and perform operations like sorting, slicing, and filtering with ease.

Think of a list as a flexible container — it can grow, shrink, and adapt to the data you’re working with.


🧠 What Is a List?

A list in Python is an ordered, mutable sequence of items.
Each element can be of any data type — even a mix of types in the same list.

fruits = ["apple", "banana", "orange"]
numbers = [10, 20, 30, 40]
mixed = ["hello", 42, 3.14, True]

⚙️ Creating Lists

Lists are created using square brackets [] or the built-in list() function.

# Using brackets
colors = ["red", "green", "blue"]

# Using list() constructor
numbers = list((1, 2, 3, 4))

Empty lists can be created as:

empty = []
empty2 = list()

🎯 Accessing and Modifying Elements

Python lists are zero-indexed — the first element has index 0.

fruits = ["apple", "banana", "cherry"]
print(fruits[0])  # apple
print(fruits[-1]) # cherry (last element)

Lists are mutable, so you can change elements by assignment:

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

🧩 Adding and Removing Elements

Python provides many methods to modify lists dynamically.

MethodDescriptionExample
append(x)Add element x to the endlst.append(5)
insert(i, x)Insert x at position ilst.insert(1, "new")
extend(iterable)Append all items from another iterablelst.extend([4,5,6])
remove(x)Remove first occurrence of xlst.remove(10)
pop(i)Remove and return item at index ilst.pop(2)
clear()Remove all elementslst.clear()
del lst[i]Delete item at index idel lst[1]

Example:

numbers = [1, 2, 3]
numbers.append(4)
numbers.insert(1, 10)
numbers.remove(2)
popped = numbers.pop()  # removes last element
print(numbers, popped)

Output:

[10, 3] 4

🧮 Getting Information from Lists

FunctionDescription
len(lst)Returns number of elements
min(lst) / max(lst)Smallest / largest element
sum(lst)Sum of numeric elements
lst.index(x)Position of first occurrence
lst.count(x)Number of occurrences of x

Example:

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

✂️ List Slicing and Copying

Slicing allows you to extract a subset of elements from a list.

numbers = [0, 1, 2, 3, 4, 5, 6]
subset = numbers[2:5]   # elements from index 2 to 4
print(subset)           # [2, 3, 4]

Other slice variations:

print(numbers[:4])   # [0, 1, 2, 3] — from start
print(numbers[3:])   # [3, 4, 5, 6] — to end
print(numbers[::2])  # [0, 2, 4, 6] — every 2nd element
print(numbers[::-1]) # [6, 5, 4, 3, 2, 1, 0] — reversed

To copy a list safely (not just reference it):

copy1 = numbers[:]
copy2 = numbers.copy()
copy3 = list(numbers)

⚠️ Using = creates an alias, not a copy. Changes to one affect the other.


🧱 Sorting and Reversing Lists

You can sort lists in place using .sort() or return a sorted copy with sorted().

numbers = [5, 3, 8, 1]
numbers.sort()
print(numbers)  # [1, 3, 5, 8]

Sort descending:

numbers.sort(reverse=True)

Sort using custom key:

words = ["apple", "banana", "cherry"]
words.sort(key=len)  # sort by word length

Reversing order:

numbers.reverse()

Using sorted() (non-destructive):

new_sorted = sorted(numbers)

🔁 Iterating Through Lists

You can iterate over lists easily with for loops.

fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)

With index using enumerate():

for index, fruit in enumerate(fruits):
    print(index, fruit)

🧩 Nested Lists (Lists of Lists)

Lists can contain other lists — great for representing matrices or tables.

matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
print(matrix[1][2])  # 6

Flattening nested lists:

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

🧰 Copying vs Referencing — Mutability in Depth

Lists are mutable, meaning their contents can be modified.
However, this also introduces potential pitfalls.

a = [1, 2, 3]
b = a  # both refer to the same list
b.append(4)
print(a)  # [1, 2, 3, 4]

To create a true copy (independent object):

import copy
b = copy.deepcopy(a)

🧮 List Comprehensions (Recap)

List comprehensions are a compact way to build or transform lists.

squares = [x**2 for x in range(1, 6)]
even_squares = [x**2 for x in range(10) if x % 2 == 0]

⚡ Advanced List Operations

Concatenation and Repetition

a = [1, 2, 3]
b = [4, 5]
print(a + b)   # [1, 2, 3, 4, 5]
print(a * 2)   # [1, 2, 3, 1, 2, 3]

Membership Test

fruits = ["apple", "banana"]
print("apple" in fruits)   # True
print("pear" not in fruits)  # True

Min/Max with Key Functions

words = ["python", "is", "awesome"]
longest = max(words, key=len)
print(longest)  # awesome

⚙️ Comparing Python Collections

FeatureListTupleSet
Syntax[1, 2, 3](1, 2, 3){1, 2, 3}
Mutable✅ Yes❌ No✅ Yes (but no duplicates)
Ordered✅ Yes✅ Yes⚠️ Not guaranteed (as of Python 3.7+, insertion order preserved but conceptually unordered)
Duplicates✅ Allowed✅ Allowed❌ Not allowed
PerformanceSlightly slowerFaster (immutable)Optimized for membership tests

🧠 Best Practices for Lists


🧾 Key Takeaways


Lists are the workhorses of Python programming — whether you’re processing user input, aggregating data, or building dynamic structures, lists will be your most used and most flexible companion.