Class 12 Computer Science Chapter 02 ยท 36 min read

๐Ÿ Python Revision Tour II

Unit 1 ยท Ch 2 Nov 02, 2026
Chapter Quiz Share

Chapter 2 continues the Python revision with the four built-in collection types โ€” strings, lists, tuples and dictionaries. It builds directly on Tour I.

๐Ÿ’ก How to use these notes

Each section has a concept explanation, code example, and at least one Board Exam Tip. Don't just read โ€” type every code snippet yourself in Python. Typing the code yourself helps you remember the syntax.


2.1 Introduction

In Python Revision Tour I, we covered the basics โ€” tokens, variables, data types, and flow control. Tour II goes deeper into Python's built-in data structures โ€” the workhorses of real-world programming.

๐Ÿ”ค

Strings

Ordered, immutable sequences of characters

"Hello"'Python'
๐Ÿ“‹

Lists

Ordered, mutable sequences โ€” can store any data type

[1"two"3.0]
๐Ÿ“ฆ

Tuples

Ordered, immutable sequences โ€” fixed after creation

(102030)
๐Ÿ—‚

Dictionaries

Key-value pairs โ€” fast lookups by key, not by position

{"name": "Arjun"}
๐Ÿ“‹ Board Exam Tip

A typical 1-mark question: "Name the four main sequence/collection data types in Python." Answer: String, List, Tuple, Dictionary. Know which are mutable (List, Dictionary) and which are immutable (String, Tuple).

๐Ÿ’ก In simple words

mutable means "can be changed after it is made"; immutable means "cannot be changed โ€” you can only make a new one".

Which one should I use? Answer these questions from the top:

graph TD
    Q1{"Will you look items up\nby a NAME (key)?"}
    Q2{"Is it just text?"}
    Q3{"Will the items need\nto change later?"}
    D["๐Ÿ—‚ Dictionary\n{'name': 'Arjun', 'age': 17}"]
    S["๐Ÿ”ค String\n'Hello'"]
    L["๐Ÿ“‹ List โ€” mutable\n[10, 'two', 3.0]"]
    T["๐Ÿ“ฆ Tuple โ€” immutable\n(10, 20, 30)"]

    Q1 -->|"Yes"| D
    Q1 -->|"No, by position"| Q2
    Q2 -->|"Yes"| S
    Q2 -->|"No"| Q3
    Q3 -->|"Yes"| L
    Q3 -->|"No, fixed"| T

    style D fill:#FFE0B2,stroke:#FF9800
    style S fill:#C8E6C9,stroke:#4CAF50
    style L fill:#BBDEFB,stroke:#2196F3
    style T fill:#E1BEE7,stroke:#9C27B0

2.2 Strings in Python

A string is an ordered, immutable sequence of characters enclosed in single ' ', double " ", or triple ''' ''' quotes. Strings are one of Python's most-used data types.

# Creating strings
s1 = 'Hello'
s2 = "World"
s3 = '''This is a
multi-line string'''

print(type(s1))   # <class 'str'>
print(len(s1))    # 5

Indexing in Strings โ€” Both Directions!

Index H e l l o
Positive 0 1 2 3 4
Negative -5 -4 -3 -2 -1
s = "Hello"
print(s[0])    # H  (first character)
print(s[4])    # o  (last character)
print(s[-1])   # o  (last character, negative index)
print(s[-5])   # H  (first character, negative index)

2.2.1 Item Assignment Not Supported

Strings are immutable โ€” once created, individual characters cannot be changed. This is one of the most important properties of strings.

What really happens: Python never edits the old string. It builds a new string and moves the name s to it.

graph LR
    N(["name: s"])
    OLD["'Hello'\nold string โ€” never changed"]
    NEW["'Jello'\nbrand-new string"]

    N -.->|"before"| OLD
    N -->|"after s = 'J' + s[1:]"| NEW

    style OLD fill:#ECEFF1,stroke:#90A4AE
    style NEW fill:#C8E6C9,stroke:#4CAF50

Code Example: string_immutable.py

# string_immutable.py
s = "Hello"

# Trying to change a character โ€” WILL CRASH!
# s[0] = "J"    โ† TypeError: 'str' object does not support item assignment

# โœ… CORRECT WAY โ€” create a NEW string
s = "J" + s[1:]
print(s)   # Jello

# Another correct method
s = "Hello"
s = s.replace("H", "J")
print(s)   # Jello
๐Ÿ“‹ Board Exam Tip

"Why can't we change a character of a string directly?" is a typical 1-mark question. Answer: Strings are immutable in Python. Item assignment (s[0] = 'X') raises a TypeError. To "change" a string, you must create a new string.

โš  Classic Trap

Beginners often try s[0] = 'X' and get confused by the TypeError. Remember: you can read from a string using index (s[0]) but you can never write to it!


2.2.2 Traversing a String

Traversal means visiting each character of a string one by one. Python gives you two clean ways to do this.

Code Example: string_traversal.py

# string_traversal.py

name = "Python"

# Method 1: for loop (PREFERRED โ€” clean and Pythonic)
print("Method 1: for loop")
for ch in name:
    print(ch, end=" ")   # P y t h o n
print()

# Method 2: while loop with index
print("Method 2: while loop")
i = 0
while i < len(name):
    print(name[i], end=" ")   # P y t h o n
    i += 1
print()

# Method 3: for loop with range and index
print("Method 3: for with range")
for i in range(len(name)):
    print(f"Index {i}: {name[i]}")

