0% found this document useful (0 votes)
3 views41 pages

Python Unit III Notes

This document covers the fundamentals of strings and lists in Python, including their definitions, characteristics, and common operations. It emphasizes the immutability of strings versus the mutability of lists, detailing methods for string manipulation such as slicing, concatenation, and membership checks, as well as list methods like append and sort. Best practices and common errors are highlighted to aid in effective programming.

Uploaded by

Vishnuvardan
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views41 pages

Python Unit III Notes

This document covers the fundamentals of strings and lists in Python, including their definitions, characteristics, and common operations. It emphasizes the immutability of strings versus the mutability of lists, detailing methods for string manipulation such as slicing, concatenation, and membership checks, as well as list methods like append and sort. Best practices and common errors are highlighted to aid in effective programming.

Uploaded by

Vishnuvardan
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Lecture 21: Strings – Operations, Indexing, and Concatenation

Strings are one of the most heavily used data types in Python. They are central to user input
handling, file processing, data cleaning, reporting, and interaction with external systems. In
engineering and scientific programs, strings are not optional—they are infrastructure.
1. What is a String in Python?
Definition
A string is an immutable sequence of characters enclosed within quotes.
Python allows:
• Single quotes: 'Python'
• Double quotes: "Python"
• Triple quotes: """Python""" (mainly for docstrings / multi-line strings)
Example
name = "Python"
department = 'Civil Engineering'
2. Characteristics of Strings
1. Strings are immutable (cannot be modified in place)
2. Strings are ordered (index-based access)
3. Strings support sequence operations
4. Strings can contain spaces and special characters
Immutability implication:
s = "Python"
# s[0] = "J" ERROR
A new string must be created instead.
3. String Indexing
Concept
Each character in a string is assigned an index number.
• Indexing starts at 0
• Negative indexing starts at -1 (from the end)
Example
s = "PYTHON"
Character P YTHON
Index 0 1 2 3 4 5
Character P YTHON
Negative Index -6 -5 -4 -3 -2 -1
Accessing Characters
print(s[0]) # P
print(s[-1]) # N
⚠ Accessing out-of-range index causes IndexError.
4. String Slicing (Brief but Essential)
Syntax
string[start : stop : step]
Rules:
• start → inclusive
• stop → exclusive
• step → optional
Examples
s = "PYTHON"

print(s[1:4]) # YTH
print(s[:3]) # PYT
print(s[::2]) # PTO
print(s[::-1]) # NOHTYP (reverse)
5. String Operations
1. Concatenation (+)
Joins two or more strings.
a = "Hello"
b = "World"

print(a + " " + b)


Output:
Hello World
⚠ Only strings can be concatenated with strings.
# "Age: " + 20 ERROR
"Age: " + str(20) ✔
2. Repetition (*)
Repeats a string.
print("Python " * 3)
Output:
Python Python Python
3. Membership Operators (in, not in)
Checks presence of substring.
print("Py" in "Python") # True
print("Java" not in "Python") # True
4. Length of String
s = "Engineering"
print(len(s))
6. String Comparison
Strings are compared lexicographically (character by character, ASCII/Unicode based).
print("abc" == "abc") # True
print("abc" < "abd") # True
⚠ Case-sensitive:
print("Python" == "python") # False
7. Common String Methods (Operational Awareness)
Method Purpose
upper() Convert to uppercase
lower() Convert to lowercase
strip() Remove leading/trailing spaces
replace() Replace substring
split() Split string into list
Example:
text = " Python Programming "

print([Link]())
print([Link]())
print([Link]())
8. Strings and Input (Very Important)
User input is always a string.
name = input("Enter your name: ")
print(type(name)) # <class 'str'>
Conversion is required for numbers:
age = int(input("Enter age: "))
9. Immutability Demonstration (Must Explain)
s = "Python"
s = s + "3"
print(s)
Explanation:
• Original string not modified
• New string object created
• Reference updated
10. Common Errors (Must Be Explicitly Warned)
1. Index out of range
2. Mixing string and numeric types
3. Assuming strings are mutable
4. Forgetting type conversion during concatenation
5. Misunderstanding slicing boundaries
Incorrect:
print("Value: " + 10)
Correct:
print("Value: " + str(10))
11. Engineering Use Cases of Strings
• Reading and validating user inputs
• Parsing filenames and paths
• Handling CSV and text data
• Generating reports and logs
• Command-based programs
12. Best Practices (Engineering Discipline)
1. Always validate string inputs
2. Use meaningful variable names
3. Avoid hard-coded strings (magic strings)
4. Prefer string methods over manual loops
5. Be cautious with indexing and slicing
13. Summary (Exam-Ready Points)
• Strings are immutable sequences of characters
• Indexing starts from 0; negative indexing is supported
• Slicing extracts substrings
• + concatenates strings
• * repeats strings
• len() returns string length
• Strings support membership and comparison operations
• Input from user is always a string
Lecture 22: String Slicing and Methods — split(), join(), strip()
This lecture extends basic string handling into practical text processing. Slicing extracts
substrings; split(), join(), and strip() clean, tokenize, and reassemble text—core
operations for input validation, data preprocessing, and report generation.
1. String Slicing (Refresher with Precision)
Syntax
string[start : stop : step]
Rules
• start is inclusive
• stop is exclusive
• Defaults: start=0, stop=len(string), step=1
• Negative indices count from the end
• Negative step reverses traversal
Examples
s = "ENGINEERING"

