0% found this document useful (0 votes)
2 views164 pages

Unit - 2 Pythonn 2

The document provides an overview of data structures in Python, including lists, dictionaries, tuples, and sets. It explains how to create, access, and manipulate these structures, highlighting methods like append, extend, and comprehension techniques. Additionally, it covers the characteristics and methods associated with each data structure, emphasizing their mutability and usage in programming.
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)
2 views164 pages

Unit - 2 Pythonn 2

The document provides an overview of data structures in Python, including lists, dictionaries, tuples, and sets. It explains how to create, access, and manipulate these structures, highlighting methods like append, extend, and comprehension techniques. Additionally, it covers the characteristics and methods associated with each data structure, emphasizing their mutability and usage in programming.
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

Unit -2

1. LISTS IN PYTHON
List are used to store multiple items in a single
variable.
created using "[]".
It allows duplicate values
It is changeable (mutable)
Indexing Supporting
It is ordered
• Creating a List
• # Empty list
• my_list = []

• # List with values


• numbers = [10, 20, 30, 40]

• # Mixed data types


• data = [10, "Python", 3.14, True]
• Accessing List Elements
• numbers = [10, 20, 30, 40]

• print(numbers[0]) # 10
• print(numbers[2]) # 30
• print(numbers[-1]) # 40
• fruits = ["apple", "banana", "mango"]
• fruits[1] = "orange"
• print(fruits)
• ['apple', 'orange', 'mango']
Comprehensions in Python

• What are Comprehensions?


• Comprehensions provide a short and simple way to create new
sequences
(like list, set, dictionary, generator) from existing sequences.
• Instead of writing long for loops, we can write everything in one clean
line
• Types of Comprehensions in Python
• Python supports 4 types of comprehensions:
1. List Comprehension
2. Dictionary Comprehension
3. Set Comprehension
[Link] Comprehension
• 1)List Comprehension
• List comprehension is used to create new lists in a simple and elegant
way.
• Syntax of List Comprehension
• new_list= [expression for item in iterable if condition]

• expression → Operation performed on each item (optional).


• for item in iterable→ Loops through an iterable(like a list, range, etc.).
• if condition → (Optional) Filters items based on a condition.
•if we have a list of integers and want to create a new list
containing the square of each element, we can easily achieve
this using list comprehension.
•a = [2,3,4,5]
•res = [val** 2 for val in a]
•print(res)
• for loop vs. list comprehension

• The main difference is that a for loop requires multiple lines to create
a new list by iterating over items and manually adding each one.
Whereas, list comprehension do the same task in a single line, this
makes the code simpler and easier to read.
• Example:Let’s take an example, where we want to multiply each
number with 2 of given list into a new list
• Using for loop
• a = [1, 2, 3, 4, 5]
• res = []
• for val in a:
• [Link](val * 2)
• print(res)
• Using List Comprehension
• res = [val * 2 for val in a]
• print(res)
•What is val?
•Val is the loop variable that takes each element from the list
a one by one.
Iteration val val * 2 Stored in res

1st 1 1×2 2

2nd 2 2×2 4

3rd 3 3×2 6

4th 4 4×2 8

