Free Study Material

List In Python

Introduction

Every value you've stored so far held one single thing. A list holds many values together, in order, under one single variable name.

Concept

A list is an ordered, mutable collection of values, written inside square brackets [], separated by commas. A list can hold values of different types together, and its elements are reached using indexing and slicing, the same rules as a string.

Worked Example

marks = [78, 85, 92, 67, 74]
mixed = ["Aisha", 16, True]

print(marks)
print(marks[0])
print(marks[-1])
print(marks[1:4])
print(type(marks))

marks is a list of five integers. mixed holds a string, an integer, and a bool together — perfectly legal, a list doesn't require every element to share one type. marks[0] gives 78 (the first element); marks[-1] gives 74 (the last); marks[1:4] gives [85, 92, 67] — a slice, following the "stop is excluded" rule. type(marks) prints <class 'list'>.

Note: A list uses square brackets [ ]. Round brackets ( ) create a different type — a tuple — even though both are ordered collections.

Explanation

Lists exist because most real data naturally comes as a collection, not a single value — a set of five test scores — and a list lets a program work with that entire collection under one name, instead of a separate variable per value.

Summary

A list is an ordered, mutable collection written in square brackets, able to hold mixed data types, accessed using the same indexing and slicing rules as strings.

Definition

A List is a standard Python data type that stores an ordered sequence of items. It is defined by placing items inside square brackets [ ], separated by commas.

The "Big Three" Characteristics:

  • 1. Ordered: Every item has a fixed position (index). The first item is always at index 0.
  • 2. Heterogeneous: Unlike arrays in other languages, a Python list can hold mixed data types (e.g., Integers, Strings, and Floats together).
  • 3. Mutable: This is the most critical feature. You can change, add, or delete items after the list has been created.

Syntax

Method 1: Square Brackets (Recommended)

variable_name = [item1, item2, item3]

Examples:

  • Empty List: empty = []
  • Integers: nums = [10, 20, 30]
  • Mixed: data = ["Amit", 101, 95.5]
# Creating a list of Computer Science topics
topics = ["Python", "SQL", "Networking", "Security"]

# 1. Forward Indexing (0, 1, 2, 3)
print("First Topic [0]:", topics[0])   # Output: Python
print("Third Topic [2]:", topics[2])   # Output: Networking
# 2. Backward Indexing (-1, -2...)
# -1 is always the LAST item
print("Last Topic [-1]:", topics[-1])  # Output: Security
print("Second Last [-2]:", topics[-2]) # Output: Networking
Slicing Syntax: list[start : stop : step]

Note: If you omit 'start', it starts at 0. If you omit 'stop', it goes to the end.

# Our list: ["Python", "SQL", "Networking", "Security"]
# Indices:      0        1          2            3

# Slice from index 1 up to (but not including) 3
sub_group = topics[1:3]

print("Sliced List:", sub_group)
# Output: ['SQL', 'Networking']
# Demonstrating Mutability
prices = [100, 200, 300]
print("Before:", prices)

# Change the middle price (Index 1) to 999
prices[1] = 999

print("After:", prices)
# Output: [100, 999, 300]

Introduction

Lists support the same general operators strings do, plus traversal with a for loop.

Concept

  • Concatenation (+) — joins two lists into a new one.
  • Repetition (*) — repeats a list's elements.
  • Membership (in / not in) — checks whether a value exists in a list.
  • len() — number of elements.
  • Traversal — visiting every element with a for loop.

Worked Example

group_a = [1, 2, 3]
group_b = [4, 5]

print(group_a + group_b)
print(group_a * 2)
print(3 in group_a)

for value in group_a:
    print("Value:", value)

group_a + group_b gives [1, 2, 3, 4, 5]. group_a * 2 gives [1, 2, 3, 1, 2, 3] — the elements repeated twice, not each number doubled. 3 in group_a is True. The for loop then prints each of group_a's three values on its own line.

Note: group_a * 2 repeats the list's elements — it does not multiply each individual number by 2.

Explanation

List traversal with for value in group_a: works exactly like string traversal — one pass per element, in order — the same loop pattern applies to every collection type.

Summary

Lists support +, * (repetition of the whole list, not its values), in/not in, and len(). for element in list: traverses every element in order.

1. Concatenation (+)

The + operator joins two lists end-to-end to create a new list. It does not change the original lists.

list1 + list2  →  combined_list

2. Repetition (*)

The * operator repeats the list items a specific number of times.

list * n  →  repeated_list
# 1. Concatenation (Joining)
# We have two separate teams
team_A = ["Alice", "Bob"]
team_B = ["Charlie", "David"]

# Join them into one big team
all_teams = team_A + team_B

print("Combined:", all_teams)
# Output: ['Alice', 'Bob', 'Charlie', 'David']
# 2. Repetition (Multiplying)
# Create a list of 5 zeros quickly
zeros = [0] * 5