s[0:4] # 'ENGI'
s[5:] # 'EERING'
s[:6] # 'ENGINE'
s[::2] # 'EGNEIG'
s[::-1] # 'GNIREENIG' (reverse)
Engineering note: Prefer slicing over manual loops for clarity and speed.
2. The split() Method — Tokenization
Purpose
Breaks a string into a list of substrings based on a delimiter.
Syntax
[Link](separator=None, maxsplit=-1)
• separator=None → splits on any whitespace
• maxsplit limits number of splits
Examples
text = "Hydrology Water Resources Engineering"

[Link]()
# ['Hydrology', 'Water', 'Resources', 'Engineering']

csv = "10,20,30,40"
[Link](",")
# ['10', '20', '30', '40']

log = "2026-01-03 INFO system started"


[Link](" ", 2)
# ['2026-01-03', 'INFO', 'system started']
Common pitfalls
• split() returns a list, not a string
• Numeric conversion must be explicit after splitting
values = "10 20 30".split()
nums = [int(v) for v in values]
3. The join() Method — Reassembly
Purpose
Joins an iterable of strings into a single string using a delimiter.
Syntax
[Link](iterable)
Critical rule: All elements must be strings.
Examples
words = ["Groundwater", "Recharge", "Zone"]
" ".join(words)
# 'Groundwater Recharge Zone'

path = ["home", "user", "data", "[Link]"]


"/".join(path)
# 'home/user/data/[Link]'
Incorrect
",".join([10, 20, 30]) # TypeError
Correct
",".join(map(str, [10, 20, 30]))
4. strip(), lstrip(), rstrip() — Cleaning Text
Purpose
Remove unwanted leading/trailing characters (default: whitespace).
Syntax
[Link](chars=None)
[Link](chars=None)
[Link](chars=None)
Examples
s = " Python Programming "
[Link]() # 'Python Programming'
[Link]() # 'Python Programming '
[Link]() # ' Python Programming'

code = "***DATA***"
[Link]("*") # 'DATA'
Important: These methods do not remove characters from the middle.
5. Typical Processing Pipeline (Realistic Pattern)
Task: Clean input → tokenize → process → reassemble
raw = " rainfall, runoff , recharge "
clean = [Link]()
parts = [[Link]() for p in [Link](",")]
result = " | ".join(parts)

result
# 'rainfall | runoff | recharge'
This pattern appears constantly in:
• CSV/text ingestion
• CLI input handling
• Report formatting
6. Immutability Reminder
Strings are immutable. All methods return new strings.
s = " data "
[Link]()
print(s) # ' data ' (unchanged)
s = [Link]() # reassignment required
7. Common Errors to Flag Explicitly
1. Expecting split() to modify the string
2. Using join() on non-string elements
3. Forgetting reassignment after strip()
4. Misunderstanding slicing boundaries
5. Using loops instead of built-in methods
8. Best Practices (Engineering Discipline)
• Prefer split()/join() over manual parsing
• Always validate and clean inputs with strip()
• Use slicing for concise substring extraction
• Chain methods thoughtfully but keep readability
• Comment pipelines that perform multiple transformations
9. Summary (Exam-Ready Points)
• Slicing extracts substrings using [start:stop:step]
• split() converts strings into lists of substrings
• join() combines iterable strings using a delimiter
• strip() removes leading/trailing whitespace or characters
• String methods return new strings due to immutability
• These tools are essential for text preprocessing
Lecture 23: Lists — Creation, Indexing, and Mutability
Lists are Python’s workhorse data structure. They store ordered collections of items, allow
modification, and underpin most data-processing workflows. For engineers and scientists, lists
are unavoidable—datasets, time series, grids, parameters, and intermediate results all live in lists
at some point.
1. What is a List?
Definition
A list is an ordered, mutable collection of elements enclosed in square brackets [].
• Elements can be of any data type
• A list can contain mixed types
• Lists preserve insertion order
Examples
numbers = [10, 20, 30]
names = ["Hydrology", "Geology", "GIS"]
mixed = [1, 3.14, "Python", True]
2. Creating Lists
2.1 Direct Literal Creation
values = [5, 10, 15]
2.2 Empty List
data = []
2.3 Using list() Constructor
chars = list("ENGINEER")
# ['E', 'N', 'G', 'I', 'N', 'E', 'E', 'R']
2.4 List from range()
nums = list(range(1, 6))
# [1, 2, 3, 4, 5]
3. List Indexing
Lists use zero-based indexing, identical to strings.
lst = [10, 20, 30, 40]
Element 10 20 30 40
Index 0 1 2 3
Negative Index -4 -3 -2 -1
Accessing Elements
lst[0] # 10
lst[-1] # 40
⚠ Accessing an invalid index raises IndexError.
4. List Slicing
Syntax
list[start : stop : step]
Examples
lst = [10, 20, 30, 40, 50]