5th 5 5×2 10
• Conditional statements in list comprehension
• a = [1, 2, 3, 4, 5]
• res = [val for val in a if val% 2 == 0]
• print(res)
• [2, 4]
• Creating a list from a range
• # Creates a list of numbers from 0 to 9
• a = [i for i in range(10)]
• print(a)
• [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

• a = [var for var in range(1,51)]


• print(a)
List Methods

• 1. append()
• append is a list method used to add a single element at the end of the list.
• It modifies the original list and does not return a new list.
• It adds only one element at a time.

• fruits = ["apple", "banana"]


• [Link]("mango")
• print(fruits)
• ['apple', 'banana', 'mango’]
• Return Type:
• The append() method does not return any value, it just modifies the original list
in place.
• Appending Elements of Different Types
• The append() method allows adding elements of different data types
(integers, strings, lists, or objects) to a list. Python lists are
heterogeneous meaning they can hold a mix of data types.
• a = [1, "hello", 3.14]
• [Link](True)
• print(a)
• Appending List to a List
• When appending one list to another, the entire list is added as a single
element, creating a nested list.

• a = [1, 2, 3]
• [Link]([4, 5])
• print(a)
• Op:[1, 2, 3, [4, 5]]
• 2. extend()
• Extend is a list method used to add multiple elements (another list or
iterable) at the end of the existing list.
• It adds each element individually.
• It modifies the original list.
• fruits = ["apple"]
• [Link](["banana", "mango"])
• print(fruits)
• ['apple', 'banana', 'mango']
Using extend() with Different Iterables
# Using a tuple
a = [1, 2, 3]
b = (4, 5)
[Link](b)
print(a)
# Using a set
a = [1, 2, 3]
b = {4, 5}
[Link](b)
print(a)
# Using a string
a = ['a', 'b']
b = "cd"
[Link](b)
print(a)
• 3. insert()
• is used to add an element at a specific index position in the list.
• It shifts existing elements to the right.
• What makes it different from append()is that the list insert() function can add the
value at any position in a list, whereas the append function is limited to adding
values at the end.
• It modifies the original list.

• numbers = [10, 20, 40]


• [Link](2, 30)
• print(numbers)
• [10, 20, 30, 40]
• Insert an Element on first Index
• list = ['Sun', 'rises', 'in', 'the', 'east']
• [Link](0, "The")
• print(list)
• ['The', 'Sun', 'rises', 'in', 'the', 'east']
• Inserting Tuple into a list
• list1 = [ 1, 2, 3, 4, 5, 6 ]
• # tuple of numbers
• num_tuple= (4, 5, 6)
• # inserting a tuple to the list
• [Link](2, num_tuple)
• print(list1)
• [1, 2, (4, 5, 6), 3, 4, 5, 6]
• Inserting a dictionary to a list in Python
• my_list= [{'name': 'Alice', 'age': 30}, {'name': 'Bob', 'age': 25}]
• new_dict= {'name': 'Charlie', 'age': 40}
• my_list.append(new_dict)
• print(my_list)
• [{'name': 'Alice', 'age': 30}, {'name': 'Bob',
'age': 25}, {'name': 'Charlie', 'age': 40}]
• Insert elements of a set to a list in Python
• list1 = [1, 2, 3]
• s= {4,5,6}
• [Link](3,s)
• print(list1)
• [1, 2, 3, {4, 5, 6}]
• [Link]() deletes a value from the list.
• li = [1,3.14,3j,'string',True,False,None]
• [Link](3j)
• print(li)
• [1, 3.14, 'string', True, False, None]

• [Link]() -Reverses the order of elements in the list.


• li = [1,3.14,3j,'string',True,False,None]
• [Link]()
• print(li)
• [None, False, True, 'string', 3j, 3.14, 1]
• pop() → Removes the element at a given index.
• li = [1,3.14,3j,'string']
• [Link](2)
• print(li)
• [1, 3.14, 'string']
• sort() → Sorts the list in ascending order.
• li = [3,4,6,7,23,1,2,8]
• [Link]()
• print(li)
• sort(reverse=True) → Sorts the list in descending order.
• li = [3,4,6,9,7,1,2,8]
• [Link](reverse=True)
• print(li)
• Dictionaries in Python
• A Dictionary is a data structure that stores data in Key–Value pairs.
• Keys must be unique
• Values can be duplicate
• Dictionary is mutable (changeable)
• Written inside {}.
• 1. Creating Dictionary
• student = {
• "name": "Aachal",
• "age": 22,
• "city": "Ahmedabad"
•}
• 2. Accessing dictionary
• print(student)
• {'name': 'Aachal', 'age': 22, 'city': 'Ahmedabad'}
• Methods:-
• get()
• Python Dictionary get() Method returns the value for the given key if present in
the dictionary. If not, then it will return None (if get() is used with only one
argument).
• Dictionary_name.get(key, default_value)
• key: The key name of the item you want to return the value from
• Default_value: (Optional) Value to be returned if the key is not found. The default
value is None.
• student = {"name": "Amit", "age": 21, "course": "Python"}
• # Using get() to access a key
• print([Link]("name")) # Output: Amit
• # Accessing a key that doesn't exist
• print([Link]("grade")) # Output: None (instead of an error
• Example
• student = {"name": "Amit", "age": 21, "course": "Python"}
• # Key doesn't exist, so it returns the default value
• print([Link]("grade", "Not available")) # Output: Not available
• # Key exists, so it returns the actual value
• print([Link]("age", "Not available")) # Output: 21
• items()
Definition: items() method returns all key-value pairs of a dictionary
in the form of tuples. Each pair is returned as (key, value). It is
commonly used in loops.
• Syntax:
dictionary_name.items()
• Example:
student = {"name": "Aachal", "age": 22}
print([Link]())
• dict_items([('name', 'Aachal'), ('age', 22)])
• [Link]()
Definition: values() method returns all the values present in the
dictionary.
• Syntax:
dictionary_name.values()
• Example:
student = {"name": "Aachal", "age": 22, "city": "Ahmedabad"}
print([Link]())
• dict_values(['Aachal', 22, 'Ahmedabad'])
• [Link]() method
• The update() method is used to add new key–value pairs or modify
existing ones.
• student = {"name": "Aachal", "city": "Ahmedabad"}
• [Link]({"age": 21})
• {'name': 'Aachal', 'city': 'Ahmedabad', 'age': 21}
• For loop in dictionary
• Loop through keys default
• student = {"name": "Ram", "age": 20, "marks": 85}
• for key in [Link]():
print(key)
• for key in student:
• print(key)
• Output:
• name age marks
• Example 2: Loop Through Values
• for value in [Link]():
• print(value)
• Output:
• Ram 20 85
• Example 3: Loop Through Both Key and Value
• for key, value in [Link]():
• print(key, ":", value)
• name : Ram
• age : 20
• marks : 85
• Updates in dict
• d = {'a':123 , 'b':45 , 46:12 }
• d[46] = 'Ram'
• print(d)
• {'a': 123, 'b': 45, 46: 'Ram'}
• Tuples
Tuple used to store multiple items in a single variable.
A tuple is an ordered collection of elements. It is similar to a list, but it is
immutable, which means once created, its values cannot be changed.

Characteristics of Tuple:
1. Ordered
2. Immutable(unchangeble)
3. Allows duplicate values
[Link] using "()".
[Link] supporting
•Creating a tuple:
numbers = (10, 20, 30)
•Accessing elements:
print(numbers[0])
• Why tuple is immutable?
Because after creating a tuple, you cannot change, add, or remove
elements.
• Example:
numbers = (10, 20, 30)
numbers[0] = 100 → This gives error
• Change Tuple Values
• Once a tuple is created, you cannot change its values becauseTuples are unchangeable, or immutable .
• But we can convert the tuple into a list, change the list, and convert the list back into a tuple.

• # it is typecasting
• tp = (1,2,3)
• tp1 = list(tp)
• print(tp1)

[Link](859)
• print(tp1)
• tp2 = tuple(tp1)
• print(tp2)
• Output:
• [1, 2, 3] [1, 2, 3, 859] (1, 2, 3, 859)
• Tuple Methods
• Since tuple is immutable, it has only two built-in methods:
1. count()
2. index()
• count()
• count() method returns the number of times a specified value appears in the
tuple.
• Example:
numbers = (10, 20, 10, 30, 10)
print([Link](10))
• Output:
3
• index()
• index() method returns the index position of the first occurrence of a
specified value in the tuple.
• Example:
numbers = (10, 20, 30, 40)
print([Link](30))
• Output:
2
• Tuple Length
• To determine how many items a tuple has, use the len() function.
• thistuple = ("apple", "banana", "cherry")
print(len(thistuple))
• Set:
• Sets are used to store multiple items in a single variable.
A set is an unordered collection of unique elements. It does not allow
duplicate values.
• Characteristics of Sets
1. Unordered (no indexing)
[Link] not Allow
[Link]
[Link] using curly braces {}
• Creating a Set
• nums = {1,2,8,4,3}
• Print(nums)
• Op: {1, 2, 3, 4, 8}
• nums = {10, 1, 50, 3}
• print(nums)
• {1, 50, 3, 10}

• Note:
• The output order may appear sorted sometimes, but it is not
guaranteed
• Duplicates Not Allowed
• Sets cannot have two items with the same value.
• nums = {1, 2, 2, 3, 4}
print(nums)
• Output
{1, 2, 3, 4}
• Accessing Elements
• Since sets are unordered, we cannot access elements using index like
list or tuple.
• nums[0] → Error
• Method of set:
• add()
Definition: add() method is used to add a single element to the set.
• Example:
nums = {1, 2, 3}
[Link](4)
print(nums)
• {1, 2, 3, 4}
• update()
Definition: update() method is used to add multiple elements to a set.
• Example:
a = {1,2,3}
• b= {5,6,4}
• [Link](b)
• print(a)
• {1, 2, 3, 4, 5, 6}
• remove()
Definition: remove() removes a specified element.
If element is not found, it gives an error.
• nums = {1, 2, 3}
[Link](2)
• print(nums)
• discard()
Definition: discard() removes a specified element.
If element is not found, it does NOT give error.
• [Link](5)
• pop()
Definition: pop() removes and returns a random element from the set (because set is
unordered).
• a={1,2,3,4,5,6,7}
• print(a)
• [Link]()
• print(a)
• Clear()
• Definition :This method is used to remove all elements from the set.
• s = {1, 2, 3}
• [Link]()
• print(s)
• Set Operations
• Union
Definition: Combines elements of both sets and removes duplicates.
• a = {1, 2, 3}
b = {3, 4, 5}
print(a | b)
• [Link](b)
{1, 2, 3, 4, 5}
• Intersection
Definition: Returns common elements from both sets.
• print(a & b)
• [Link](b)
• {3}
• Difference
Definition: Returns elements present in first set but not in second set.
• print(a - b)
• [Link](b)
• {1, 2}
• Symmetric Difference
Definition: Returns elements that are in either set but not in both.
• print(a ^ b)
• a.symmetric_difference(b)
• {1, 2, 4, 5}
•Frozenset :
• A frozenset is similar to a set, but it is immutable (cannot be changed)
after creation.
• Characteristics of Frozenset
• Does not allow duplicate values
• Is unordered (no indexing)
• Is immutable (cannot be modified after creation)
• Frozenset is created using the frozenset() constructor, not by special
brackets.
• Example 1: Creating frozenset from tuple
• fset = frozenset((1, 2, 3, 4, 5))
print(fset)
• op:frozenset({1, 2, 3, 4, 5})
• Example 2: Creating frozenset from set
• fset = frozenset({3, 1, 4, 1, 5})
print(fset)
• Op:frozenset({1, 3, 4, 5})
• Example 3: Creating frozenset from list
• fset = frozenset([1, 2, 3, 4, 5])
print(fset)
• Op:frozenset({1, 2, 3, 4, 5})
• Here,We convert a list into a [Link] creation, it cannot be modified.
• If we try:
• [Link](6)
• It will give error because frozenset is immutable.
File Handling

• What is File Handling?


• File handling is used to store data permanently in a file instead of
keeping it only in memory.
When the program stops, variables are deleted.
But file data stays saved in computer.
• open() Function
• Definition:
open() is used to open a file.
• Syntax:
file_object = open("filename", "mode")
• Example:
f = open("[Link]", "r")
• File Modes
• "r" → Read mode (default)
"w" → Write mode (creates new file or overwrites)
"a" → Append mode (adds data at end)
"x" → Create new file (error if exists)
• read() Method
• Definition:
read() is used to read the content of a file.
• Example:
• f = open("[Link]", "r")
content = [Link]()
print(content)
[Link]()
• If file does not exist in read mode then error occurs.
• write() Method
• Definition:
write() is used to write data into a file.
• Example:
• f = open("[Link]", "w")
[Link]("Hello Python")
[Link]()
• Append Mode ( "a" )
• "a" mode is used to add new data at the end of the file without
deleting existing data.
1. If file exists → data is added at the end, Old data is NOT removed.
2. If file does not exist → new file is created.
• Example:
• f = open("[Link]", "a")
[Link](“\nNew line added")
[Link]()
• Create Mode ( "x" )
• Definition:
"x" mode is used to create a new file only.
• Important Points:
1. If file does not exist → file is created.
2. If file already exists → it gives an error.
• Example:
• f = open("[Link]", "x")
[Link]("This is new file")
[Link]()
• Difference Between w, a, x
• "w" - Overwrites file (dangerous if file has important data)
"a" - Adds data without deleting old data
"x" - Creates new file only
• close() Method
• Definition:
close() is used to close the file after operation.
• Why close is important?
1. Saves data properly
2. Frees memory
3. Prevents file corruption
• Example:
• f = open("[Link]", "r")
print([Link]())
[Link]()
• 2)Reading and Writing Text and Binary Files
• There are two types of files in Python:
1. Text Files
2. Binary Files
• 1)Text Files
• Text files store data in readable format (characters).
Example: .txt, .csv, .py
• In text files, data is stored as strings.
• Reading Text File
• f = open("[Link]", "r")
print([Link]())
[Link]()
• Writing Text File
• f = open("[Link]", "w")
[Link]("Hello Python\n")
[Link]("Welcome to File Handling")
[Link]()
• 2)Binary Files
• Binary files store data in binary format (0 and 1).
They are not human readable.
• Example:
Images (.jpg, .png)
Videos
Audio files
PDF
• For binary files, we use "b" with mode.
• "rb" → Read binary
"wb" → Write binary
"ab" → Append binary
• Reading Binary File Example
• f = open("[Link]", "rb")
data = [Link]()
print(data)
[Link]()
• Writing Binary File Example
• f = open("[Link]", "wb")
[Link](data)
[Link]()
• Difference Between Text and Binary
• Text File:
• Stores data as characters
• Human readable
• Uses modes: r, w, a
• Binary File:
• Stores data in binary format
• Not human readable
• Uses modes: rb, wb, ab
Context manager in python
• A context manager in Python is a way to handle files in a clean and
controlled manner. It ensures the file is properly used when needed
and automatically closes it after the work is done. This removes the
need to manually close the file. It is used with the with statement to
make the code safer and easier to write.
• When we use normal file handling:
• If we forget to write [Link](), the file may not close properly.
• This can:
• Waste memory
• Cause data not to save properly
• What is with statement?
• The with statement is used to open a file and automatically close it
after use.
• We do not need to write close() manually.
• Syntax
• with open("filename", "mode") as variable:
file operations
• Example 1: Reading File
• with open("[Link]", "r") as f:
print([Link]())
• Example 2: Writing File
• with open("[Link]", "w") as f:
[Link]("Hello Python")
• File automatically closes after writing.
Working with CSV Files in Python (Using csv
module)
• CSV stands for Comma Separated Values. It is a simple file format
used to store data in tabular form, like rows and columns (similar to
Excel). In a CSV file, each line represents a row, and values are
separated by commas. These files are stored in plain text format.
• Example of csv file content
• name,age,city
• Aachal,22,Ahmedabad
• Rahul,25,Surat
• CSV files are widely used to store data such as student records,
employee details, and to transfer data between Excel and Python.
• In Python, we use a built-in module called csv to work with CSV files.
First, we import the module:
• import csv
• Reading csv file
• To read a CSV file, we use [Link](). It reads the file row by row,
and each row is returned as a list.
• import csv
• with open("[Link]", "r", newline="") as file:
• reader = [Link](file)
• for row in reader:
• print(row)
• Output:
• ['name', 'age']
['Aachal', '22']
• Reading CSV as Dictionary
• We can also read data as dictionaries using [Link]().
• In this case, each row is returned as a dictionary where keys are column
names.
• import csv