print("Zeros:", zeros)
# Output: [0, 0, 0, 0, 0]
Syntax: item in list_name
# Shopping List
cart = ["Milk", "Eggs", "Bread"]

# Check if 'Eggs' are in the cart
if "Eggs" in cart:
    print("You have Eggs!")

# Check if 'Butter' is missing
if "Butter" not in cart:
    print("Warning: You forgot Butter.")

Method 1: By Element (Read-Only)

Use this when you just want to read or print the items. It is cleaner and easier to write.

Method 2: By Index (Read & Write)

Use this when you need to change the items in the list. You need the index (position number) to update the value.

# Method 1: Direct Access
# Best for printing or reading data
scores = [90, 85, 88]

print("--- Scores ---")
for s in scores:
    print(s)
# Method 2: Index Access
# Goal: Add 5 bonus marks to every score
scores = [90, 85, 88]
n = len(scores) # Total items: 3

print("Original:", scores)

# Loop from 0 to 2
for i in range(n):
    # Update the item at index 'i'
    scores[i] = scores[i] + 5

print("Updated:", scores)
# Output: [95, 90, 93]

Introduction

A list being mutable means it can actually change after creation — this topic covers adding new elements, and overwriting an existing one.

Concept

  • append(value) — adds value as one new element at the end.
  • insert(index, value) — adds value at a specific position, shifting later elements right.
  • extend(other_list) — adds every element of other_list individually onto the end.
  • Modifying — my_list[i] = new_value overwrites the element at that position in place.

Worked Example

fruits = ["apple", "banana"]

fruits.append("mango")
fruits.insert(1, "kiwi")
fruits.extend(["grape", "fig"])
fruits[0] = "orange"

print(fruits)

append("mango") adds it at the end. insert(1, "kiwi") inserts at index 1, pushing later elements over. extend(["grape", "fig"]) adds both as separate elements. fruits[0] = "orange" overwrites the first element in place. The final result: ['orange', 'kiwi', 'banana', 'mango', 'grape', 'fig'].

Warning: fruits.append(["grape", "fig"]) (using append instead of extend) adds the entire two-item list as one single element — append() never unpacks its argument.

Explanation

fruits[0] = "orange" really does change the original list object in memory, with no new list created — exactly the mutability this data type promises, and strings never allow.

Summary

append(value) adds one element at the end; insert(index, value) adds at a position; extend(other_list) adds each element of another list; my_list[i] = new_value overwrites in place — all four change the original list directly.

Syntax

list_name.append(item)

Note: It modifies the list in place and returns None. Do not write L = L.append(x)!

# 1. Using append()
fruits = ["Apple", "Banana"]
print("Original:", fruits)

# Add 'Cherry' to the end
fruits.append("Cherry")

print("After Append:", fruits)
# Output: ['Apple', 'Banana', 'Cherry']

Syntax

list_name.extend(another_list)

It takes an iterable (like a list or tuple) and appends each element to the list.

# 2. Using extend()
bucket_A = ["Red", "Blue"]
bucket_B = ["Green", "Yellow"]

# Pour bucket_B into bucket_A
bucket_A.extend(bucket_B)

print("Extended List:", bucket_A)
# Output: ['Red', 'Blue', 'Green', 'Yellow']
# Comparison
list_1 = [1, 2]
list_2 = [3, 4]

# If we used APPEND:
# list_1.append(list_2)
# Result: [1, 2, [3, 4]]  <- Nested List!

# If we used EXTEND:
# list_1.extend(list_2)
# Result: [1, 2, 3, 4]    <- Flat List

Syntax

list_name.insert(index, item)
  • index: Where you want the new item to sit.
  • item: The value to add.
# 3. Using insert()
ranks = ["First", "Third"]

# Oops, we missed "Second"!
# Insert "Second" at index 1
ranks.insert(1, "Second")

print("Corrected:", ranks)
# Output: ['First', 'Second', 'Third']

Introduction

Just as elements can be added, they can be removed — Python gives four different ways, each suited to a different situation.

Concept

  • remove(value) — removes the first occurrence of value. Raises ValueError if not present.
  • pop(index) — removes and returns the element at index; with no argument, removes the last element.
  • del list[index] — removes the element at index (a statement, returns nothing).
  • clear() — removes every element.

Worked Example

scores = [55, 70, 70, 90, 40]

scores.remove(70)
last = scores.pop()
del scores[0]

print(scores, "| removed:", last)

remove(70) deletes only the first 70 it finds, leaving the second one: [55, 70, 90, 40]. pop() removes and returns the last element, 40, leaving [55, 70, 90]. del scores[0] removes 55, leaving [70, 90]. Final output: [70, 90] | removed: 40.

Note: remove() searches by value; pop() and del act by index. scores.remove(0) would try to delete the value 0, not the element at index 0.