Output:

Method 1: for loop
P y t h o n
Method 2: while loop
P y t h o n
Method 3: for with range
Index 0: P
Index 1: y
Index 2: t
Index 3: h
Index 4: o
Index 5: n
๐Ÿ“‹ Board Exam Tip

Programs to count vowels/consonants, count specific characters, or check palindrome all use string traversal. Know both the for ch in s and while i < len(s) methods โ€” both appear in practical exams.


2.2.3 String Operators

Python supports several operators that work directly on strings.

Operator Name Example Result
+ Concatenation "Hello" + " World" "Hello World"
* Repetition "Ha" * 3 "HaHaHa"
in Membership "ell" in "Hello" True
not in Non-membership "xyz" not in "Hello" True
== Equal "abc" == "abc" True
< > Comparison "apple" < "banana" True (lexicographic)

Code Example: string_operators.py

# string_operators.py

s1 = "Hello"
s2 = " World"

# Concatenation
print(s1 + s2)        # Hello World

# Repetition
print("Ha" * 3)       # HaHaHa
print(3 * "-")        # ---  (order doesn't matter!)

# Membership
print("ell" in s1)    # True
print("xyz" in s1)    # False
print("xyz" not in s1)# True

# Comparison (lexicographic โ€” based on ASCII values)
print("apple" < "banana")   # True  (a < b)
print("Apple" < "apple")    # True  (A=65 < a=97)
print("abc" == "abc")       # True
โš  String Comparison Trap!

Python compares strings lexicographically (like a dictionary). "Apple" < "apple" is True because uppercase letters have lower ASCII values than lowercase (A=65, a=97). This often surprises students!


2.2.4 String Slices

Slicing extracts a portion (substring) of a string. It's one of the most useful string features in Python.

Syntax: string[start : stop : step]

  • start โ€” Index to begin (inclusive). Default: 0
  • stop โ€” Index to end (exclusive โ€” NOT included). Default: len(s)
  • step โ€” Jump between characters. Default: 1

Picture it: s = "PYTHON" is a row of numbered boxes. s[1:4] starts at box 1 and stops before box 4, so it takes boxes 1, 2 and 3:

graph LR
    P["P\n0"] ~~~ Y["Y\n1"] ~~~ T["T\n2"] ~~~ H["H\n3"] ~~~ O["O\n4"] ~~~ N["N\n5"]

    style Y fill:#C8E6C9,stroke:#4CAF50
    style T fill:#C8E6C9,stroke:#4CAF50
    style H fill:#C8E6C9,stroke:#4CAF50
    style O fill:#FFCDD2,stroke:#F44336

๐ŸŸฉ taken by s[1:4] โ†’ "YTH" ยท ๐ŸŸฅ box 4 is the stop โ€” not taken

Code Example: string_slicing.py

# string_slicing.py

s = "PYTHON"
#    0 1 2 3 4 5   (positive indices)
#   -6-5-4-3-2-1   (negative indices)

# Basic slices
print(s[1:4])      # YTH  (index 1,2,3 โ€” stop=4 is excluded)
print(s[:3])       # PYT  (start defaults to 0)
print(s[3:])       # HON  (stop defaults to end)
print(s[:])        # PYTHON (full string)

# Step slicing
print(s[::2])      # PTO  (every 2nd character)
print(s[1::2])     # YHN  (start at 1, every 2nd)

# Negative step โ€” REVERSAL!
print(s[::-1])     # NOHTYP  (reverse the string!)
print(s[4:1:-1])   # OHT  (from index 4 to 2, going backwards)

# Using negative indices
print(s[-3:])      # HON  (last 3 characters)
print(s[:-3])      # PYT  (everything except last 3)
๐Ÿ“‹ Board Exam Tip โ€” The Reversal Trick

s[::-1] reverses a string โ€” useful in both MCQs and programs. Also know: s[::2] gives alternate characters, s[1::2] gives alternate characters starting from index 1. These are typical 1-mark MCQs.

๐Ÿง  Slicing in 3 Easy Steps โ€” s[start:stop:step]

  1. Begin at index start.
  2. Keep taking characters while the index is before stop โ€” the stop index itself is never taken.
  3. Move by step each time (a negative step walks backwards).

Quick check: with step 1, s[a:b] always gives b โˆ’ a characters โ€” s[1:4] gives 4 โˆ’ 1 = 3. Backwards example: s[4:1:-1] takes indices 4, 3, 2 โ†’ "OHT".


2.2.5 String Functions

Python's str type comes loaded with built-in functions and methods. These are exam gold!

Case Functions:

Function What it does Example
upper() All uppercase "hello".upper() โ†’ "HELLO"
lower() All lowercase "HELLO".lower() โ†’ "hello"
capitalize() First letter upper, rest lower "hELLO".capitalize() โ†’ "Hello"
title() First letter of each word upper "hello world".title() โ†’ "Hello World"
swapcase() Flip case of every character "HeLLo".swapcase() โ†’ "hEllO"

Search & Replace:

Function What it does Example
find(sub) First index of sub; -1 if not found "Hello".find("ll") โ†’ 2
index(sub) Like find() but raises ValueError if not found "Hello".index("ll") โ†’ 2
count(sub) How many times sub appears "Hello".count("l") โ†’ 2
replace(old, new) Replace all occurrences "Hello".replace("l","r") โ†’ "Herro"
startswith(s) Returns True if string starts with s "Python".startswith("Py") โ†’ True
endswith(s) Returns True if string ends with s "Python".endswith("on") โ†’ True

