CSIP12.in
Back to List
Calculating...
UNIT 1 : CH 2 Dec 09, 2025

šŸ Python Revision Tour II

## 1. Definitions

- **String**: An immutable sequence of characters enclosed in single, double, or triple quotes.
- **List**: A mutable, ordered collection of items that can store elements of different data types.
- **Tuple**: An immutable, ordered collection of items enclosed in parentheses.
- **Dictionary**: An unordered collection of key-value pairs enclosed in curly braces.
- **Immutable**: Objects that cannot be changed after creation (strings, tuples).
- **Mutable**: Objects that can be modified after creation (lists, dictionaries).
- **Traversing**: Accessing each element of a sequence one by one.
- **Slicing**: Extracting a portion of a sequence using index ranges.
- **Sorting**: Arranging elements in ascending or descending order.

---

## 2. Explanation of Concepts

### 2.2 Strings in Python

### 2.2.1 Item Assignment not Supported

**Strings are immutable** in Python, meaning once created, their characters cannot be changed.

```python
# This will give an error
name = "Python"
name[0] = "J" # TypeError: 'str' object does not support item assignment
```

### 2.2.2 Traversing a String

Accessing each character of a string one by one.

```python
# Method 1: Using for loop
text = "CBSE"
for char in text:
print(char)

# Method 2: Using index
for i in range(len(text)):
print(text[i])
```

### 2.2.3 String Operators

- **Concatenation (+)**: Joins two strings
- **Repetition (*)**: Repeats string multiple times
- **Membership (in, not in)**: Checks if substring exists
- **Comparison (==, !=, <, >, <=, >=)**: Compares strings lexicographically

```python
# Examples
s1 = "Hello"
s2 = "World"
print(s1 + " " + s2) # Hello World
print(s1 * 3) # HelloHelloHello
print("H" in s1) # True
print(s1 == s2) # False
```

### 2.2.4 String Slices

Extracting substrings using **[start:end:step]**

```python
text = "Computer Science"
print(text[0:8]) # Computer
print(text[9:]) # Science
print(text[:8]) # Computer
print(text[-7:]) # Science
print(text[::2]) # Cmue cec (every 2nd character)
print(text[::-1]) # ecneicS retupmoC (reverse)
```

### 2.2.5 String Functions

| Function | Description | Example |
| --- | --- | --- |
| `len()` | Returns length | `len("Hello")` → 5 |
| `upper()` | Converts to uppercase | `"hello".upper()` → "HELLO" |
| `lower()` | Converts to lowercase | `"HELLO".lower()` → "hello" |
| `strip()` | Removes whitespace | `" hi ".strip()` → "hi" |
| `split()` | Splits into list | `"a-b-c".split("-")` → ['a','b','c'] |
| `join()` | Joins list into string | `"-".join(['a','b','c'])` → "a-b-c" |
| `find()` | Returns index of substring | `"hello".find("ll")` → 2 |
| `replace()` | Replaces substring | `"hello".replace("l","L")` → "heLLo" |
| `count()` | Counts occurrences | `"hello".count("l")` → 2 |

---

### 2.3 Lists in Python

### 2.3.1 Creating Lists

```python
# Empty list
list1 = []

# List with elements
list2 = [10, 20, 30, 40]

# Mixed data types
list3 = [1, "Python", 3.14, True]

# Nested list
list4 = [[1, 2], [3, 4], [5, 6]]

# Using list() function
list5 = list("Python") # ['P', 'y', 't', 'h', 'o', 'n']
```

### 2.3.2 Lists vs. Strings

| Feature | List | String |
| --- | --- | --- |
| Mutability | Mutable | Immutable |
| Elements | Any data type | Only characters |
| Syntax | `[1, 2, 3]` | `"123"` |
| Modification | Can change elements | Cannot change characters |

### 2.3.3 List Operations

```python
# Concatenation
L1 = [1, 2, 3]
L2 = [4, 5, 6]
L3 = L1 + L2 # [1, 2, 3, 4, 5, 6]

# Repetition
L4 = [0] * 5 # [0, 0, 0, 0, 0]

# Membership
print(2 in L1) # True

# Slicing
marks = [85, 90, 78, 92, 88]
print(marks[1:4]) # [90, 78, 92]
```

### 2.3.4 List Manipulation

```python
# Adding elements
L = [1, 2, 3]
L.append(4) # [1, 2, 3, 4]
L.insert(1, 10) # [1, 10, 2, 3, 4]
L.extend([5, 6]) # [1, 10, 2, 3, 4, 5, 6]

# Removing elements
L.remove(10) # Removes first occurrence
L.pop() # Removes last element
L.pop(0) # Removes element at index 0
del L[0] # Deletes element at index 0

# Modifying elements
L[0] = 100 # Changes first element
```