Explanation

pop() is the one removal method that hands back what it deleted — the right choice whenever the removed value is still needed afterwards.

Summary

remove(value) deletes the first matching value; pop(index) deletes by position and returns it; del list[index] deletes by position without returning anything; clear() empties the list completely.

Syntax

list_name.remove(value)

Warning: If the value is NOT found, Python raises a ValueError (Crash). Always check with in first!

# 1. Using remove()
cart = ["Milk", "Bread", "Milk", "Butter"]

# We want to remove 'Milk'
# Only the FIRST 'Milk' (Index 0) is gone
cart.remove("Milk")

print("Cart:", cart)
# Output: ['Bread', 'Milk', 'Butter']

Syntax

variable = list_name.pop(index)

Key Feature: It returns the removed item so you can store it in a variable.

# 2. Using pop()
tasks = ["Homework", "Cleaning", "Cooking"]

# Remove the last item (Cooking) and save it
done_task = tasks.pop()

print("Finished:", done_task) # Output: Cooking
print("Remaining:", tasks)    # Output: ['Homework', 'Cleaning']

# Remove specific index (0)
tasks.pop(0)
print("After removing first task:", tasks) # Output: ['Cleaning']
# 3. Using del and clear()
data = [10, 20, 30, 40, 50]

# Delete index 2 (Value 30)
del data[2]
print("After del:", data) # [10, 20, 40, 50]

# Delete a SLICE (Indices 0 to 2)
del data[0:2]
print("After slice del:", data) # [40, 50]

# Clear everything
data.clear()
print("After clear:", data) # []
Method Action Returns Value?
remove(x) Deletes first 'x' No
pop(i) Deletes index 'i' Yes
del L[i] Deletes index 'i' No

Introduction

Python provides ready-made functions that work on a whole list at once — summarising it, or putting it in order — without a hand-written loop.

Concept

  • len(), min(), max(), sum() — summarise a list.
  • sort() — sorts the list in place (rearranges it permanently, returns nothing).
  • sorted(list) — returns a new, sorted list, leaving the original unchanged.

Both accept reverse=True for descending order.

Worked Example

marks = [67, 92, 45, 88, 71]

print(min(marks), max(marks), sum(marks))

marks.sort()
print(marks)

original = [67, 92, 45]
new_list = sorted(original, reverse=True)
print(original, new_list)

min/max/sum give 45 92 363. marks.sort() rearranges marks itself: [45, 67, 71, 88, 92]. sorted(original, reverse=True) returns a brand-new descending list, [92, 67, 45], while original prints completely unchanged: [67, 92, 45].

Warning: marks.sort() returns None — writing marks = marks.sort() throws away the entire list. sort() changes the list itself; it does not hand back a sorted copy.

Explanation

sort() and sorted() do the same job but disagree on what they touch: sort() changes its own list and returns nothing; sorted() leaves its input alone and returns a new one.

Summary

len(), min(), max(), sum() summarise a list. sort() rearranges in place and returns nothing; sorted() returns a new sorted list without changing the original — both accept reverse=True.

len(list)

Returns the total count of items.

sum(list)

Returns the total sum of all numbers.

min(list)

Returns the smallest value.

max(list)

Returns the largest value.

# A list of student marks
marks = [55, 98, 76, 42, 88]

print("Total Students:", len(marks))  # 5
print("Highest Mark:", max(marks))    # 98
print("Lowest Mark:", min(marks))     # 42
print("Total Sum:", sum(marks))       # 359

# Calculate Average (Mean)
average = sum(marks) / len(marks)
print("Average Score:", average)      # 71.8
# 1. Reverse
numbers = [1, 2, 3, 4]
numbers.reverse()
print("Reversed:", numbers) # Output: [4, 3, 2, 1]

# 2. Sort (Ascending by default)
data = [10, 5, 20, 1]
data.sort()
print("Sorted:", data)      # Output: [1, 5, 10, 20]

# 3. Sort (Descending)
data.sort(reverse=True)
print("Descending:", data)  # Output: [20, 10, 5, 1]

Which one to use?

If you want to keep the original order but need a sorted version for calculation, use sorted().
If you want to permanently reorder the list, use sort().

# Demonstration: sort() vs sorted()
original = [3, 1, 2]

# Using sorted() - SAFE
new_list = sorted(original)
print("Original stays same:", original) # [3, 1, 2]
print("New List is sorted:", new_list)  # [1, 2, 3]

# Using sort() - DESTRUCTIVE
original.sort()
print("Original is changed:", original) # [1, 2, 3]

Introduction

You've already used in to check whether a value exists in a list. This topic goes further — finding exactly where a value is, and how many times it occurs.

Concept

  • index(value) — returns the position of the first occurrence of value. Raises ValueError if not present.
  • count(value) — returns how many times value occurs.