Split & Join:

Function What it does Example
split(sep) Split string into list "a,b,c".split(",") โ†’ ['a','b','c']
join(iterable) Join iterable with string as separator ",".join(['a','b','c']) โ†’ "a,b,c"

Strip Functions:

Function What it does Example
strip() Remove whitespace from both ends " Hi ".strip() โ†’ "Hi"
lstrip() Remove whitespace from left end " Hi ".lstrip() โ†’ "Hi "
rstrip() Remove whitespace from right end " Hi ".rstrip() โ†’ " Hi"

Check Functions (Return True/False):

Function Returns True when...
isalpha() All characters are letters
isdigit() All characters are digits
isalnum() All characters are letters or digits
isspace() All characters are whitespace
isupper() All letters are uppercase
islower() All letters are lowercase

Other Useful Functions:

Function What it does Example
len(s) Length of string len("Hello") โ†’ 5
ord(ch) ASCII value of character ord('A') โ†’ 65
chr(n) Character for ASCII value chr(65) โ†’ 'A'

Code Example: string_functions.py

# string_functions.py

s = "  Hello, World!  "

# Case operations
print(s.upper())        # "  HELLO, WORLD!  "
print(s.lower())        # "  hello, world!  "
print("hello world".title())   # "Hello World"

# Strip whitespace
print(s.strip())        # "Hello, World!"
clean = s.strip()

# Find and Count
print(clean.find("l"))  # 2
print(clean.count("l")) # 3
print(clean.find("xyz"))# -1 (not found โ€” no crash!)

# Replace
print(clean.replace("World", "Python"))  # "Hello, Python!"

# Split and Join
sentence = "apple,banana,cherry"
fruits = sentence.split(",")
print(fruits)           # ['apple', 'banana', 'cherry']
print(" | ".join(fruits))  # apple | banana | cherry

# Check functions
print("Hello123".isalnum())   # True
print("Hello".isalpha())      # True
print("12345".isdigit())      # True
print("   ".isspace())        # True

# ord() and chr()
print(ord('A'))   # 65
print(ord('a'))   # 97
print(chr(65))    # A
print(chr(90))    # Z
๐Ÿ“‹ Board Exam Tip โ€” find() vs index()

Both find the position of a substring, BUT: find() returns -1 if not found (safe!), while index() raises a ValueError exception. In programs, prefer find() unless you want an error on failure. This difference can be asked as a 2-mark question.

๐Ÿ“‹ Board Exam Tip โ€” ord() and chr()

These functions are used in encoding/decoding programs. Remember: ord('A')=65, ord('a')=97, ord('0')=48. The gap between uppercase and lowercase is always 32 (ord('a') - ord('A') == 32). This is used in Caesar cipher programs.


2.3 Lists in Python

A list is an ordered, mutable (changeable) sequence that can hold items of different data types. Lists are the most versatile data structure in Python.

๐Ÿ“‹ Board Exam Tip

"What is a list in Python?" โ€” Answer: A list is an ordered, mutable sequence of elements enclosed in square brackets [ ]. Elements can be of different data types. Lists support indexing, slicing, and many built-in methods.


2.3.1 Creating Lists

Code Example: creating_lists.py

# creating_lists.py

# Empty list
empty = []
print(empty)        # []

# List of integers
numbers = [10, 20, 30, 40, 50]
print(numbers)      # [10, 20, 30, 40, 50]

# Mixed data types โ€” Lists can hold anything!
mixed = [42, "Python", 3.14, True, None]
print(mixed)        # [42, 'Python', 3.14, True, None]

# Nested list (list of lists)
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix[1][2]) # 6  (row 1, col 2)

# Using list() constructor
chars = list("CBSE")
print(chars)        # ['C', 'B', 'S', 'E']

nums = list(range(1, 6))
print(nums)         # [1, 2, 3, 4, 5]

Indexing in Lists โ€” Same as Strings:

Index 10 20 30 40 50
Positive 0 1 2 3 4
Negative -5 -4 -3 -2 -1
lst = [10, 20, 30, 40, 50]
print(lst[0])    # 10
print(lst[-1])   # 50
print(lst[2])    # 30

2.3.2 Lists vs. Strings

Both strings and lists are sequences, but they have key differences:

Feature String List
Mutability โŒ Immutable โœ… Mutable
Data types stored Characters only Any data type
Syntax "Hello" [1, 2, 3]
Item assignment โŒ TypeError โœ… Allowed
Concatenation (+) โœ… โœ…
Repetition (*) โœ… โœ…
Indexing โœ… โœ…
Slicing โœ… โœ…

Code Example: list_vs_string.py

# list_vs_string.py

# String โ€” IMMUTABLE
s = "Hello"
# s[0] = "J"   โ† TypeError!

# List โ€” MUTABLE
lst = ["H", "e", "l", "l", "o"]
lst[0] = "J"   # โœ… Allowed!
print(lst)     # ['J', 'e', 'l', 'l', 'o']

# Both support slicing
print(s[1:4])       # ell
print(lst[1:4])     # ['e', 'l', 'l']

# Both support membership
print("e" in s)     # True
print("e" in lst)   # True
๐Ÿ“‹ Board Exam Tip

"Differentiate between lists and strings in Python" โ€” can be asked as a 3-mark question. Always mention: mutability, data types stored, and syntax. The key difference is mutability.