lst[1:4] # [20, 30, 40]


lst[:3] # [10, 20, 30]
lst[::2] # [10, 30, 50]
lst[::-1] # [50, 40, 30, 20, 10]
Slicing returns a new list.
5. Mutability of Lists (CRITICAL CONCEPT)
What is Mutability?
Mutability means the object can be changed after creation without creating a new object.
Lists are mutable.
Example
lst = [10, 20, 30]
lst[1] = 25
print(lst)
Output:
[10, 25, 30]
The list is modified in place.
6. Lists vs Strings (Contrast with Lecture 21–22)
Feature List String
Mutable Yes No
Indexing Yes Yes
Slicing Yes Yes
Modification In-place Requires new string
Feature List String
Brackets [] Quotes
String (immutable)
s = "Python"
# s[0] = "J" ERROR
List (mutable)
lst = ["P", "y", "t", "h", "o", "n"]
lst[0] = "J" # ✔ Allowed
7. Common List Operations (Introductory)
Length
len(lst)
Membership
20 in lst
Concatenation
[1, 2] + [3, 4] # [1, 2, 3, 4]
Repetition
[0] * 5 # [0, 0, 0, 0, 0]
8. Nested Lists (Preview)
Lists can contain other lists.
matrix = [
[1, 2, 3],
[4, 5, 6]
]
Access:
matrix[0][1] # 2
Used in:
• Matrices
• Grids
• Spatial data
• Tables
9. Reference Behavior (Important Warning)
Assignment does not copy a list.
a = [1, 2, 3]
b = a
b[0] = 99

print(a)
Output:
[99, 2, 3]
Both names refer to the same list.
To copy:
b = a[:] # shallow copy
10. Common Errors (Must Be Highlighted)
1. Index out of range
2. Assuming assignment copies a list
3. Confusing list and string behavior
4. Forgetting lists are mutable
5. Modifying a list unintentionally via another reference
11. Engineering Use Cases
• Storing measurement data
• Time-series values
• Parameter sets for simulations
• Intermediate computation results
• Reading data from files (CSV, logs)
12. Best Practices (Engineering Discipline)
1. Use lists for collections that change
2. Avoid unintended shared references
3. Use slicing to copy when needed
4. Use meaningful variable names
5. Keep lists homogeneous when possible (for clarity)
13. Summary (Exam-Ready Points)
• Lists are ordered, mutable collections
• Created using [] or list()
• Indexing starts from 0; negative indexing supported
• Slicing extracts sublists
• Lists are mutable; elements can be changed
• Assignment copies references, not values
• Lists differ fundamentally from strings in mutability
Lecture 24: List Methods — append(), sort(), and pop()
This lecture focuses on core list-manipulation methods that every Python programmer must
master. These methods modify lists in place and are central to data accumulation, ordering, and
controlled removal—common patterns in engineering data processing and algorithms.
1. Recap: Lists Are Mutable
Lists can be changed without creating a new object. The methods covered here operate in
place, meaning they directly modify the existing list.
data = [10, 20, 30]
2. append() — Adding Elements to a List
Purpose
Adds one element to the end of a list.
Syntax
[Link](element)
Examples
values = [10, 20, 30]
[Link](40)
print(values)
Output:
[10, 20, 30, 40]
Important Characteristics
• Adds exactly one item
• Modifies the list in place
• Returns None
result = [Link](50)
print(result) # None
⚠ Do not assign the result of append().
Appending Different Data Types
lst = []
[Link](10)
[Link](3.14)
[Link]("Python")
Appending a List (Common Trap)
a = [1, 2]
[Link]([3, 4])
print(a)
Output:
[1, 2, [3, 4]]
This creates a nested list, not a flat list.
3. sort() — Ordering List Elements
Purpose
Sorts the elements of a list in ascending order by default.
Syntax
[Link]()
Example
numbers = [40, 10, 30, 20]
[Link]()
print(numbers)
Output:
[10, 20, 30, 40]
Key Characteristics
• Sorts in place
• Returns None
• Original order is lost
print([Link]()) # None
Sorting in Descending Order
[Link](reverse=True)
Sorting Strings
names = ["delta", "alpha", "charlie"]
[Link]()
print(names)
Output:
['alpha', 'charlie', 'delta']
⚠ Sorting is case-sensitive:
["apple", "Banana"].sort()
# ['Banana', 'apple']
Engineering Note
Use sort() only when:
• In-place modification is intended
• Original ordering is not required
(Non-destructive sorting using sorted() is covered later.)
4. pop() — Removing and Returning Elements
Purpose
Removes and returns an element from the list.
Syntax
[Link](index)
• index is optional
• Default index = -1 (last element)
Examples
Pop Last Element
data = [10, 20, 30, 40]
x = [Link]()
print(x)
print(data)
Output:
40
[10, 20, 30]
Pop Specific Index
y = [Link](1)
print(y)
print(data)
Output:
20
[10, 30]
Key Characteristics
• Modifies list in place
• Returns the removed element
• Raises IndexError if index is invalid
[Link](10) # IndexError
5. append() vs pop() — Stack Behavior
Using append() and pop() together creates a stack (LIFO) structure.
stack = []
[Link](10)
[Link](20)
[Link](30)