Worked Example

grades = ["B", "A", "C", "A", "B", "A"]

print(grades.index("A"))
print(grades.count("A"))
print(grades.count("D"))

grades.index("A") returns 1 — the position of the first "A", even though it appears again at positions 3 and 5. grades.count("A") returns 3. grades.count("D") returns 0 — count() never raises an error for a missing value; it simply reports zero occurrences.

Note: count() returning 0 and index() raising a ValueError for a missing value are two different, deliberate behaviours — check value in my_list first if you're not sure index() will succeed.

Explanation

index() answers "where is it, at minimum?" while count() answers "how many are there, in total?" — two genuinely different questions about the same list.

Summary

index(value) returns the position of a value's first occurrence, raising ValueError if missing; count(value) returns how many times a value occurs, returning 0 (never an error) if missing.

Syntax

list_name.index(item)

Critical Warning: If the item is NOT found, Python raises a ValueError (Crash). Always check if the item exists using in before asking for its index!

# 1. Using index()
grades = ["A", "B", "A", "C", "A"]

# Find where the FIRST "B" is
pos = grades.index("B")
print("B is at index:", pos)  # Output: 1

# Find where the FIRST "A" is
# Notice it stops at index 0 and ignores the rest
print("First A is at:", grades.index("A")) # Output: 0

Syntax

list_name.count(item)
# 2. Using count()
grades = ["A", "B", "A", "C", "A"]

# How many A's?
total_As = grades.count("A")
print("Total A grades:", total_As) # Output: 3

# How many F's? (Not in list)
print("Total F grades:", grades.count("F")) # Output: 0

Introduction

A list's elements can themselves be lists — this is how Python represents table-like data, such as rows of student records. This closing topic covers reading nested lists, then puts the chapter to work in a complete program.

Concept

A nested list is a list containing other lists as elements. Reaching an element inside an inner list needs two indexes: outer[i][j] — the first selects which inner list, the second selects the position inside it.

Worked Example

students = [
    ["Aisha", 91],
    ["Rahul", 78],
    ["Meera", 85]
]

topper = students[0]
for record in students:
    if record[1] > topper[1]:
        topper = record

print("Topper:", topper[0], "with", topper[1], "marks")

students[0][0] would reach "Aisha"; students[1][1] would reach 78. The loop traverses the outer list one row at a time, comparing each record's mark (record[1]) against the best found so far (topper[1]), replacing topper whenever a higher one appears. By the end, topper holds ['Aisha', 91], so the program prints Topper: Aisha with 91 marks.

Note: This "start with the first item, then replace it whenever something better is found" pattern is the standard way to find a maximum by hand, without using max().

Explanation

Traversing a nested list with for record in students: visits one inner list per pass — exactly the standard way to process table-like data such as a list of student records, reached with two indexes rather than one.

Summary

A nested list is a list of lists, read with two indexes (outer[i][j]) — traversing one with for record in outer_list: visits one inner list per pass, the standard technique for finding a value (like the highest mark) across rows of data.

Syntax: Accessing 2D Elements

value = list_name[row][col]

Example Matrix:

Col 0 Col 1
Row 0 10 20
Row 1 30 40

To access 30: matrix[1][0]

# Creating a 3x3 Matrix
matrix = [
    [1, 2, 3],  # Row 0
    [4, 5, 6],  # Row 1
    [7, 8, 9]   # Row 2
]

# Accessing elements
print("Row 1, Col 2:", matrix[1][2])  # Output: 6
print("Row 0, Col 0:", matrix[0][0])  # Output: 1

# Modifying an element
matrix[2][0] = 99
print("Modified Row 2:", matrix[2])   # Output: [99, 8, 9]
# Program: Linear Search
numbers = [10, 50, 30, 70, 80, 20]
target = 70
found = False

for i in range(len(numbers)):
    if numbers[i] == target:
        print("Found", target, "at Index:", i)
        found = True
        break  # Stop searching once found

if found == False:
    print(target, "not found in list.")
# Program: Count Frequency
data = [1, 2, 1, 3, 1, 4, 1]
search_item = 1
count = 0

for item in data:
    if item == search_item:
        count = count + 1

print("Number", search_item, "appears", count, "times.")
# Program: Find Max, Min, and Mean manually
values = [45, 88, 12, 67, 99, 34]

# Initialize variables with the first item
max_val = values[0]
min_val = values[0]
total_sum = 0

for x in values:
    # Check Max
    if x > max_val:
        max_val = x
    
    # Check Min
    if x < min_val:
        min_val = x
        
    # Add to Total
    total_sum = total_sum + x

mean_val = total_sum / len(values)

print("Maximum:", max_val)
print("Minimum:", min_val)
print("Mean (Average):", mean_val)

Want the full course?

Unlock all chapters, video lectures, and SQL practice exercises.

Get Full Access