2.3.3 List Operations

Operation Operator Example Result
Concatenation + [1,2] + [3,4] [1, 2, 3, 4]
Repetition * [0] * 3 [0, 0, 0]
Membership in 3 in [1,2,3] True
Non-membership not in 5 not in [1,2,3] True
Comparison == [1,2] == [1,2] True

Code Example: list_operations.py

# list_operations.py

a = [1, 2, 3]
b = [4, 5, 6]

# Concatenation โ€” creates a NEW list
c = a + b
print(c)           # [1, 2, 3, 4, 5, 6]

# Repetition
zeros = [0] * 4
print(zeros)       # [0, 0, 0, 0]

# Membership
print(2 in a)      # True
print(10 in a)     # False
print(10 not in a) # True

# Comparison
print([1,2,3] == [1,2,3])  # True
print([1,2,3] == [3,2,1])  # False (order matters!)

# Slicing a list โ€” same syntax as strings
lst = [10, 20, 30, 40, 50]
print(lst[1:4])    # [20, 30, 40]
print(lst[::-1])   # [50, 40, 30, 20, 10]  (reversed!)
print(lst[::2])    # [10, 30, 50]

2.3.4 List Manipulation

Since lists are mutable, we can directly modify their elements โ€” unlike strings!

Code Example: list_manipulation.py

# list_manipulation.py

fruits = ["apple", "banana", "cherry", "date", "elderberry"]

# โ‘  Updating an element
fruits[1] = "blueberry"
print(fruits)   # ['apple', 'blueberry', 'cherry', 'date', 'elderberry']

# โ‘ก Updating a slice (replace multiple elements at once)
fruits[2:4] = ["coconut", "durian"]
print(fruits)   # ['apple', 'blueberry', 'coconut', 'durian', 'elderberry']

# โ‘ข Deleting an element by index
del fruits[0]
print(fruits)   # ['blueberry', 'coconut', 'durian', 'elderberry']

# โ‘ฃ Deleting a slice
del fruits[1:3]
print(fruits)   # ['blueberry', 'elderberry']

# โ‘ค Inserting in the middle via slice assignment
fruits[1:1] = ["fig", "grape"]
print(fruits)   # ['blueberry', 'fig', 'grape', 'elderberry']
โš  Common Mistake

fruits[1:3] = ["mango"] does NOT just change elements 1 and 2 โ€” it replaces that slice with the new list. The length of the list may change! Slice assignment is powerful but needs care.


2.3.5 Making True Copy of a List

This is one of the trickiest topics for students โ€” and important for exams.

The Problem: Shallow (Alias) Copy

When you write b = a, Python does NOT create a new list. Both a and b point to the same list object. Changing one changes both!

๐Ÿ’ก In simple words

a variable is just a name tag stuck on a box of data. b = a sticks a second tag on the same box โ€” so a change made through either name shows up in both. b = a[:] builds a second box with the same contents, so the two lists are independent.

graph LR
    subgraph CP["โœ… copy1 = original[:]"]
        O2(["original"])
        C2(["copy1"])
        L2["[1, 2, 3, 4, 5]"]
        L3["[999, 2, 3, 4, 5]\na SEPARATE list"]
        O2 --> L2
        C2 --> L3
    end
    subgraph AL["โŒ alias = original"]
        O1(["original"])
        A1(["alias"])
        L1["[999, 2, 3, 4, 5]\nONE list in memory"]
        O1 --> L1
        A1 --> L1
    end

    style L1 fill:#FFCDD2,stroke:#F44336
    style L2 fill:#C8E6C9,stroke:#4CAF50
    style L3 fill:#C8E6C9,stroke:#4CAF50

Code Example: list_copy.py

# list_copy.py

# โŒ ALIAS (NOT a copy!)
original = [1, 2, 3, 4, 5]
alias = original           # Both point to SAME list!
alias[0] = 999
print(original)   # [999, 2, 3, 4, 5] โ† Original CHANGED!
print(alias)      # [999, 2, 3, 4, 5]

# โœ… TRUE COPY โ€” Method 1: Slicing
original = [1, 2, 3, 4, 5]
copy1 = original[:]
copy1[0] = 999
print(original)   # [1, 2, 3, 4, 5] โ† Original SAFE!
print(copy1)      # [999, 2, 3, 4, 5]

# โœ… TRUE COPY โ€” Method 2: list() constructor
copy2 = list(original)
copy2[0] = 888
print(original)   # [1, 2, 3, 4, 5] โ† Original SAFE!

# โœ… TRUE COPY โ€” Method 3: .copy() method
copy3 = original.copy()
copy3[0] = 777
print(original)   # [1, 2, 3, 4, 5] โ† Original SAFE!
๐Ÿ“‹ Board Exam Tip โ€” Most Important Concept!

"What is the difference between b = a and b = a[:] for lists?" โ€” This is a 3-mark question. Always explain:

  • b = a creates an alias (both refer to same object)
  • b = a[:] creates a true copy (independent objects) Use id() to prove they are different: id(original) != id(copy1).
๐Ÿง  id() Verification

a = [1, 2, 3]
b = a         # alias
c = a[:]      # true copy
print(id(a) == id(b))  # True  โ€” same object!
print(id(a) == id(c))  # False โ€” different objects!

2.3.6 List Functions

Python provides a rich set of list functions and methods. Know them all!

Methods that MODIFY the list (in-place):