[Link]() # 30
[Link]() # 20
Used in:
• Undo operations
• Backtracking algorithms
• Expression evaluation
6. Summary Comparison of Methods
Method Operation In-place Returns
append(x) Add element at end Yes None
sort() Arrange elements Yes None
pop(i) Remove element Yes Removed value
7. Common Student Errors (Must Be Corrected)
1. Assigning the result of append() or sort()
2. Expecting sort() to return a new list
3. Confusing append() with list concatenation
4. Popping from an empty list
5. Assuming pop() does not modify the list
Incorrect:
new_list = my_list.sort()
Correct:
my_list.sort()
8. Best Practices (Engineering Discipline)
1. Use append() for incremental data collection
2. Use sort() only when original order is not needed
3. Use pop() when the removed value must be reused
4. Always validate list size before popping
5. Comment logic when using lists as stacks
9. Engineering Use Cases
• Collecting sensor data (append)
• Ranking or ordering results (sort)
• Processing tasks sequentially (pop)
• Simulation time-step handling
• Data cleaning pipelines
10. Summary (Exam-Ready Points)
• append() adds a single element to the end of a list
• sort() arranges list elements in ascending or descending order
• pop() removes and returns an element
• All three methods modify the list in place
• append() and sort() return None
• pop() returns the removed element
• These methods rely on list mutability
Lecture 25: Tuples — Immutability and Usage Scenarios
Tuples are a fundamental but often misunderstood data structure in Python. They look similar
to lists but behave very differently. Understanding immutability and appropriate usage
scenarios is essential for writing safe, predictable, and efficient programs—especially in
engineering and scientific applications.
1. What is a Tuple?
Definition
A tuple is an ordered, immutable collection of elements, enclosed in parentheses ().
• Elements can be of any data type
• Tuples preserve order
• Once created, a tuple cannot be modified
Examples
coordinates = (10, 20)
record = ("Station-1", 12.5, True)
single = (5,) # single-element tuple
⚠ Important:
x = (5) # NOT a tuple
x = (5,) # tuple
2. Creating Tuples
2.1 Direct Creation
t = (1, 2, 3)
2.2 Tuple without Parentheses (Tuple Packing)
t = 1, 2, 3
2.3 Empty Tuple
empty = ()
2.4 Tuple from Other Iterables
lst = [10, 20, 30]
t = tuple(lst)
3. Tuple Indexing and Slicing
Tuples support indexing and slicing, just like lists and strings.
t = (10, 20, 30, 40)
Indexing
t[0] # 10
t[-1] # 40
Slicing
t[1:3] # (20, 30)
t[::-1] # (40, 30, 20, 10)
⚠ Index out of range → IndexError.
4. Immutability of Tuples (CRITICAL CONCEPT)
What is Immutability?
Immutability means the object cannot be changed after creation.
Example
t = (10, 20, 30)
t[1] = 25 # ERROR
Error:
TypeError: 'tuple' object does not support item assignment
This is the defining feature of tuples.
Contrast with Lists
lst = [10, 20, 30]
lst[1] = 25 # ✔ Allowed
5. Tuple vs List (Exam-Favourite Comparison)
Feature Tuple List
Mutable No ✔ Yes
Syntax () []
Modification Not allowed Allowed
Speed Faster Slower
Safety High Lower
Use case Fixed data Dynamic data
6. Why Use Tuples? (Design Rationale)
Tuples are used when:
• Data must not change
• Data represents a single logical entity
• Safety and predictability are required
Key idea:
Use tuples to protect data integrity.
7. Common Usage Scenarios of Tuples
7.1 Coordinates and Geometry
point = (12.5, 77.6)
Coordinates should not change accidentally.
7.2 Function Return Values (Very Important)
Python returns multiple values as a tuple.
def min_max(values):
return min(values), max(values)