• with open("[Link]", "r", newline="") as file:


• reader = [Link](file)
• for row in reader:
• print(row)
• {'name': 'Aachal', 'age': '22'}
• Writing to a CSV File

• To write data into a CSV file, we use [Link](). We can write one row using writerow()
or multiple rows using writerows().
• import csv

• data = [
• ["Student_ID", "Name", "Age"],
• [101, "Amit", 20],
• [102, "Neha", 21]
•]

• with open("[Link]", "w", newline="") as file:


• writer = [Link](file)
• [Link](data)

• print("CSV file created successfully")


import csv
with open("[Link]", "w") as file:
writer = [Link](file)
[Link](["name", "age"])
[Link](["Rahul", 20])
Introduction to Regular Expressions

• Regular Expressions (Regex)


• A Regular Expression (Regex) is a sequence of characters used to search,
match, extract, replace, or split text based on a pattern. In simple words,
Regex helps us find specific patterns inside a string.
• For example, if we have a sentence like:
"My contact number is 9876543210"
• And we want to find a 10-digit number, we can use a pattern like:
\d{10}
• Here:
\d means digit (0–9)
{10} means exactly 10 number
• Features of Regex
• Works on patterns
• Supports flexible matching
• Useful for large text processing
• Language-independent concept
• Why we use Regex
• Regex is used in many real-life situations such as:
• Checking email format
• Validating phone numbers
• Extracting numbers from text
• Replacing words
• Splitting sentences
• Regex Module in Python
• Python has a built-in module named “re”that is used for regular expressions in
Python. We can import this module by using the import statement.
• import re
• Important functions in re module:
• [Link]()
[Link]()
[Link]()
[Link]()
[Link]()
• 1) [Link](pattern, string)
• This function searches the pattern anywhere in the string. It returns the
first match.
• Example:
• import re
• text = "I love Python programming"
result = [Link]("Python", text)
• if result:
print("Found")
• This prints Found because Python exists in the string.
• we can also get the position of the match:
• import re
• s = "A computer science portal for students portal"
match = [Link](r"portal", s)
print("Start Index:", [Link]())
print("End Index:", [Link]())
• Start Index: 19
• End Index: 25
• Why Use r in Regular Expressions?
• Regular expressions use many special characters (like \d, \s, \w), and
Python also uses backslashes (\) for escape sequences (e.g., \n for
newline).
• Using a raw string (r"...") prevents conflicts and ensures that the
regex pattern is interpreted correctly.
• 2) [Link](pattern, string)
• This checks if the pattern matches only at the beginning of the string.
• If it finds a match at the start, it returns matched result ; otherwise, it
returns nothing.
• Example:
• import re
• text = "Hello World"
• if [Link]("Hello", text):
print("Matched at start")
• Matched at start
• Difference between match and search:
• [Link]() checks only at the beginning
[Link]() checks anywhere in the string
• [Link]() vs [Link]()
• [Link]() → Only checks at the beginning of the string.
• [Link]() → Searches anywhere in the string.
• import re
• text = "Python is fun!"
• print([Link]("Python", text)) # Match found
• print([Link]("Python", text)) # Match found
• text2 = "I love Python!"
• print([Link]("Python", text2)) # No match (not at start)
• print([Link]("Python", text2)) # Match found (anywhere)
• 3) [Link](pattern, string)
• This returns all matching patterns in a list. The string is scanned left-to-right, and
matches are returned in the order found.
• Example:
• import re
• text = "My numbers are 123, 456 and 789"
numbers = [Link](r"\d+", text)
print(numbers)
• Output:
['123', '456', '789']
• Here:
\d+ means one or more digits.
• text = "My numbers are 123, 456 and 789"
numbers = [Link](r"\w+", text)
print(numbers)
• ['My', 'numbers', 'are', '123', '456', 'and',
'789']
• text = "My numbers are 123, 456 and 789"
• numbers = [Link](r"\s+", text)
• print(numbers)
• [' ', ' ', ' ', ' ', ' ', ' ']
• [Link](pattern, replacement, string)