Method What it does Example
append(x) Add x at the END lst.append(6)
extend(iterable) Add all items of iterable at end lst.extend([7,8])
insert(i, x) Insert x at index i lst.insert(2, 99)
remove(x) Remove first occurrence of x lst.remove(99)
pop(i) Remove & return item at index i (default: last) lst.pop()
sort() Sort list in place (ascending) lst.sort()
sort(reverse=True) Sort in descending order lst.sort(reverse=True)
reverse() Reverse the list in place lst.reverse()
clear() Remove all elements lst.clear()

Methods/Functions that return a value (do NOT modify):

Function What it does Example
len(lst) Number of elements len([1,2,3]) โ†’ 3
count(x) Count occurrences of x [1,2,2,3].count(2) โ†’ 2
index(x) Index of first occurrence of x [1,2,3].index(2) โ†’ 1
min(lst) Minimum element min([5,1,3]) โ†’ 1
max(lst) Maximum element max([5,1,3]) โ†’ 5
sum(lst) Sum of all elements sum([1,2,3]) โ†’ 6
sorted(lst) Returns new sorted list sorted([3,1,2]) โ†’ [1,2,3]

Code Example: list_functions.py

# list_functions.py

lst = [30, 10, 50, 20, 40]
print("Original:", lst)     # [30, 10, 50, 20, 40]

# append โ€” adds ONE element to end
lst.append(60)
print("After append(60):", lst)     # [30, 10, 50, 20, 40, 60]

# extend โ€” adds MULTIPLE elements to end
lst.extend([70, 80])
print("After extend:", lst)         # [30, 10, 50, 20, 40, 60, 70, 80]

# insert โ€” at specific position
lst.insert(1, 5)
print("After insert(1,5):", lst)    # [30, 5, 10, 50, 20, 40, 60, 70, 80]

# remove โ€” first occurrence
lst.remove(5)
print("After remove(5):", lst)      # [30, 10, 50, 20, 40, 60, 70, 80]

# pop โ€” removes and returns last element
popped = lst.pop()
print("Popped:", popped)            # 80
print("After pop():", lst)          # [30, 10, 50, 20, 40, 60, 70]

# pop(index) โ€” removes and returns specific index
popped_at = lst.pop(2)
print("Popped at [2]:", popped_at)  # 50

# sort and reverse
lst.sort()
print("After sort():", lst)         # [10, 20, 30, 40, 60, 70]
lst.reverse()
print("After reverse():", lst)      # [70, 60, 40, 30, 20, 10]

# Statistics
print("min:", min(lst))   # 10
print("max:", max(lst))   # 70
print("sum:", sum(lst))   # 230
print("len:", len(lst))   # 6
๐Ÿ“‹ Board Exam Tip โ€” append() vs extend()

Revise this difference carefully.

  • append([4,5]) โ†’ adds the list as a single element: [1,2,3,[4,5]]
  • extend([4,5]) โ†’ adds each item separately: [1,2,3,4,5] After lst.append([4,5]), len(lst) increases by 1. After lst.extend([4,5]), it increases by 2.
graph LR
    A["lst = [1, 2, 3]"]
    B["[1, 2, 3, [4, 5]]\nlength 4 โ€” the whole list\ngoes in as ONE item"]
    C["[1, 2, 3, 4, 5]\nlength 5 โ€” each item\ngoes in separately"]

    A -->|"lst.append([4, 5])"| B
    A -->|"lst.extend([4, 5])"| C

    style B fill:#FFE0B2,stroke:#FF9800
    style C fill:#C8E6C9,stroke:#4CAF50
โš  sort() vs sorted()

  • lst.sort() โ†’ modifies the original list, returns None
  • sorted(lst) โ†’ does NOT modify original list, returns a new sorted list Writing lst = lst.sort() is a classic bug โ€” lst becomes None!

2.4 Tuples in Python

A tuple is an ordered, immutable sequence of elements. Think of a tuple as a "read-only list" โ€” once created, it cannot be changed.

๐Ÿ“‹ Board Exam Tip

"When would you use a tuple instead of a list?" โ€” Answer: When data should not change (e.g., days of week, RGB color values, database records), use a tuple. Tuples are also faster than lists and can be used as dictionary keys (lists cannot).


2.4.1 Creating Tuples

Code Example: creating_tuples.py

# creating_tuples.py

# Empty tuple
t0 = ()
print(t0)           # ()

# Tuple of integers
t1 = (10, 20, 30)
print(t1)           # (10, 20, 30)

# Mixed data types
t2 = (42, "Python", 3.14, True)
print(t2)

# โš ๏ธ CRITICAL: Single-element tuple โ€” the comma is MANDATORY!
single_wrong = (42)      # This is just an int, NOT a tuple!
single_right = (42,)     # This IS a tuple โ€” note the comma!
print(type(single_wrong))  # <class 'int'>
print(type(single_right))  # <class 'tuple'>

# Tuple without parentheses (tuple packing)
t3 = 1, 2, 3
print(t3)           # (1, 2, 3)
print(type(t3))     # <class 'tuple'>

# Using tuple() constructor
t4 = tuple([1, 2, 3])    # from list
t5 = tuple("CBSE")       # from string
print(t4)   # (1, 2, 3)
print(t5)   # ('C', 'B', 'S', 'E')
โš  The Single-Element Tuple Trap