result = min_max([10, 5, 20])


print(result) # (5, 20)
7.3 Tuple Unpacking
a, b = (10, 20)
Used in:
• Swapping values
• Multiple assignments
• Function returns
7.4 Dictionary Keys (Preview)
Tuples can be used as dictionary keys (lists cannot).
locations = {
(12.5, 77.6): "Station A",
(13.0, 78.1): "Station B"
}
7.5 Fixed Records
sensor = ("S01", 25.4, "OK")
Represents a read-only record.
8. Tuple Methods (Limited by Design)
Tuples have only two built-in methods:
t = (10, 20, 10, 30)

[Link](10) # 2
[Link](30) # 3
Reason:
• Tuples are immutable
• No methods that modify content
9. Nested Tuples
Tuples can contain other tuples.
data = (
(1, 2),
(3, 4)
)
Access:
data[0][1] # 2
⚠ Inner mutable objects inside a tuple can change.
t = (1, [2, 3])
t[1].append(4)
print(t) # (1, [2, 3, 4])
The tuple is immutable, but the list inside is not.
10. Common Student Errors (Must Be Explicitly Corrected)
1. Trying to modify tuple elements
2. Forgetting the comma in single-element tuples
3. Using tuples where lists are required
4. Assuming tuples and lists behave the same
5. Ignoring immutability during design
11. Best Practices (Engineering Discipline)
1. Use tuples for fixed, related data
2. Use lists for data that changes
3. Prefer tuples for function returns
4. Use tuples to prevent accidental modification
5. Document tuple structure clearly
12. Engineering Use Cases
• Coordinates and spatial data points
• Sensor readings (ID, value, status)
• Configuration constants
• Lookup keys
• Returning multiple computed values
13. Summary (Exam-Ready Points)
• Tuples are ordered and immutable collections
• Created using parentheses ()
• Support indexing and slicing
• Cannot be modified after creation
• Safer and faster than lists
• Ideal for fixed data and function returns
• Tuples differ fundamentally from lists due to immutability
Lecture 26: Sets — Unordered Collections and Uniqueness
Sets are Python’s mathematical collection type. They are designed to store unique elements
with no guaranteed order, making them ideal for membership testing, duplicate elimination,
and set algebra (union, intersection, difference). In engineering and data workflows, sets are
indispensable for cleaning data and enforcing constraints.
1. What is a Set?
Definition
A set is an unordered, mutable collection of unique elements, created using curly braces {}
or the set() constructor.
Key properties:
• Unordered (no indexing)
• Unique elements only
• Mutable container (elements can be added/removed)
• Elements must be hashable (immutable types)
Examples
stations = {"A", "B", "C"}
numbers = {1, 2, 3, 3} # duplicates removed automatically
print(numbers) # {1, 2, 3}
2. Creating Sets
2.1 Literal Creation
s = {10, 20, 30}
2.2 Empty Set (Important)
empty = set() # NOT {}
{} creates an empty dictionary, not a set.
2.3 From Other Iterables
s = set([1, 2, 2, 3])
# {1, 2, 3}

chars = set("ENGINEER")
# {'E', 'N', 'G', 'I', 'R'} (order not guaranteed)
3. Unordered Nature of Sets
Sets do not support indexing or slicing.
s = {10, 20, 30}
# s[0] TypeError
Reason:
• Sets are optimized for membership tests, not positional access.
4. Uniqueness Guarantee (Core Concept)
Any duplicate added to a set is ignored.
ids = {101, 102, 103}
[Link](102)
print(ids) # {101, 102, 103}
Use case:
• Removing duplicates from data
• Enforcing uniqueness constraints
5. Common Set Methods
5.1 add() — Add One Element
s = {1, 2}
[Link](3)
# {1, 2, 3}
5.2 update() — Add Multiple Elements
[Link]([3, 4, 5])
# {1, 2, 3, 4, 5}
5.3 remove() vs discard()
[Link](3) # KeyError if 3 not present
[Link](10) # No error if absent
5.4 pop()
x = [Link]() # removes an arbitrary element
⚠ Because sets are unordered, pop() removes any element.
6. Membership Testing (Fast and Critical)
if 20 in s:
print("Present")
Set membership is much faster than lists for large datasets.
7. Set Operations (Mathematical Power)
7.1 Union
A = {1, 2, 3}
B = {3, 4, 5}
A | B # {1, 2, 3, 4, 5}
7.2 Intersection
A & B # {3}
7.3 Difference
A - B # {1, 2}
7.4 Symmetric Difference
A ^ B # {1, 2, 4, 5}
8. Set vs List vs Tuple (Exam-Favourite)
Feature Set List Tuple
Ordered No ✔ Yes ✔ Yes