### 2.3.5 Making True Copy of a List

```python
# Shallow copy (reference)
L1 = [1, 2, 3]
L2 = L1 # L2 points to same list
L2[0] = 100 # Changes L1 also!

# True copy (independent)
L3 = L1.copy() # Method 1
L4 = L1[:] # Method 2
L5 = list(L1) # Method 3
L3[0] = 200 # Does NOT change L1
```

### 2.3.6 List Functions

| Function | Description | Example |
| --- | --- | --- |
| `len()` | Returns length | `len([1,2,3])` → 3 |
| `max()` | Returns maximum | `max([1,5,3])` → 5 |
| `min()` | Returns minimum | `min([1,5,3])` → 1 |
| `sum()` | Returns sum | `sum([1,2,3])` → 6 |
| `sorted()` | Returns sorted list | `sorted([3,1,2])` → [1,2,3] |
| `reverse()` | Reverses list | `L.reverse()` |
| `sort()` | Sorts list in place | `L.sort()` |
| `index()` | Returns index | `L.index(5)` |
| `count()` | Counts occurrences | `L.count(2)` |

---

### 2.4 Tuples in Python

### 2.4.1 Creating Tuples

```python
# Empty tuple
t1 = ()

# Single element tuple (comma is mandatory)
t2 = (5,)

# Multiple elements
t3 = (10, 20, 30)

# Without parentheses (tuple packing)
t4 = 1, 2, 3

# Mixed data types
t5 = (1, "Python", 3.14, True)

# Nested tuple
t6 = ((1, 2), (3, 4))

# Using tuple() function
t7 = tuple([1, 2, 3]) # Converts list to tuple
```

### 2.4.2 Tuples vs. Lists

| Feature | Tuple | List |
| --- | --- | --- |
| Mutability | Immutable | Mutable |
| Syntax | `(1, 2, 3)` | `[1, 2, 3]` |
| Speed | Faster | Slower |
| Methods | Limited (2) | Many |
| Use Case | Fixed data | Dynamic data |

### 2.4.3 Tuple Operations

```python
# Concatenation
t1 = (1, 2)
t2 = (3, 4)
t3 = t1 + t2 # (1, 2, 3, 4)

# Repetition
t4 = (0,) * 5 # (0, 0, 0, 0, 0)

# Membership
print(2 in t1) # True

# Slicing
marks = (85, 90, 78, 92, 88)
print(marks[1:4]) # (90, 78, 92)

# Unpacking
a, b, c = (10, 20, 30)
print(a) # 10
```

### 2.4.4 Tuple Functions and Methods

| Function/Method | Description | Example |
| --- | --- | --- |
| `len()` | Returns length | `len((1,2,3))` → 3 |
| `max()` | Returns maximum | `max((1,5,3))` → 5 |
| `min()` | Returns minimum | `min((1,5,3))` → 1 |
| `sum()` | Returns sum | `sum((1,2,3))` → 6 |
| `count()` | Counts occurrences | `t.count(2)` |
| `index()` | Returns index | `t.index(5)` |

---

### 2.5 Dictionaries in Python

### 2.5.1 Creating a Dictionary

```python
# Empty dictionary
d1 = {}
d2 = dict()

# Dictionary with key-value pairs
student = {
"name": "Rahul",
"roll": 12,
"marks": 95
}

# Using dict() function
d3 = dict(name="Priya", age=17)

# Dictionary with mixed keys
d4 = {
1: "One",
"two": 2,
(3, 4): "Tuple Key"
}
```

### 2.5.2 Accessing Elements of a Dictionary

```python
student = {"name": "Rahul", "roll": 12, "marks": 95}

# Using square brackets
print(student["name"]) # Rahul
# print(student["age"]) # KeyError if key doesn't exist

# Using get() method (safer)
print(student.get("name")) # Rahul
print(student.get("age")) # None (no error)
print(student.get("age", 17)) # 17 (default value)
```

### 2.5.3 Characteristics of a Dictionary

1. **Unordered**: Elements have no fixed position (Python 3.7+ maintains insertion order)
2. **Mutable**: Can be modified after creation
3. **Keys must be unique**: Duplicate keys are not allowed
4. **Keys must be immutable**: Can use strings, numbers, tuples (not lists)
5. **Values can be any type**: Including lists, dictionaries, etc.