t = (42) is an integer, NOT a tuple! Python reads the parentheses as just grouping. t = (42,) is a tuple โ€” the trailing comma makes all the difference. This is a typical 1-mark MCQ trap. Remember: ONE item โ†’ must have a comma!


2.4.2 Tuples vs. Lists

Feature Tuple List
Mutability โŒ Immutable โœ… Mutable
Syntax ( ) [ ]
Speed โœ… Faster Slower
Memory Less More
Can be dict key โœ… Yes โŒ No
Has all list methods โŒ No โœ… Yes
Use case Fixed data Dynamic data

Code Example: tuple_vs_list.py

# tuple_vs_list.py

t = (1, 2, 3)
lst = [1, 2, 3]

# โŒ Tuple item assignment raises TypeError
# t[0] = 99    โ† TypeError: 'tuple' object does not support item assignment

# โœ… List item assignment works
lst[0] = 99
print(lst)      # [99, 2, 3]

# Tuples can be dict keys, lists CANNOT
my_dict = {(1, 2): "point A", (3, 4): "point B"}
print(my_dict[(1, 2)])   # point A

# This would CRASH:
# bad_dict = {[1,2]: "point"}  โ† TypeError: unhashable type: 'list'

2.4.3 Tuple Operations

Tuples support all read-only operations that lists do:

Operation Example Result
Concatenation (1,2) + (3,4) (1, 2, 3, 4)
Repetition (0,) * 3 (0, 0, 0)
Membership 2 in (1,2,3) True
Indexing t[1] Second element
Slicing t[1:3] Sub-tuple
Comparison (1,2) == (1,2) True

Code Example: tuple_operations.py

# tuple_operations.py

t1 = (10, 20, 30)
t2 = (40, 50, 60)

# Concatenation โ€” creates NEW tuple
t3 = t1 + t2
print(t3)         # (10, 20, 30, 40, 50, 60)

# Repetition
t4 = (0,) * 4
print(t4)         # (0, 0, 0, 0)

# Membership
print(20 in t1)   # True
print(99 in t1)   # False

# Indexing
print(t1[0])      # 10
print(t1[-1])     # 30

# Slicing
print(t3[2:5])    # (30, 40, 50)
print(t3[::-1])   # (60, 50, 40, 30, 20, 10)

# Tuple unpacking โ€” very Pythonic!
a, b, c = t1
print(a, b, c)    # 10 20 30
๐Ÿ’ก Tuple Unpacking

is a clean Python technique โ€” assign a tuple's values to multiple variables in one line: x, y, z = (1, 2, 3). This works because Python's multiple assignment is based on tuple packing/unpacking.


2.4.4 Tuple Functions and Methods

Tuples have only 2 methods (because they're immutable โ€” can't add, remove, or sort):

Method What it does Example
count(x) Count occurrences of x (1,2,2,3).count(2) โ†’ 2
index(x) Index of first occurrence of x (10,20,30).index(20) โ†’ 1

Built-in functions that work on tuples:

Function What it does
len(t) Number of elements
min(t) Minimum element
max(t) Maximum element
sum(t) Sum of all numeric elements
sorted(t) Returns a new sorted list (not tuple!)
tuple(seq) Convert sequence to tuple

Code Example: tuple_functions.py

# tuple_functions.py

marks = (85, 92, 78, 92, 88, 70)

print("Length:", len(marks))         # 6
print("Maximum:", max(marks))        # 92
print("Minimum:", min(marks))        # 70
print("Sum:", sum(marks))            # 505
print("Count of 92:", marks.count(92)) # 2 โ€” count() is a tuple method
print("Index of 78:", marks.index(78)) # 2

# sorted() returns a LIST, not a tuple!
sorted_marks = sorted(marks)
print("Sorted:", sorted_marks)          # [70, 78, 85, 88, 92, 92]
print("Type:", type(sorted_marks))      # <class 'list'>

# If you need a sorted tuple:
sorted_tuple = tuple(sorted(marks))
print("Sorted tuple:", sorted_tuple)    # (70, 78, 85, 88, 92, 92)
๐Ÿ“‹ Board Exam Tip

sorted(t) on a tuple returns a list, not a tuple! Remember this for MCQs. Also: tuples have only count() and index() methods โ€” they do NOT have append(), remove(), sort(), etc.


2.5 Dictionaries in Python

A dictionary is a collection of key-value pairs. It's like a real dictionary โ€” you look up a word (key) to find its definition (value). You find an item by its key, never by a position number. (Since Python 3.7, a dictionary also remembers the order in which you added the items.)

graph LR
    K1["๐Ÿ”‘ 'name'"] --> V1["'Arjun'"]
    K2["๐Ÿ”‘ 'age'"] --> V2["17"]
    K3["๐Ÿ”‘ 'marks'"] --> V3["95"]

    style K1 fill:#FFE0B2,stroke:#FF9800
    style K2 fill:#FFE0B2,stroke:#FF9800
    style K3 fill:#FFE0B2,stroke:#FF9800

student["age"] follows the arrow from the key 'age' and gives 17.

๐Ÿ“‹ Board Exam Tip

"Define dictionary in Python" โ€” Answer: A dictionary is a mutable collection of key-value pairs enclosed in curly braces { }, where items are found by key, not by position (from Python 3.7 it also keeps insertion order). Each key must be unique and immutable (string, number, or tuple). Values can be of any type.


2.5.1 Creating a Dictionary

Code Example: creating_dict.py

# creating_dict.py

# Empty dictionary
d0 = {}
print(d0)            # {}
print(type(d0))      # <class 'dict'>