Duplicates No ✔ Yes ✔ Yes

Mutable ✔ Yes ✔ Yes No

Indexing No ✔ Yes ✔ Yes


Use case Uniqueness, algebra Dynamic data Fixed records
9. Valid and Invalid Set Elements
Valid (Hashable)
• int, float, str, tuple
Invalid (Unhashable)
• list, dict, set
s = {(1, 2), (3, 4)} # ✔ valid
# s = {[1, 2]} # invalid
10. Engineering Use Cases
• Removing duplicate sensor IDs
• Finding common elements across datasets
• Tracking visited nodes/states
• Validating unique inputs
• Fast membership checks
Example:
unique_ids = set(raw_ids)
11. Common Student Errors (Must Be Flagged)
1. Using {} for empty set
2. Expecting order or indexing
3. Confusing remove() and discard()
4. Assuming pop() removes a specific element
5. Trying to store mutable items in a set
12. Best Practices (Engineering Discipline)
1. Use sets for uniqueness and membership
2. Convert lists to sets to remove duplicates
3. Avoid remove() unless sure the element exists
4. Use set operations for clarity and speed
5. Do not rely on set order
13. Summary (Exam-Ready Points)
• Sets are unordered collections of unique elements
• Created using {} or set()
• Do not support indexing or slicing
• Automatically remove duplicates
• Support fast membership testing
• Provide powerful mathematical operations
• Ideal for data cleaning and constraint enforcement
Lecture 27: Set Operations — Union, Intersection, and Difference
This lecture builds directly on Lecture 26 (Sets: Unordered Collections and Uniqueness) and
introduces set algebra operations. These operations are fundamental for data comparison,
filtering, overlap analysis, and constraint enforcement—common tasks in engineering,
scientific computing, and data analytics.
1. Why Set Operations Matter
Set operations allow you to:
• Combine datasets
• Identify common elements
• Remove unwanted elements
• Compare groups logically
Key idea:
Set operations work on membership, not position.
2. Union of Sets
Definition
The union of two sets contains all unique elements from both sets.
Mathematical Notation
𝐴∪𝐵
Python Syntax
Operator Form
A | B
Method Form
[Link](B)
Example
A = {1, 2, 3}
B = {3, 4, 5}

print(A | B)
Output:
{1, 2, 3, 4, 5}
Engineering Use Case
• Combine sensor IDs from two monitoring stations
• Merge unique records from multiple sources
3. Intersection of Sets
Definition
The intersection contains only elements common to both sets.
Mathematical Notation
𝐴∩𝐵
Python Syntax
Operator Form
A & B
Method Form
[Link](B)
Example
A = {10, 20, 30}
B = {20, 30, 40}

print(A & B)
Output:
{20, 30}
Engineering Use Case
• Find common wells monitored in two years
• Identify overlapping parameters in datasets
4. Difference of Sets
Definition
The difference contains elements that are in one set but not the other.
Mathematical Notation
𝐴−𝐵
Python Syntax
Operator Form
A - B
Method Form
[Link](B)
Example
A = {1, 2, 3, 4}
B = {3, 4}
print(A - B)
Output:
{1, 2}
⚠ Order matters:
B - A # Empty set
Engineering Use Case
• Identify stations removed from a monitoring network
• Filter invalid or excluded data points
5. Symmetric Difference (Extension)
Definition
Contains elements present in either set but not both.
Mathematical Notation
𝐴△𝐵
Python Syntax
A ^ B
Example
A = {1, 2, 3}
B = {3, 4, 5}

print(A ^ B)
Output:
{1, 2, 4, 5}
6. Method vs Operator Forms (Exam-Relevant)
Operation Operator Method
Union `A B`
Intersection A & B [Link](B)
Difference A - B [Link](B)
Symmetric Difference A ^ B A.symmetric_difference(B)
Both are valid.
Operators are shorter and clearer; methods are more explicit.
7. In-place Set Operations (Important Distinction)
These modify the original set.
A |= B # Union update
A &= B # Intersection update
A -= B # Difference update
A ^= B # Symmetric difference update
Example:
A = {1, 2, 3}
B = {3, 4}

