Module 2
Module 2
Working with strings as single things, working with the parts of a string, Length, Traversal and the for
loop, Slices, String comparison. Strings are immutable, the in and not in operators. A find function,
optional parameters. The built-in find method. The split method, Cleaning up your strings. The string
format [Link]: Tuples are used for grouping data, Tuple assignment, Tuples as return values,
Composability of Data Structures. Lists: List values, accessing elements, List length, List membership,
List operations, List slices, Lists are mutable, List deletion, Objects and references, Aliasing, cloning
lists, Lists and for loops, List parameters, List methods, Pure functions and modifiers, Functions that
produce lists, Strings and lists, list and range, Nested lists, Matrices.
String
Example
s = "Hello"
Just like a turtle in the turtle module is an object with: attributes (color, position, etc.),methods
(forward(), left(), etc.)
A string is also an object in Python.
Example
our_string = "Hello, World!"
all_caps = our_string.upper()
Output:
string methods
✔ upper()
"python".upper()
Output: "PYTHON"
✔ lower()
"HELLO".lower()
✔capitalize()
"python".capitalize()
✔ swapcase()
"PyThOn".swapcase()
✔ find()
"banana".find("na")
✔ count()
"banana".count("a")
"Python".startswith("Py")
✔ endswith()
"Python".endswith("on")
✔ replace()
✔ strip()
split() Method
Purpose:
🔹 Syntax:
[Link](separator)
🔹 Example:
"a,b,c".split(",")
🔹 Output:
['a', 'b', 'c']
Explanation:
Example:
Combines elements of a list (or iterable) into a single string using a specified separator.
Syntax:
[Link](iterable)
Example:
Output:
'a,b,c'
Explanation:
In this case, the comma , acts as the separator used to join the elements of a list. When the join() method
is applied, it takes each element from the list and combines them into a single string, placing the
separator between each element. This means that instead of having separate items in a list, all elements
are merged together with the specified separator in between, resulting in one complete string.
Example:
Output:
● All elements in the iterable must be strings, otherwise an error will occur.
1. isalnum()
"abc123".isalnum()
Output: True
2. isalpha()
"Python".isalpha()
Output: True
3. isdigit()
"12345".isdigit()
Output: True
Indexing in Strings
A = "HELLO PYTHON"
print(A[2]) // Output: L
print(A[-5]) // Y
Print(A[0]) // H
print(A[11]) // N
print(A[5]) // space
It is a built-in function that adds a counter (index) to an iterable (like string, list, tuple).It allows you to
access:
● Index (position)
● Value (element)
at the same time.
Syntax
enumerate(iterable, start=0)
Parameters: iterable → string, list, tuple, etc, start → optional starting index (default = 0)
Example:
text = "Python"
print(index, value)
print(i, fruit)
Output:
1 Apple
2 Mango
3 Banana
Example:
word = "banana"
len(word) // Output:6
size = len(word)
Traversal means processing each character of a string one by one, usually from the beginning to the
end. Many programs need to Check each character,Count letters,Modify text,Print characters
separatelyThis step-by-step processing is called string traversal.
The for loop is considered better in Python because it is shorter, clearer, and easier to understand
compared to other looping methods like the while loop. It reduces the amount of code needed and avoids
manually handling index values, which makes the program more readable. Since there is no need to
explicitly update variables (like incrementing an index), it is less error-prone and helps prevent common
mistakes such as infinite loops. Overall, the for loop follows Python’s simple and clean coding style,
making it more “Pythonic” and preferred for iteration.
In a for loop, Python automatically selects each character from the string one by one during iteration, so
there is no need to manually use an index to access elements. This means you do not have to rely on
functions like len() to control the loop. The loop continues smoothly through all characters and stops
automatically once it reaches the end of the string. This makes the process simple, efficient, and easy to
use.
word = "Banana"
for letter in word:
print(letter)
Output:
B
a
n
a
suffix = "ack"
for p in prefixes:
print(p + suffix)
Output
Jack
Kack
Lack
Mack
Nack
Oack
Pack
Qack
Slices
string slicing means extracting a part (substring) of a string using index positions.
Syntax
string_name[start : end]
print(text[0:4])
Output: Pyth
P y t h o n
0 1 2 3 4 5
print(text[:3]) // Pyt
print(text[2:]) // thon
print(text[:]) // Python
● == → equal
● != → not equal
● < → less than
● > → greater than
● <= → less than or equal
● >= → greater than or equal
These comparisons are based on lexicographical (dictionary) order using ASCII/Unicode values.
Example:
word = "banana"
if word == "banana":
Output:
Yes, we have no bananas!
Example:
if word < "banana":
else:
print("Same word!")
Python compares strings in a character-by-character manner when using comparison operators. It starts
by comparing the first character of both strings; if they are equal, it moves on to the next character. This
process continues step by step, checking each corresponding character in sequence, until a difference is
found. As soon as a mismatch occurs, Python determines the result of the comparison based on the
ASCII/Unicode values of the differing characters.
3. Internal Working
Example:
"apple" < "banana"
True
The expression evaluates to True because Python compares the strings starting with their first
characters. In this case, it compares 'a' from the first string with 'b' from the second string. Since the
ASCII value of 'a' is less than the ASCII value of 'b', Python determines that the first string is smaller,
and therefore the comparison returns True.
Example:
"Zebra" < "banana"
True
When comparing the strings, Python first looks at the first characters, which are 'Z' and 'b'. It then
checks their ASCII values, where the value of 'Z' is smaller than that of 'b'. Because of this, Python
determines that 'Z' comes before 'b', and therefore the comparison evaluates to True.
Example:
word = "Zebra"
print("Before banana")
False
The lower() function converts all characters in a string to lowercase, which helps ensure a fair
comparison. In this case, "Zebra" becomes "zebra", and the comparison is now "zebra" < "banana".
Python compares the first characters, 'z' and 'b', and since the ASCII value of 'z' is greater than 'b', it
determines that "zebra" comes after "banana". Therefore, the result of the comparison is False.
In Python, once a string is created, it cannot be changed, which means strings are immutable. In the
given example,
greeting = "Hello, world!", when we try to change the first character using
greeting[0] = 'J'
Python raises an error. This is because indexing in strings is only used to access characters, not to
modify them. Since strings do not support changing individual characters directly, Python throws a
TypeError stating that a string object does not support item assignment. To modify a string, we must
create a new string instead of changing the existing one.
Output:
Jello, world!
The in operator is used to check whether something exists inside something else.
When both operands are strings, in checks whether the left string is a substring of the right string.
Syntax:
substring in main_string
Syntax:
substring not in main_string
Example:
def remove_vowels(phrase):
vowels = "aeiou"
string_sans_vowels = “”
string_sans_vowels += letter
return string_sans_vowels
find() function
The find() function in Python is used to search for a substring within a string. It returns the index
Python Programming (BBPYPB205), Department of CSE Module 2
14
(position) of the first occurrence of the specified substring. If the substring is not found, it does not raise
an error; instead, it returns -1, making it a safe way to perform searches. The syntax of the function is
[Link](substring, start, end), where substring is the value you want to search for, start is an optional
parameter that specifies the index from where the search should begin, and end is another optional
parameter that defines the position where the search should stop.
Basic Example
text = "Bananarama!"
print([Link]("a"))
Output:
1
Output:
-1
So unlike some functions, it does not give an error, it safely returns -1.
Output:
2
Output:
3
Python Programming (BBPYPB205), Department of CSE Module 2
15
It starts searching from index 2
def count_a(text):
count = 0
if letter == "a":
count += 1
return(count)
print(count_a("banana") == 3)
Output: True
optional parameter
An optional parameter is a function parameter that has a default value assigned in the function
definition.
If the user does not provide a value for that parameter while calling the function, Python automatically
uses the default value.
Basic Syntax
Simple Example
def greet(name="Student"):
Function Calls:
greet("Yashaswini")
Output:
Hello Yashaswini
greet()
Output:
Hello Student
split() method
The split() method in Python is used to divide a string into a list of smaller parts based on a specified
separator. It breaks the string wherever the separator occurs and returns a list containing the resulting
substrings. If no separator is provided, Python automatically splits the string based on spaces. This
method is very useful when working with sentences, data processing, or user input where values need to
be separated and handled individually.
Example
words = [Link]()
print(words)
Cleaning a string means removing unwanted characters such as punctuation marks (like ! , . ? ; :),
newline characters (\n), tabs (\t), and extra spaces to make the text neat and easier to process. This is
especially important when performing tasks like counting word frequency, checking spelling, analyzing
text from files or the internet, or handling user input, where unwanted symbols can affect accuracy. One
common way to clean a string is by using a loop to examine each character and remove unwanted ones.
For example, using [Link], we can check whether a character is a punctuation mark and skip
it while building a new cleaned string.
Python Programming (BBPYPB205), Department of CSE Module 2
17
The function remove_punctuation() works by iterating through each letter in the given phrase and
adding only those characters that are not punctuation to a new string. In addition to this approach,
built-in methods like .split() can also help in cleaning and organizing text by breaking it into meaningful
parts.
import string
def remove_punctuation(phrase):
cleaned = ""
for letter in phrase:
if letter not in [Link]:
cleaned += letter
return cleaned
The String Format Method
String formatting is the process of inserting values (variables) into a string in a clean and readable way.
Instead of joining strings using +, formatting lets us embed variables inside strings easily.
Example:
name = "Yashaswini"
age = 20
Output:
Example:
Output:
Tuples
Tuples are used for grouping data by storing multiple related values together in a single variable. A tuple
is a collection of elements written using parentheses (), and it can contain different data types such as
strings, integers, or more. Tuples are ordered, which means the elements maintain their position, and
they are immutable, meaning their values cannot be changed after creation. This makes tuples useful
when we want to store fixed data that should not be modified
Example:
Tuple Assignment
Tuple assignment is a feature in Python that allows you to assign multiple values to multiple variables in
a single line. It works by unpacking the values from a tuple (or any iterable) and assigning them to
corresponding variables in order. This makes the code shorter, cleaner, and easier to read compared to
assigning each variable separately.
Example:
print(name) # Sai
print(age) # 21
print(course) # CSE
a = 10
b = 20
a, b = b, a
print(a, b) # 20 10
Here, Python automatically swaps the values of a and b using tuple assignment.
Overall, tuple assignment simplifies code, reduces the number of lines, and is considered a more
Pythonic way of handling multiple assignments.
In Python, functions can return multiple values at once by using tuples. When we return more than one
value separated by commas, Python automatically groups them into a tuple. This makes it easy to send
back multiple results from a function without needing separate variables or complex data structures.
Example:
sum = a + b
diff = a - b
result = calculate(10, 5)
print(result)
Output: (15, 5)
Composability of data structures means that different data structures in Python, such as lists, tuples, and
dictionaries, can be combined or nested inside one another to represent more complex data. Instead of
using a single data structure, we can build structured and organized data by placing one type inside
For example, a tuple inside a list can be used to store multiple records, such as student names and
marks. A list inside a tuple can group related collections together while keeping the overall structure
fixed. Similarly, a dictionary inside a tuple can store key-value pairs within a grouped structure. This
ability to combine data structures allows us to organize information in a hierarchical way, making it
easier to access, manage, and process data efficiently in Python programs.
Output:
Sai 80
Ravi 90
Anu 85
Output:
Lists
List Values
Syntax:
list_name = [value1, value2, value3, ...]
Output:
[10, 20, 30, 40]
Output:
[10, 'Python', 3.5, True]
Accessing Elements
Accessing elements in a list means retrieving individual items from the list using their position, known
as an index. In Python, lists are ordered, so each element is assigned an index starting from 0. This
means the first element is at index 0, the second at index 1, and so on. We can also use negative
indexing to access elements from the end of the list, where -1 refers to the last element, -2 to the second
last, and so forth. This makes it easy to access any element in the list directly.
Syntax:
list_name[index]
Example:
fruits = ["Apple", "Banana", "Mango", "Orange"]
In this example, elements are accessed using both positive and negative indexing, allowing flexible
retrieval of values from the list.
List Length
The length of a list refers to the total number of elements present in the list. In Python, we use the
built-in function len() to find the length of a list. This function counts all the items in the list and returns
the number as an integer. Knowing the length of a list is useful when performing operations like looping,
indexing, or checking whether a list is empty or not.
Syntax:
len(list_name)
Example:
print(len(numbers))
Output:
List Membership
List membership in Python refers to checking whether a particular element exists in a list or not. This is
done using membership operators, namely in and not in. The in operator returns True if the specified
element is present in the list, and False otherwise. On the other hand, the not in operator returns True if
the element is not present in the list. This concept is very useful when searching for values, validating
input, or making decisions based on whether an item exists in a list.
Syntax:
element in list_name
In this example, Python checks whether the given element is present in the list and returns a Boolean
value (True or False) accordingly.
List Operations
List operations in Python are the various actions that can be performed on lists to manipulate or work
with their elements. These operations include combining lists, repeating lists, and checking for
membership. They help in organizing and processing data efficiently. Lists are flexible, so we can easily
perform different operations using simple operators.
Syntax:
list1 + list2
Example:
a = [1, 2, 3]
b = [4, 5]
print(a + b)
Output: [1, 2, 3, 4, 5]
2. Repetition
list_name * number
Example:
nums = [1, 2]
print(nums * 3)
Output:
[1, 2, 1, 2, 1, 2]
3. Membership Operation
Check whether an element exists in the list using in and not in.
Syntax:
element in list_name
Example:
List Slices :
List slicing in Python is a technique used to extract a part (sub-list) from an existing list by specifying a
range of indices. Instead of accessing one element at a time, slicing allows you to retrieve multiple
elements in a single operation.
Syntax:
List[start:end:step]
Example:
Output
List Deletion :
List deletion in Python refers to removing elements from a list using different methods depending on the
requirement. The most common ways are del, remove(), and pop().
The del statement is used to delete an element by its index or even remove the entire list.
Example:
numbers = [1, 2, 3, 4]
del numbers[2]
print(numbers) # [1, 2, 4]
The remove() method deletes the first occurrence of a specified value from the list, making it useful
when you know the element but not its position.
Example:
numbers = [1, 2, 3, 2]
[Link](2)
print(numbers) # [1, 3, 2]
The pop() method removes an element based on its index (default is the last element) and also returns
the removed value, which can be useful for further processing.
Example:
a = [1, 2, 3]
b=a
the list [1, 2, 3] is created as an object in memory, and the variable a stores a reference to that object.
When you assign b = a, Python does not create a new list; instead, b is made to refer to the same object
that a is pointing to. This means both a and b are referencing the same list in memory. As a result, any
changes made using one variable (like [Link](4)) will also be reflected when accessing the list
through the other variable (b), because both refer to the same object.
Aliasing
Since variables refer to objects, if we assign one variable to another, both variables refer to the same
Object:
Because the same list has two different names, a and b, we say that it is aliased. Changes made with one
alias affect the other:
Cloning Lists
1. Sometimes, we may want to modify a list but also keep a copy of the original.
In such cases, we need to create a separate copy of the list — not just another reference to the
same list.
2. This process is called cloning, to avoid confusion with the term copy (which can also mean
reference).
3. The simplest way to clone a list in Python is by using the slice operator ([:]).
Python Programming (BBPYPB205), Department of CSE Module 2
28
4. Example:
a = [1, 2, 3]
b = a[:] # Cloning the list
print(b)
Output:
[1, 2, 3]
5. When you take a slice of a list, Python creates a new list object that contains the same elements
as the original.
6. Therefore, a and b are two different lists even though they contain the same data.
7. Relationship after cloning:
a → [1, 2, 3]
b → [1, 2, 3]
(Both lists look the same but are stored separately in memory.)
8. Now, you can change one list without affecting the other.
9. Example:
10. b[0] = 5
11. print(a)
12. print(b)
Output:
[1, 2, 3]
[5, 2, 3]
13. As seen, modifying b does not change a. This confirms that b is a clone a true copy of the list.
List Parameters
1. When a list is passed as an argument to a function, Python passes a reference, not a copy of the
list.
➤ This means the function receives an alias to the original list — both refer to the same object
in memory.
2. So, if the function modifies the list, the changes are visible outside the function as well.
Example:
def double_stuff(stuff_list):
"""Overwrite each element in a_list with double its value."""
for (index, stuff) in enumerate(stuff_list):
stuff_list[index] = 2 * stuff
things = [2, 5, 9]
double_stuff(things)
print(things)
Output:
[4, 10, 18]
Explanation:
List Methods
The dot operator (.) is used to access built-in methods of a list.
These methods perform specific operations on the list itself (like adding, removing,
sorting,etc.).
1. append()
• Usage: [Link](item)
• Function: Adds an item to the end of the list.
• Example:
• mylist = []
• [Link](5)
• [Link](27)
• [Link](3)
• [Link](12)
• print(mylist)
Output: [5, 27, 3, 12]
Python Programming (BBPYPB205), Department of CSE Module 2
32
2. insert()
• Usage: [Link](index, item)
• Function: Inserts an item at the specified index; shifts the remaining items to the right. •
Example:
• [Link](1, 12)
• print(mylist)
Output: [5, 12, 27, 3, 12]
3. count()
• Usage: [Link](item)
• Function: Returns how many times an item appears in the list.
• Example:
• [Link](12)
Output: 2
4. extend()
• Usage: [Link]([list])
• Function: Adds all elements of another list to the end of the current list. •
Example:
• [Link]([5, 9, 5, 11])
• print(mylist)
Output: [5, 12, 27, 3, 12, 5, 9, 5, 11]
5. index()
• Usage: [Link](item)
• Function: Returns the index of the first occurrence of the item.
• Example:
• [Link](9)
Output: 6
6. reverse()
[Link] Function
Example – double_stuff()
def double_stuff(a_list):
"""Return a new list which contains doubles of the elements in a_list."""
new_list = []
for value in a_list:
new_elem = 2 * value
new_list.append(new_elem)
return new_list
Example Output
things = [2, 5, 9]
more_things = double_stuff(things)
print(things) # Original list
print(more_things) # New list returned
Output:
[2, 5, 9]
4. Important Observation
Even if you assign the result back to the same variable, it is still safe because the function returns a new
list, not modifying the old one.
things = [2, 5, 9]
things = double_stuff(things)
print(things)
Output:
[4, 10, 18]
Output:
['The r', 'n in Sp', 'n...']
Note:
The delimiter (“ai”) does not appear in the result.
[Link] range()
• The range() function represents a sequence of numbers, but it doesn’t generate all numbers
immediately.
• It creates a lazy object (a promise to produce numbers when needed).
• This is known as lazy evaluation — it saves memory and speeds up processing.
Example Function:
def f(n):
"""Find the first number between 101 and n that is divisible by 21"""
for i in range(101, n):
if i % 21 == 0:
return i
Testing it:
print(f(110)) # Output: 105
print(f(1000000000)) # Output: 105
Even though range(101, 1000000000) covers a huge range,
Python doesn’t create a list of all those numbers — it generates them one by one only when
needed.
• Without lazy evaluation: Python would try to build a giant list in memory → �� crash! •
With lazy evaluation: Python only generates numbers on demand, so it runs efficiently.
1. Purpose of Loops:
o Loops allow computers to repeat computations quickly and accurately.
o They are a core part of almost every program, especially when dealing with large data or
repetitive tasks.
2. Unnecessary Lists (Tip):
o Don’t create lists unless you actually need to store the data for later use.
o Lists take extra memory, so if data is only needed temporarily (like for summing
numbers), avoid storing it.
3. Example Programs:
o Two functions are shown — both generate 10 million random numbers and return
their sum.
6. Key Takeaway:
o Use lists only if you need to reuse data later.
o If data is used immediately, process it directly inside the loop.
o Always think about memory usage and efficiency when working with loops.
2.3.20 Nested Lists
1. Definition:
o A nested list is a list that contains another list as one of its elements
It allows storing multiple levels of data inside one list
2. Example:
3. nested = ["hello", 2.0, 5, [10, 20]]
o This list has 4 elements:
▪ "hello" → string
▪ 2.0 → float
▪ 5 → integer
▪ [10, 20] → another list (this is the nested list)
4. Accessing the Nested List:
5. print(nested[3])
o Output: [10, 20]
o The element at index 3 is itself a list.
Python Programming (BBPYPB205), Department of CSE Module 2
43
6. Accessing Elements Inside the Nested List (Two Steps):
elem = nested[3] # get the nested list
print(elem[0]) # access its first element
o Output: 10
8. How It Works:
o The bracket operators ([]) are evaluated from left to right. o
So, nested[3][1] means:
▪ Access the 3rd element of nested.
▪ Then access the 1st element inside that nested list.
2.3.21 Matrices
1. Definition:
o A matrix is a rectangular arrangement of numbers in rows and columns.
o In Python, we can represent a matrix using nested lists — each inner list represents
one row of the matrix.
2. Example Matrix:
3. Structure:
o The outer list → represents the matrix as a whole.
o Each inner list → represents one row.
So:
o mx[0] → [1, 2, 3] (1st row)
o mx[1] → [4, 5, 6] (2nd row)
o mx[2] → [7, 8, 9] (3rd row)
4. Accessing a Row:
print(mx[1])
Output:
[4, 5, 6]
mx[1] selects the 2nd row (since indexing starts from 0).
7. Alternate Representation:
Python Programming (BBPYPB205), Department of CSE Module 2
45
o Instead of rows, you could represent a matrix as a list of columns: o
mx_col = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
o Here, each inner list is a column instead of a row.
o (This approach is less common.)
8. Future Note:
o Later, we can represent matrices more efficiently using:
▪ Dictionaries (for sparse matrices)
▪ NumPy arrays (for numerical operations)
Key Takeaway:
• A matrix = list of lists in Python.
• First index = row, second index = column.
• Example:
mx[1][2] → element from 2nd row, 3rd column = 6