```python
# Valid dictionary
d = {
"name": "Python",
(1, 2): [10, 20],
100: {"nested": "dict"}
}

# Invalid - list as key
# d = {[1, 2]: "value"} # TypeError
```

### 2.5.4 Dictionary Operations

```python
student = {"name": "Rahul", "roll": 12}

# Adding/Updating
student["marks"] = 95 # Adds new key-value
student["roll"] = 15 # Updates existing key

# Removing
del student["marks"] # Deletes key-value pair
marks = student.pop("roll") # Removes and returns value
student.clear() # Removes all items

# Membership (checks keys only)
print("name" in student) # True
print("Rahul" in student) # False (checks keys, not values)
```

### 2.5.5 Dictionary Functions and Methods

| Method | Description | Example |
| --- | --- | --- |
| `len()` | Returns number of items | `len(d)` |
| `keys()` | Returns all keys | `d.keys()` |
| `values()` | Returns all values | `d.values()` |
| `items()` | Returns key-value pairs | `d.items()` |
| `get()` | Returns value for key | `d.get("name")` |
| `pop()` | Removes and returns value | `d.pop("name")` |
| `update()` | Updates dictionary | `d.update({"age": 17})` |
| `clear()` | Removes all items | `d.clear()` |
| `copy()` | Returns shallow copy | `d.copy()` |

```python
# Traversing dictionary
student = {"name": "Rahul", "roll": 12, "marks": 95}

# Method 1: Keys
for key in student.keys():
print(key, ":", student[key])

# Method 2: Values
for value in student.values():
print(value)

# Method 3: Items (best)
for key, value in student.items():
print(key, ":", value)
```

---

### 2.6 Sorting Techniques

### 2.6.1 Bubble Sort

**Concept**: Repeatedly compares adjacent elements and swaps them if they are in wrong order.

**Algorithm**:

1. Compare adjacent elements
2. Swap if first is greater than second
3. Repeat for all elements
4. After each pass, largest element reaches end

```python
def bubble_sort(arr):
n = len(arr)
for i in range(n-1):
for j in range(n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr

# Example
numbers = [64, 34, 25, 12, 22]
print(bubble_sort(numbers)) # [12, 22, 25, 34, 64]
```

**Time Complexity**: O(n²)

**Space Complexity**: O(1)

**Pass-by-Pass Example**:

```
Original: [64, 34, 25, 12, 22]
Pass 1: [34, 25, 12, 22, 64]
Pass 2: [25, 12, 22, 34, 64]
Pass 3: [12, 22, 25, 34, 64]
Pass 4: [12, 22, 25, 34, 64]
```

### 2.6.2 Insertion Sort

**Concept**: Builds sorted array one element at a time by inserting each element at correct position.

**Algorithm**:

1. Start from second element
2. Compare with elements in sorted portion
3. Insert at correct position
4. Repeat for all elements

```python
def insertion_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
return arr

# Example
numbers = [12, 11, 13, 5, 6]
print(insertion_sort(numbers)) # [5, 6, 11, 12, 13]
```

**Time Complexity**: O(n²)

**Space Complexity**: O(1)

**Pass-by-Pass Example**:

```
Original: [12, 11, 13, 5, 6]
Pass 1: [11, 12, 13, 5, 6]
Pass 2: [11, 12, 13, 5, 6]
Pass 3: [5, 11, 12, 13, 6]
Pass 4: [5, 6, 11, 12, 13]
```

---

## 3. Important Points

### Strings

- Strings are **immutable** – cannot change individual characters
- Indexing starts from **0** (positive) or **-1** (negative from end)
- Slicing format: **[start:end:step]** (end is exclusive)
- String methods do NOT modify original string, they return new string

### Lists

- Lists are **mutable** – elements can be changed
- Can store **mixed data types**
- Use `copy()` or `[:]` for true copy, not assignment operator
- `append()` adds at end, `insert()` adds at specific position
- `remove()` removes by value, `pop()` removes by index

### Tuples

- Tuples are **immutable** like strings
- Faster than lists for fixed data
- Single element tuple needs **comma**: `(5,)`
- Used for multiple return values from functions
- Can be used as dictionary keys (lists cannot)

### Dictionaries

- Store data as **key-value pairs**
- Keys must be **unique and immutable**
- Values can be **any data type**
- Use `get()` method to avoid KeyError
- `in` operator checks **keys only**, not values

### Sorting

- **Bubble Sort**: Simple but slow, compares adjacent elements
- **Insertion Sort**: Efficient for small or nearly sorted data
- Both have O(n²) time complexity
- Python's `sort()` uses **Timsort** (faster than both)

---

## 4. Syntax Reference