A &= B
print(A)
Output:
{3}
8. Chaining Set Operations
A = {1, 2, 3, 4}
B = {3, 4, 5}
C = {4, 5, 6}

result = (A & B) | C
print(result)
Execution:
• Intersection of A and B → {3, 4}
• Union with C → {3, 4, 5, 6}
9. Constraints and Rules (Must Be Explained)
1. Operands must be sets or set-like
2. Results are always sets
3. Order is never preserved
4. Duplicates are automatically removed
10. Common Student Errors (Explicitly Warn)
1. Expecting ordered output
2. Confusing union with addition
3. Using lists instead of sets for set operations
4. Forgetting order sensitivity in difference
5. Modifying original sets unintentionally with in-place operations
Incorrect:
[1, 2] | [2, 3] # TypeError
Correct:
set([1, 2]) | set([2, 3])
11. Best Practices (Engineering Discipline)
1. Convert datasets to sets before comparison
2. Use intersection for validation checks
3. Use difference for exclusion logic
4. Avoid in-place operations unless intentional
5. Clearly document set logic in algorithms
12. Engineering Use Cases Summary
• Data cleaning and deduplication
• Comparing datasets across time/space
• Identifying overlaps and exclusions
• Rule-based filtering
• Validation of unique constraints
13. Summary (Exam-Ready Points)
• Union combines all unique elements
• Intersection finds common elements
• Difference finds exclusive elements
• Python supports operator and method syntax
• Set operations are unordered and duplicate-free
• In-place operations modify original sets
• Set algebra simplifies complex comparison logic
Lecture 28: Dictionaries — Key-Value Mapping and Nesting
Dictionaries are Python’s most powerful and flexible data structure. They store data as key–
value pairs, enabling fast lookup, structured representation, and real-world modeling. In
engineering, dictionaries are used for configuration data, metadata, mappings, structured
records, and hierarchical datasets.
1. What is a Dictionary?
Definition
A dictionary is an unordered, mutable collection of key–value pairs, enclosed in curly
braces {}.
student = {
"name": "Arun",
"roll": 101,
"cgpa": 8.4
}
Key idea:
Values are accessed using keys, not positions.
2. Key Characteristics of Dictionaries
1. Stored as key : value pairs
2. Keys must be unique and immutable
3. Values can be any data type
4. Dictionaries are mutable
5. Access time is very fast (hash-based)
3. Creating Dictionaries
3.1 Literal Creation
dept = {"CE": "Civil", "ME": "Mechanical"}
3.2 Empty Dictionary
data = {}
3.3 Using dict() Constructor
info = dict(name="Python", year=1991)
3.4 From Sequences
keys = ["a", "b", "c"]
values = [1, 2, 3]
d = dict(zip(keys, values))
4. Accessing Dictionary Values
Using Keys
print(student["name"])
⚠ Accessing a missing key raises KeyError.
Safe Access Using get()
print([Link]("age")) # None
print([Link]("age", 0)) # Default value
5. Modifying Dictionaries (Mutability)
Adding or Updating Entries
student["age"] = 20 # add
student["cgpa"] = 8.6 # update
Removing Entries
[Link]("roll")
del student["name"]
6. Iterating Over Dictionaries (Intro Level)
for key in student:
print(key, student[key])
Common views:
[Link]()
[Link]()
[Link]()
7. Dictionary Keys: Rules and Constraints
Valid Keys (Hashable)
• int, float, str, tuple
Invalid Keys (Unhashable)
• list, dict, set
location = {(12.5, 77.6): "Station A"} # ✔ valid
# {[1,2]: "X"} # invalid
8. Dictionary Nesting (CRITICAL CONCEPT)
What is Nesting?
A nested dictionary contains another dictionary as a value.
Example: Nested Dictionary
students = {
"S01": {"name": "Arun", "cgpa": 8.2},
"S02": {"name": "Kiran", "cgpa": 8.7}
}
Accessing Nested Data
print(students["S01"]["cgpa"])
Engineering Example (Structured Data)
station = {
"id": "GW01",
"location": {"lat": 12.5, "lon": 77.6},
"readings": {"pH": 7.1, "EC": 850}
}
Access:
station["readings"]["EC"]
9. Dictionary vs Other Data Structures (Exam-Favourite)
Feature Dictionary List Tuple Set
Access by Key Index Index Membership
Ordered (logical) ✔ ✔

Mutable ✔ ✔ ✔