# Dictionary with initial values
student = {
    "name": "Arjun",
    "age": 17,
    "marks": 95,
    "passed": True
}
print(student)

# Mixed key types (keys must be immutable)
mixed = {
    1: "one",
    "two": 2,
    (3, 4): "tuple key"
}
print(mixed[1])        # one
print(mixed["two"])    # 2
print(mixed[(3, 4)])   # tuple key

# Using dict() constructor
d2 = dict(name="Priya", age=16, city="Delhi")
print(d2)              # {'name': 'Priya', 'age': 16, 'city': 'Delhi'}

# Creating from list of tuples
d3 = dict([("a", 1), ("b", 2), ("c", 3)])
print(d3)              # {'a': 1, 'b': 2, 'c': 3}

2.5.2 Accessing Elements of a Dictionary

Code Example: accessing_dict.py

# accessing_dict.py

student = {"name": "Arjun", "age": 17, "marks": 95}

# Method 1: Direct key access โ€” FAST
print(student["name"])   # Arjun
print(student["marks"])  # 95

# โŒ Key error if key doesn't exist
# print(student["grade"])  โ† KeyError: 'grade'

# โœ… Method 2: get() โ€” SAFE (returns None or default if key not found)
print(student.get("grade"))          # None  (no crash!)
print(student.get("grade", "N/A"))   # N/A   (custom default value)

# Checking if key exists
if "age" in student:
    print("Age found:", student["age"])   # Age found: 17
๐Ÿ“‹ Board Exam Tip โ€” [] vs get()

  • d["key"] โ†’ raises KeyError if key doesn't exist
  • d.get("key") โ†’ returns None (or custom default) if key doesn't exist In safe programs, always use get(). This difference is tested in both MCQ and programming questions!

2.5.3 Characteristics of a Dictionary

๐Ÿ”‘

Unique Keys

Each key appears EXACTLY once โ€” duplicate keys overwrite

{"a":1"a":2} โ†’ {"a":2}
๐Ÿ”’

Immutable Keys

Keys must be immutable: strings, numbers, tuples โ€” NOT lists

Use "name" not ["name"]
โœ๏ธ

Mutable Values

Values can be any data type and can be changed

Values can even be lists or dicts!
๐Ÿ“š

Ordered (3.7+)

From Python 3.7, dicts maintain insertion order

Items appear in order you added them

Code Example: dict_characteristics.py

# dict_characteristics.py

# Duplicate keys โ€” LAST VALUE WINS
d = {"a": 1, "b": 2, "a": 99}
print(d)    # {'a': 99, 'b': 2}  โ€” first "a":1 is overwritten!

# Values can be any type โ€” even lists, dicts!
complex_dict = {
    "name": "Arjun",
    "scores": [85, 90, 88],
    "address": {"city": "Delhi", "pin": 110001}
}
print(complex_dict["scores"])          # [85, 90, 88]
print(complex_dict["address"]["city"]) # Delhi

# Lists CANNOT be keys (unhashable!)
# bad = {[1,2]: "value"}  โ† TypeError: unhashable type: 'list'

# Tuples CAN be keys
good = {(1, 2): "coordinates"}
print(good[(1, 2)])   # coordinates

2.5.4 Dictionary Operations

Code Example: dict_operations.py

# dict_operations.py

student = {"name": "Arjun", "age": 17}

# โ‘  Adding a new key-value pair
student["marks"] = 95
print(student)   # {'name': 'Arjun', 'age': 17, 'marks': 95}

# โ‘ก Updating an existing value
student["age"] = 18
print(student)   # {'name': 'Arjun', 'age': 18, 'marks': 95}

# โ‘ข Deleting a key-value pair using del
del student["age"]
print(student)   # {'name': 'Arjun', 'marks': 95}

# โ‘ฃ Deleting using pop() โ€” also returns the value
removed = student.pop("marks")
print("Removed value:", removed)  # 95
print(student)                    # {'name': 'Arjun'}

# โ‘ค Checking membership (checks KEYS only!)
student = {"name": "Arjun", "age": 17, "marks": 95}
print("name" in student)     # True
print("Arjun" in student)    # False  โ€” "Arjun" is a VALUE, not a KEY!
print(17 in student)         # False  โ€” 17 is a VALUE!

# โ‘ฅ Traversal
for key in student:
    print(key, ":", student[key])
โš  Membership Check on Dictionaries

"key" in d checks only keys, NOT values! "Arjun" in student is False even though "Arjun" is in the dictionary (as a value). Use "Arjun" in student.values() to search values.


2.5.5 Dictionary Functions and Methods

Method What it does Returns
keys() All keys dict_keys view
values() All values dict_values view
items() All key-value pairs as tuples dict_items view
get(key, default) Value for key; default if not found Value or default
update(d2) Add/update with another dict None (in-place)
pop(key) Remove and return value for key Value
popitem() Remove and return last inserted pair (key, value) tuple
clear() Remove all items None
copy() Shallow copy New dict
setdefault(key, val) Return value; set default if key absent Value
fromkeys(seq, val) Create dict with keys from seq New dict
len(d) Number of key-value pairs Integer

Code Example: dict_methods.py

# dict_methods.py

student = {"name": "Arjun", "age": 17, "marks": 95, "grade": "A"}