• The ‘sub’ in the function stands for SubString


• This replaces the matched pattern with a new string.
• Example:
• import re
• text = "I love apples and apples are tasty"
new_text = [Link]("apples", "oranges", text)
print(new_text)
• Output:
I love oranges and oranges are tasty
• [Link](pattern, string)
• This splits the string wherever the pattern occurs.
• This method is helpful when we need to split a string into multiple parts
based on complex patterns
• Example:
• import re
• text = "apple,banana;orange"
result = [Link](r"[,;]", text)
print(result)
• Output:
['apple', 'banana', 'orange']
• Example
• text = "hello-world_python.program"
• pattern = r"[-_.]" # Split by hyphen, underscore, or period
• result = [Link](pattern, text)
• print(result)
• # Output: ['hello', 'world', 'python', 'program']
• 8. Real-Life Use Cases
• Form validation (email, password)
• Data extraction
• Text editing
• Analysis
Iterator
• An iterator in Python is an object that allows traversal through the all
elements of a collection such as list or tuple, one element at a time.
• It follows the iterator protocol, which requires two methods:
• iter() and next():
• The iter() method returns the iterator object itself, while the next()
method returns the next element from the sequence.
• When there are no more elements , it raises stopiteration exception.
• An iterator is an object used to access elements of a collection one by
one using the iter() and next() methods.
• Iterable vs Iterator
• Iterable = collection of data (list, tuple, string)
Iterator = object that gives values one by one
• mylist = [10, 20, 30] # iterable
• it = iter(mylist) # iterator
• mytuple = ("apple", "banana", "cherry")