### String Operations

```python
s = "Python Programming"
s.upper() # PYTHON PROGRAMMING
s.lower() # python programming
s.title() # Python Programming
s.split() # ['Python', 'Programming']
s[0:6] # Python
s[::-1] # gnimmargorP nohtyP
```

### List Operations

```python
L = [1, 2, 3]
L.append(4) # [1, 2, 3, 4]
L.insert(0, 0) # [0, 1, 2, 3, 4]
L.remove(2) # [0, 1, 3, 4]
L.pop() # [0, 1, 3]
L.sort() # Sorts in place
L.reverse() # Reverses in place
```

### Tuple Operations

```python
t = (1, 2, 3, 4, 5)
t[0] # 1
t[1:4] # (2, 3, 4)
t.count(3) # 1
t.index(4) # 3
```

### Dictionary Operations

```python
d = {"name": "Rahul", "age": 17}
d["marks"] = 95 # Add new key
d.get("name") # Rahul
d.keys() # dict_keys(['name', 'age', 'marks'])
d.values() # dict_values(['Rahul', 17, 95])
d.items() # dict_items([...])
```

---

## 5. Examples

### Example 1: String Manipulation

```python
# Q: Count vowels in a string
def count_vowels(text):
vowels = "aeiouAEIOU"
count = 0
for char in text:
if char in vowels:
count += 1
return count

print(count_vowels("Computer Science")) # 6
```

### Example 2: List Operations

```python
# Q: Remove duplicates from list
def remove_duplicates(L):
unique = []
for item in L:
if item not in unique:
unique.append(item)
return unique

numbers = [1, 2, 2, 3, 4, 4, 5]
print(remove_duplicates(numbers)) # [1, 2, 3, 4, 5]
```

### Example 3: Tuple Unpacking

```python
# Q: Swap two numbers using tuple
a = 10
b = 20
a, b = b, a # Tuple unpacking
print(a, b) # 20 10
```

### Example 4: Dictionary for Counting

```python
# Q: Count frequency of characters
def char_frequency(text):
freq = {}
for char in text:
if char in freq:
freq[char] += 1
else:
freq[char] = 1
return freq

print(char_frequency("hello"))
# {'h': 1, 'e': 1, 'l': 2, 'o': 1}
```

### Example 5: Bubble Sort Implementation

```python
# Q: Sort marks in descending order using Bubble Sort
def bubble_sort_desc(arr):
n = len(arr)
for i in range(n-1):
for j in range(n-i-1):
if arr[j] < arr[j+1]: # Change for descending
arr[j], arr[j+1] = arr[j+1], arr[j]
return arr

marks = [85, 92, 78, 95, 88]
print(bubble_sort_desc(marks)) # [95, 92, 88, 85, 78]
```

---

## 6. Tables / Diagrams

### Comparison Table: String vs List vs Tuple vs Dictionary

| Feature | String | List | Tuple | Dictionary |
| --- | --- | --- | --- | --- |
| **Mutable** | āŒ No | āœ… Yes | āŒ No | āœ… Yes |
| **Ordered** | āœ… Yes | āœ… Yes | āœ… Yes | āŒ No* |
| **Indexed** | āœ… Yes | āœ… Yes | āœ… Yes | āŒ No |
| **Duplicates** | āœ… Yes | āœ… Yes | āœ… Yes | āŒ No (keys) |
| **Syntax** | `"abc"` | `[1,2,3]` | `(1,2,3)` | `{"a":1}` |
| **Access** | By index | By index | By index | By key |

*Python 3.7+ maintains insertion order

### String Indexing Diagram

```
String: "PYTHON"
Index: 0 1 2 3 4 5
P Y T H O N
Index: -6 -5 -4 -3 -2 -1
```

### Sorting Comparison Table

| Feature | Bubble Sort | Insertion Sort |
| --- | --- | --- |
| **Best Case** | O(n) | O(n) |
| **Average Case** | O(n²) | O(n²) |
| **Worst Case** | O(n²) | O(n²) |
| **Space** | O(1) | O(1) |
| **Stable** | āœ… Yes | āœ… Yes |
| **Best For** | Small lists | Nearly sorted lists |

---

## 7. Common Errors / Misconceptions

### āŒ Error 1: String Item Assignment

```python
# Wrong
s = "Python"
s[0] = "J" # TypeError

# Correct
s = "J" + s[1:] # "Jython"
```

### āŒ Error 2: Single Element Tuple

```python
# Wrong
t = (5) # This is just an integer!
print(type(t)) #

# Correct
t = (5,) # Note the comma
print(type(t)) #
```