# keys(), values(), items()
print(student.keys())    # dict_keys(['name', 'age', 'marks', 'grade'])
print(student.values())  # dict_values(['Arjun', 17, 95, 'A'])
print(student.items())   # dict_items([('name', 'Arjun'), ...])

# Convert to lists if needed
key_list = list(student.keys())
print(key_list)          # ['name', 'age', 'marks', 'grade']

# update() โ€” adds/modifies multiple items at once
student.update({"city": "Delhi", "age": 18})
print(student)   # age updated to 18, city added

# Traversal using items()
print("\nStudent Report:")
for key, value in student.items():
    print(f"  {key:10}: {value}")

# fromkeys() โ€” create dict with fixed value
subjects = ["Physics", "Chemistry", "Maths", "CS"]
marks_template = dict.fromkeys(subjects, 0)
print(marks_template)
# {'Physics': 0, 'Chemistry': 0, 'Maths': 0, 'CS': 0}

# popitem() โ€” removes last inserted item
last = student.popitem()
print("Removed:", last)  # ('city', 'Delhi') โ€” the last INSERTED key (updating 'age' did not move it)

# Nested dict traversal
school = {
    "class12": {"strength": 40, "subjects": 5},
    "class11": {"strength": 35, "subjects": 5}
}
for cls, info in school.items():
    print(f"{cls}: {info['strength']} students")
๐Ÿ“‹ Board Exam Tip โ€” keys(), values(), items()

Know these three methods well, including what each one returns: view objects, not lists. Convert to list with list(d.keys()) if you need a list. Also know that traversal using for k, v in d.items(): is the most Pythonic way to iterate over a dict.


โš ๏ธ Common Errors and Misconceptions

Mistake Why it goes wrong Correct way
โŒ s[0] = "J" to change a string Strings are immutable โ†’ TypeError โœ… s = "J" + s[1:]
โŒ Expecting s[1:4] to include index 4 The stop index is never included โœ… s[1:4] gives indices 1, 2, 3
โŒ s.index("x") when "x" may be missing index() raises ValueError โœ… s.find("x") returns -1
โŒ b = a to copy a list Makes an alias โ€” one list, two names โœ… b = a[:], a.copy() or list(a)
โŒ lst.append([4, 5]) to add two items Adds ONE item: a nested list โœ… lst.extend([4, 5])
โŒ lst = lst.sort() sort() returns None โœ… lst.sort() or lst = sorted(lst)
โŒ t = (42) for a one-item tuple That is just the integer 42 โœ… t = (42,)
โŒ "Arjun" in student to search values in checks only the KEYS โœ… "Arjun" in student.values()
โŒ d["grade"] when the key may be missing Raises KeyError โœ… d.get("grade", "N/A")

Practice Problems

Test your mastery of Tour II topics with these board-style problems:

Strings:

  1. Write a program to count the number of vowels and consonants in a string
  2. Write a program to check if a string is a palindrome (without using slicing)
  3. Write a program to reverse words in a sentence: "Hello World" โ†’ "World Hello"
  4. Write a program to count occurrences of each character in a string using a dictionary
  5. Write a program using ord() to encode a message (shift each letter by 3 โ€” Caesar cipher)

Lists & Tuples:

  1. Write a program to find the second-largest element in a list (without sorting)
  2. Write a program to remove duplicate elements from a list while preserving order
  3. Write a program to find the frequency of each element in a list using a dictionary
  4. Demonstrate the difference between alias copy and true copy of a list
  5. Write a program to flatten a list of lists: [[1,2],[3,4],[5,6]] โ†’ [1,2,3,4,5,6]

Dictionaries:

  1. Write a program to merge two dictionaries
  2. Write a program to create a frequency dictionary from a list of words
  3. Write a program to find the key with the maximum value in a dictionary
  4. Write a program to invert a dictionary (swap keys and values)

Quick Reference

Strings โ€” Key Facts:

  • Immutable โ€” s[0] = 'X' raises TypeError
  • Slicing: s[start:stop:step], reverse: s[::-1]
  • find() โ†’ -1 if not found | index() โ†’ ValueError if not found
  • split() โ†’ string to list | join() โ†’ list to string
  • ord() โ†’ ASCII value | chr() โ†’ character from ASCII

Lists โ€” Key Facts:

  • Mutable โ€” lst[0] = 99 is allowed
  • True copy: lst[:] or lst.copy() or list(lst) โ€” NOT b = a
  • append(x) โ†’ adds 1 item | extend([x,y]) โ†’ adds multiple
  • sort() โ†’ modifies original | sorted() โ†’ returns new list
  • pop() โ†’ removes last | pop(i) โ†’ removes at index i

Tuples โ€” Key Facts:

  • Immutable โ€” cannot change after creation
  • Single-element: (42,) โ€” comma is mandatory!
  • Only 2 methods: count() and index()
  • sorted(t) returns a list, not a tuple
  • Can be used as dictionary keys (lists cannot)

Dictionaries โ€” Key Facts:

  • Key-value pairs: {key: value}
  • Keys must be unique and immutable
  • d[key] โ†’ KeyError if missing | d.get(key) โ†’ None if missing
  • in checks keys, NOT values
  • keys(), values(), items() โ†’ view objects
Take the Chapter 02 Quiz Custom Quiz
Solved Board Questions

Practice real board exam questions for this chapter.

View Solved Board Questions
Learning Support

Need Help With This Chapter?

Save key topics for exam revision, ask questions to teachers, or submit content corrections.

Verified Doubts & Teacher Answers

Chapter 02 Quiz