Unit - 2 Pythonn 2
Unit - 2 Pythonn 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 = []
• 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
• 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]
• 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.
• 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.
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
• 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]
•]
• 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
• 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")
• 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
• 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