### āŒ Error 3: List Copy

```python
# Wrong (shallow copy)
L1 = [1, 2, 3]
L2 = L1 # Both refer to same list
L2[0] = 100 # Changes L1 also!

# Correct (true copy)
L2 = L1.copy() # or L1[:] or list(L1)
L2[0] = 100 # L1 remains unchanged
```

### āŒ Error 4: Dictionary KeyError

```python
# Wrong
student = {"name": "Rahul"}
print(student["age"]) # KeyError

# Correct
print(student.get("age")) # None (no error)
print(student.get("age", 17)) # 17 (default)
```

### āŒ Error 5: Modifying List While Iterating

```python
# Wrong
L = [1, 2, 3, 4, 5]
for x in L:
if x % 2 == 0:
L.remove(x) # Causes issues

# Correct
L = [x for x in L if x % 2 != 0] # List comprehension
```

---

## 8. Exam-Oriented Short Notes

### šŸŽÆ 2 Marks Questions

**Q1: What is the difference between mutable and immutable data types?**

- **Mutable**: Can be changed after creation (list, dictionary)
- **Immutable**: Cannot be changed after creation (string, tuple)

**Q2: Write output of:**

```python
s = "Computer"
print(s[1:5])
print(s[-3:])
```

**Answer**:

```
ompu
ter
```

**Q3: What is the difference between append() and extend()?**

- `append()`: Adds single element at end
- `extend()`: Adds multiple elements at end

**Q4: Why is tuple faster than list?**

- Tuples are immutable, so Python optimizes them better
- Less memory overhead
- Fixed size allows better performance

---

### šŸŽÆ 3 Marks Questions

**Q1: Explain string slicing with example.**

```python
s = "COMPUTER"
print(s[0:4]) # COMP (0 to 3)
print(s[4:]) # UTER (4 to end)
print(s[:4]) # COMP (start to 3)
print(s[::2]) # CMUE (every 2nd char)
print(s[::-1]) # RETUPMOC (reverse)
```

**Q2: Write a program to count frequency of each element in a list.**

```python
L = [1, 2, 2, 3, 3, 3]
freq = {}
for item in L:
freq[item] = freq.get(item, 0) + 1
print(freq) # {1: 1, 2: 2, 3: 3}
```

**Q3: Differentiate between list and tuple.**

| List | Tuple |
| --- | --- |
| Mutable | Immutable |
| Slower | Faster |
| More memory | Less memory |
| `[1, 2, 3]` | `(1, 2, 3)` |
| Many methods | Few methods |

---

### šŸŽÆ 5 Marks Questions

**Q1: Write a program to implement Bubble Sort.**

```python
def bubble_sort(arr):
n = len(arr)
for i in range(n-1):
swapped = False
for j in range(n-i-1):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
swapped = True
if not swapped:
break
return arr

marks = [64, 34, 25, 12, 22]
print(bubble_sort(marks))
```

**Q2: Write a program to implement Insertion Sort.**

```python
def insertion_sort(arr):
for i in range(1, len(arr)):
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
return arr

numbers = [12, 11, 13, 5, 6]
print(insertion_sort(numbers))
```

**Q3: Write a program to merge two dictionaries.**

```python
d1 = {"name": "Rahul", "age": 17}
d2 = {"marks": 95, "grade": "A"}

# Method 1
d1.update(d2)

# Method 2
d3 = {**d1, **d2}

# Method 3
d3 = d1 | d2 # Python 3.9+

print(d3)
```

---

### šŸ“ Quick Revision Points

**Strings:**

- Immutable, indexed, sliceable
- `len()`, `upper()`, `lower()`, `split()`, `join()`

**Lists:**

- Mutable, ordered, dynamic
- `append()`, `insert()`, `remove()`, `pop()`, `sort()`

**Tuples:**

- Immutable, ordered, faster than lists
- `count()`, `index()`
- Single element: `(5,)`

**Dictionaries:**

- Key-value pairs, unordered*, mutable
- Keys must be unique and immutable
- `keys()`, `values()`, `items()`, `get()`

**Sorting:**

- Bubble Sort: Compare adjacent, swap if needed
- Insertion Sort: Insert element at correct position
- Both O(n²) time complexity

---

### šŸ”„ Most Important Programs for Exam

1. Count vowels/consonants in string
2. Reverse a string using slicing
3. Remove duplicates from list
4. Find largest/smallest in list
5. Merge two lists
6. Create dictionary from two lists
7. Sort dictionary by values
8. Bubble Sort implementation
9. Insertion Sort implementation
10. Linear Search in list