Duplicates Keys ✔ ✔
Use case Mappings Sequences Fixed records Uniqueness
10. Common Errors (Must Be Flagged)
1. Using mutable types as keys
2. Assuming dictionary order matters
3. Accessing missing keys directly
4. Confusing list indexing with dict access
5. Deep nesting without clarity
Incorrect:
d = {}
print(d["x"]) # KeyError
Correct:
print([Link]("x"))
11. Engineering Use Cases
• Configuration files
• Metadata storage
• JSON-like hierarchical data
• Mapping IDs to properties
• Structured sensor datasets
12. Best Practices (Engineering Discipline)
1. Use dictionaries for named data
2. Keep keys simple and consistent
3. Use nesting to represent hierarchy
4. Avoid overly deep nesting
5. Use get() for safe access
6. Comment complex nested structures
13. Summary (Exam-Ready Points)
• Dictionaries store data as key–value pairs
• Keys must be unique and immutable
• Values can be of any type
• Dictionaries are mutable and fast
• Nested dictionaries model hierarchical data
• Access is by key, not index
• Ideal for structured and real-world data representation
Lecture 29: Introduction to List Comprehensions
List comprehensions provide a concise, readable, and efficient way to create lists in Python.
They replace common loop-based patterns with a single expressive construct. In engineering and
data workflows, list comprehensions are routinely used for data transformation, filtering, and
projection.
1. What is a List Comprehension?
Definition
A list comprehension is a compact syntax to create a new list by iterating over an iterable,
optionally filtering elements, and applying an expression.
Key idea:
Transform and filter data in one readable line.
2. Basic Syntax
[expression for item in iterable]
• expression → what to compute/store
• item → loop variable
• iterable → sequence (list, range, string, etc.)
Example
squares = [x*x for x in range(1, 6)]
# [1, 4, 9, 16, 25]
3. Comparison with Traditional for Loop
Using a for loop
squares = []
for x in range(1, 6):
[Link](x*x)
Using a list comprehension
squares = [x*x for x in range(1, 6)]
Benefits
• Fewer lines
• Less boilerplate
• Clear intent
4. List Comprehensions with Conditions (Filtering)
Syntax
[expression for item in iterable if condition]
Example
even_numbers = [x for x in range(1, 11) if x % 2 == 0]
# [2, 4, 6, 8, 10]
Use cases:
• Remove invalid data
• Select values meeting thresholds
• Filter datasets
5. Transforming Data
values = [10, 20, 30]
scaled = [v/10 for v in values]
# [1.0, 2.0, 3.0]
Common engineering use:
• Unit conversions
• Normalization
• Feature scaling (intro level)
6. Using if–else Inside a List Comprehension
Syntax (note the position)
[expr_if_true if condition else expr_if_false for item in
iterable]
Example
labels = ["High" if x > 50 else "Low" for x in [30, 60, 45, 80]]
# ['Low', 'High', 'Low', 'High']
⚠ Common mistake: placing else at the end (incorrect).
7. Working with Strings and Lists
names = [" python ", " data ", " engineering "]
clean = [[Link]().title() for n in names]
# ['Python', 'Data', 'Engineering']
This replaces multi-step cleaning loops with a single line.
8. Nested List Comprehensions (Introductory Preview)
Used for 2D structures (matrices, grids).
matrix = [[i*j for j in range(1, 4)] for i in range(1, 4)]
# [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
Guideline:
• Use sparingly
• Prefer clarity over cleverness
9. When NOT to Use List Comprehensions
Avoid when:
• Logic is complex or deeply nested
• Multiple side effects are required
• Readability suffers
Bad practice:
[x if x%2==0 else x*3 for x in data if x>10]
Prefer a loop if intent is unclear.
10. Performance Note (Conceptual)
• List comprehensions are generally faster than equivalent loops
• Implemented in optimized C under the hood
• Gains are noticeable for large datasets
11. Common Errors (Must Be Explicitly Warned)
1. Forgetting brackets []
2. Misplacing if / else
3. Overcomplicating expressions
4. Assuming in-place modification (they create new lists)
5. Using list comprehensions for side effects (printing)
Incorrect:
[[Link](5) for x in data] # misuse
Correct:
[x+5 for x in data]
12. Best Practices (Engineering Discipline)
1. Use list comprehensions for simple transformations
2. Keep expressions short and readable
3. Prefer clarity over one-line cleverness
4. Comment complex comprehensions
5. Remember: they create new lists
13. Engineering Use Cases
• Data cleaning and filtering
• Generating parameter lists
• Processing sensor readings
• Transforming datasets for plotting
• Preparing inputs for algorithms
14. Summary (Exam-Ready Points)
• List comprehensions create lists concisely
• Basic form: [expression for item in iterable]
• Optional filtering using if
• if–else can be embedded in expressions
• They create new lists, not in-place changes
• Faster and more readable than loops when used correctly

You might also like