• myit = iter(mytuple)

• print(next(myit)) # apple
• print(next(myit)) # banana
• print(next(myit)) # cherry
• print(next(myit)) # StopIteration
• mystr = "abc"

• myit = iter(mystr)
• print(next(myit)) # a
• print(next(myit)) # b
• print(next(myit)) # c
• print(next(myit)) # StopIteration
• list=[1,2,3]
• it=iter(list)
• print(next(it)
• print(next(it)
• print(next(it)
• Create a list of numbers [1,2,3].
• Convert it into an iterator and call next() four times.
Observe and write what happens.
• Generators in python
• A generator is a special type of function that is used to produces
values one at a time using the yield keyword.
• Instead of finishing execution like a normal function, it pauses after
each yield and resumes from the same point when called again.
• This makes generators memory efficient because they do not store all
values in memory or they generate values when needed.
• Example :
• def simple_gen():
• yield 10
• yield 20
• yield 30
• g = simple_gen()
• print(next(g)) # 10
• print(next(g)) # 20
• print(next(g)) # 30
• Example 2: Understanding State
• def count():
yield 1
yield 2
yield 3
• g = count()
• print(next(g)) # 1
print(next(g)) # 2
• The generator remembers its position.
After giving 1, the next call continues from 2.
This is called state preservation
• Generators Saves Memory
• Generators are memory-efficient because they generate values
on-the-fly instead of storing everything in memory.
• For large datasets, generators save memory:
• def large_sequence(n):
for i in range(n):
yield i
# This doesn't create a million numbers in memory
gen = large_sequence(1000000)
print(next(gen))
print(next(gen))
print(next(gen))
•0
•1
•2
• When there are no more values to yield, the generator raises a
StopIteration exception.
def simple_gen():
yield 1
yield 2

gen = simple_gen()
print(next(gen))
print(next(gen))
print(next(gen)) # This will raise StopIteration
• Write a Python program using a generator function that generates
even numbers from 1 to 10.
• def even_numbers():
• for i in range(1, 11):
• if i % 2 == 0:
• yield i

• # Using the generator


• gen = even_numbers()

• for num in gen:


• print(num)
Feature Iterator Generator

An iterator is an object that A generator is a function that


Definition allows traversal of elements produces values one at a time
one by one using yield

Created using iter() or by


Created using a function with
Creation implementing __iter__() and
the yield keyword
__next__()

Code Complexity More complex to implement Simple and concise


Memory efficient (generates
Memory Usage Uses more memory
values on demand)
Decorators in Python

• What is a Decorator?
• A Decorator is a function that modifies or extends the behavior of
another function without changing its original code.
• A decorator is a function that takes another function as
input(arguement) and returns a new function.
• A decorator adds extra functionality to an existing function.
• It allows us to add features like logging, validation, authentication,
etc., without editing the original function.
• 1) Create a Normal Function
• def greet():
• print("Hello")
• greet()
• Output:
Hello
• Create a Decorator Function
• def my_decorator(func):
• def wrapper():
• print("Before function call")
• func()
• print("After function call")
• return wrapper
• #Applying Decorator
• @my_decorator
• def greet():
• print("Hello")

• greet()
• Before function execution
Hello
After function execution
• def my_decorator(func):
• def wrapper():
• print("Before function call")
• func()
• print("After function call")
• return wrapper

• def greet():
• print("Hello")

• # Manually applying decorator


• greet = my_decorator(greet)

• greet()
• def my_decorator(func):
• def wrapper():
• print("Welcome User")
• func()
• print("Thank You")
• return wrapper

• @my_decorator
• def show_profile():
• print("Showing Profile Page")

• show_profile()
• Use Cases of Decorators
1. Authentication (Check user access)
2. Input Validation
3. Timing (Performance Check)
• Q. Write a Python program to create a decorator that prints
"Function is running" before execution and "Function finished" after
execution.
• Apply it to a function that prints numbers from 1 to 5.
• def my_decorator(func):
• def wrapper():
• print("Function is running")
• func()
• print("Function finished")
• return wrapper

• @my_decorator
• def print_numbers():
• for i in range(1, 6):
• print(i)

• print_numbers()
Itertools Module
• The itertools module in Python provides fast and memory-efficient
tools for working with iterators. It is used to perform advanced
iteration tasks like selecting combinations, generating permutations,
and combining multiple iterables. It helps in handling data efficiently
without creating extra storage.
• combinations()
• Definition:
combinations() generates all possible selections of elements from a
sequence where order does not matter. It returns unique pairs or groups
without repeating arrangements.
• Example:
• from itertools import combinations
• data = [1, 2, 3]
• for i in combinations(data, 2):
print(i)
• Output:
(1, 2)
(1, 3)
(2, 3)
• permutations()
• Definition:
permutations() generates all possible arrangements of elements where order
matters. Different orders of the same elements are treated as different results.
• Example:
• from itertools import permutations
• data = [1, 2, 3]
• for i in permutations(data, 2):
print(i)
• Output:
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
(3, 2)
• Explanation:
It arranges elements, so order is important. (1,2) and (2,1) are different.
• chain()
• Definition:
chain() is used to combine multiple iterables into a single sequence. It returns elements
from each iterable one after another without creating a new list.
• Example:
• from itertools import chain
• a = [1, 2]
b = [3, 4]
• for i in chain(a, b):
print(i)
• Output:
1
2
3
4
• Explanation:
• It combines both lists and returns elements one by one.
• combinations is for selection, permutations is for arrangement, and chain is for combining
data.
Exception Handling (try, except, else, finally)

• Definition
Exception handling is a way to handle errors that occur during
program execution so that the program does not stop suddenly and
can continue running normally.
• When an error happens (like dividing by zero or wrong input), Python
creates an exception. Using try and except, we can catch and handle
that exception.
• try and except are exception handeling statement
• When an error occurs, or exception as we call it,
Python will normally stop and generate an error
message.
• These exceptions can be handled using the try
statement.
Syntax:-
try:
# code that may cause error
except ExceptionType:
# code to handle error
else:
# runs if no error occurs
finally:
# runs always
• The try block lets you test a block of code for errors.(Runs the risky
code that might cause an error.)
• The except block lets you handle the error.
• The else block lets you execute code when there is no error.
• The finally block lets you execute code that will always run, whether
an error occurs or not.
• Built-in Exceptions in Python
• Built-in exceptions are pre-defined errors provided by Python. When a
mistake occurs in a program, Python automatically raises these exceptions.
• Common Built-in Exceptions
• ValueError → When an invalid value is used
• TypeError → When the data type is incorrect
• IndexError → When accessing an invalid list index
• KeyError → When a key is not found in a dictionary
• ZeroDivisionError → When dividing by zero
• NameError → When a variable is not defined
try and except
• Definition
try is used to write risky code and except is used to handle the error.
• Example
try:
• result = 10 / 0
• except ZeroDivisionError:
• print("Cannot divide by zero")
• Explanation
The division causes an error.
Instead of stopping the program, the except block handles it and prints a
message.
• The try block will generate an exception, because x is not defined.
• try:
• print(x)
• except :
• print("An exception occurred")
• try:
• age = int(input('enter your age : '))
• print(age)
• except:
• print('value error')
• Example : (multiple exceptions)
• try:
• num = int(input("Enter number: "))
• result = 10 / num
• except ValueError:
• print("Invalid input")
• except ZeroDivisionError:
• print("Cannot divide by zero")

If input is not a number ->ValueError
If input is 0 ->ZeroDivisionError
Python matches the correct except block and executes it.
• try:
• age = int(input('enter your age : '))
• except NameError :
• print('name error')
• except ValueError:
• print('value error')
• except TypeError:
• print('type error')
• try:
• print(X)
• except NameError :
• print('name error')
• except ValueError:
• print('value error')
• except TypeError:
• print('type error')
• # x is not defined
• try:
• add = 45 + '12'
• except NameError :
• print('name error')
• except ValueError:
• print('value error')
• except TypeError:
• print('type error')
• Else
• We can use the else keyword to define a block of code to be
executed if no errors were raised
• The else block runs only when no exception occurs.
• try:
• print("Hello")
• except:
• print("Something went wrong")
• else:
• print("Nothing went wrong")
• Hello
• Nothing went wrong
• try:
• print(g)
• except:
• print("Something went wrong")
• else:
• print("Nothing went wrong")
• Something went wrong

• # when there is no error in try block it will print


else if there is error then print except
• Finally
• The finally block, if specified, will be executed
regardless if the try block raises an error or not.
• try:
• print(z)
• except:
• print("Something went wrong")
• finally:
• print("Nothing went wrong")
• # finally always execued
Raising Exceptions (raise statement)

• The raise statement is used to manually generate an exception in a


program.
It allows the programmer to force an error when a specific condition
is not satisfied.
• In simple terms, instead of waiting for Python to produce an error
automatically, we create the error ourselves to control program
behavior.
• It is mainly used for:
• Input validation
• Stopping execution when something is wrong
• Syntax
• raise ExceptionType("error message")
• Example 1
• age = int(input("Enter age: "))
• if age < 18:
• raise ValueError("Age must be 18 or above")
• ValueError Traceback (most recent call last)
• Cell In[1], line 3
• 1 age = int(input("Enter age: "))
• 2 if age < 18: ---->
• 3 raise ValueError("Age must be 18 or above")
• ValueError: Age must be 18 or above
• Example 2
• num = -5
• if num < 0:
raise Exception("Number cannot be negative")
• Explanation
Here, the program does not wait for Python to give an error.
It explicitly checks if the number is negative and raises an exception.
This ensures invalid data is not processed further.
• Example 3 (inside function)
• def withdraw(amount):
• if amount > 5000:
• raise Exception("Limit exceeded")
• return "Transaction successful"
• print(withdraw(6000))
• Explanation
The function defines a rule that withdrawal should not exceed 5000.
If the condition fails, the function raises an exception.
This is commonly used in real-world applications like banking
systems.
• Example 4 (raise with try-except)
• try:
• num = int(input("Enter number: "))
• if num == 0:
• raise ValueError("Zero is not allowed")
• except ValueError as e:
• print(e)
• Zero is not allowed
• Explanation
The program raises an exception manually when input is zero.
The try-except block catches the error and prints the message.
This shows how raise and exception handling work together.
Custom Exceptions

• Definition
Custom exceptions are user-defined exceptions created by the
programmer to represent specific errors in a program.
• Python already provides many built-in exceptions (like ValueError,
TypeError), but sometimes those are not enough to describe a
particular situation. In such cases, we create our own exception class
to make the error more meaningful and specific.
• Syntax
• class MyError(Exception):
pass
• Explanation
A new class is created
• It inherits from the built-in Exception class
• Pass means no additional code is written (empty class)
• This class can now be used like a normal exception
• Example 1 (basic custom exception)
• class AgeError(Exception):
pass
• age = int(input("Enter age: "))
• if age < 18:
raise AgeError("User is underage")
• We created our own error called AgeError.
If age is less than 18, we raise this error.
• Example 2 (custom exception with handling)
• class BalanceError(Exception):
pass
• try:
balance = 1000
• withdraw = 2000
• if withdraw > balance:
• raise BalanceError("Insufficient balance")
• except BalanceError as e:
print(e)
• Explanation
If withdrawal is more than balance, we raise BalanceError.
The except block catches it and prints the message.
So the program does not crash.
• Example 3 (real-world login case)
• class LoginError(Exception):
pass
• try:
username = "admin"
password = "123"
• if password != "admin123":
• raise LoginError("Invalid credentials")
• except LoginError as e:
print(e)
• Explanation
A custom exception LoginError is used for login failure.
If the password does not match, the exception is raised.
The except block handles it and shows the message.
This makes the code easy to understand and domain-specific.
Debugging Techniques and Tools

• 1. assert statement
• Definition:
Assert is used to check whether a condition is true or not during
program execution.
If the condition is true, the program continues normally.
If the condition is false, Python stops the program and gives an error.
• Simple meaning
It is used to find mistakes in logic while testing the program.
• Syntax
• assert condition "error message"
• Explanation
• If condition is True → program runs normally
• If condition is False → AssertionError comes
• Example 1
• age = 16
• assert age >= 18, "User is underage"
• print("You can vote")
• AssertionError Traceback (most recent call last)
Cell In[1], line 2 1 age = 16 ----> 2 assert age >=
18, "User is underage" 3 print("You can vote")
AssertionError: User is underage
• Example :- 2
• age = 20
• assert age >= 18, "User is underage"
• print("You can vote")
• Output: You can vote

You might also like