Background of Python Programming
Python was created in the late 1980s by
Guido van Rossum, a Dutch programmer at
the Centrum Wiskunde & Informatica
(CWI) in the Netherlands as a successor to
the ABC language. [1991 - Python 0.9.0
released]
Guido van Rossum served as the lead
developer of Python until July 12, 2018.
In January 2019, the active core developers
of Python elected a five-member council to
lead the project.
What is Python programming language?
Python is a high-level, general-purpose, interpreted programming language.
Emphasizes code readability and simple syntax, often described as "executable
pseudocode."
Why is it Called Python?
• Not named after the snake !
• Named after “Monty Python’s Flying Circus”, a British comedy show that
Guido van Rossum enjoyed.
Version History of Python
Python 1.0 – Released in 1994
Python 2.0 – Released in 2000
Python 3.0 – Released in 2008 (Not backward compatible with Python 2)
Latest Version (as October 7, 2024) – Python 3.13.3
Note: The current latest version can be checked at [Link]
Features of Python
Simple and straightforward syntax
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Case sensitive language
Multi-paradigm (supports OOP, procedural, functional styles)
Dynamically typed (no need to declare variable types)
Emphasizes readability (e.g., 3 + 4 is readable)
Automatic memory management (Garbage collection)
Large standard library support
Huge global community
Platform-independent (Runs on Windows, macOS, Linux)
Amazing Facts About Python
Ranked #1 in TIOBE Index (a popular programming language ranking)
Python is the only language to have the highest rise in ratings in:
o 2007
o 2010
o 2018
o 2020
Python can reduce app development time by 1/6
Used by large organizations:
o Google, NASA, Facebook, Amazon
o Instagram, Spotify, Microsoft, CERN
o YouTube, Netflix, Dropbox
Popular framework: Django is heavily used for web development
Variety of Uses
Python can be used for:
Web Development
• Backend using frameworks like:
o Django
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
o Flask
• Frontend (via integration):
o Pyjs, IronPython for Ajax-based apps
Networking & Communication
• Twisted – a powerful framework for network communication
• Used in Dropbox backend
Scientific Computing
• Libraries:
o NumPy (Numerical)
o SciPy (Scientific)
o Matplotlib (Plotting and Visualization)
For mobile app development: Kivy and BeeWare are the most popular frameworks.
• Kivy:
Focus: Multi-touch applications, cross-platform development, and a custom UI.
• BeeWare:
Focus: Native mobile and desktop app development with a single codebase.
Types of Applications You Can Build
Console Applications
Web Applications
Desktop Applications
Mobile Applications
AI-Based Applications
Data Analytics & Visualization
Task Automation (e.g., scripts, bots)
IoT Applications
Machine Learning & Deep Learning
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Installing Python
1. Go to: [Link]/downloads
2. Select your Operating System (Windows/macOS/Linux)
3. Download the Installer
4. Run the Installer and follow setup instructions
5. Python comes with IDLE:
o Integrated Development and Learning Environment
o A simple text editor + interpreter for Python code
Your First Python Program
Steps:
1. Open IDLE. Type import this in the Python shell to see core principles
2. Go to File > New File
3. Save the file as [Link]
4. Write the following code:
1. print("Enter two numbers:")
2. a = int(input())
3. b = int(input())
4. c = a + b
5. print("Sum is", c)
5. Run the file using F5 or Run > Run Module
Additional Notes:
• Python uses indentation (spacing) instead of {} or begin/end to define blocks.
• No semicolon ; needed (optional).
• Use input() to take user input and int() to convert it to an integer.
• Python files end with .py.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit – 1: Inception
🔗 For detailed explanations and examples, visit the GitHub repository!
① Comments
• Comments are used to explain the code.
• They are ignored by Python compiler during execution of code.
• Single-line comment: starts with # This is a comment
• Multi-line comments: use triple quotes (usually for documentation)
"""
This is a
multi-line comment
"""
② Variables
• Variables are containers for storing data values. They hold data during execution of program.
• You don’t need to declare their type in Python. Python detects the type automatically.
a = 10 # Integer
b = 5.5 # Float
name = "Ram" # String
• Rules for variable names:
o Must start with a letter or underscore
o Can contain letters, numbers, and underscores
o Case-sensitive (Name and name are different)
o Cannot start with a number
o Cannot be a Python keyword like if, class, for, etc.
③ Dynamic Typing
• Python is dynamically typed, meaning:
You can change the type of value a variable holds at runtime.
x=5 x =5
x=7 x=3.14
Here we have changed the value of variable Here we have changed the value of variable
x, but type remains the same. # int x, and have also changed the type as well
from # int - # float
So, in Dynamic Typing not only the value of a variable may get changed during program
execution but the type as well.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
x= 5 # int
x=3.14 #float
x = "hello" # str
x = True # bool
x = 3 + 4j # complex
④ type() Function
• The type() function shows the data type of a variable or value. It is a predefined function
which returns the data type of a specified variable.
x = 10
print(type(x)) # <class 'int'>
x = "Hello"
print(type(x)) # <class 'str'>
x = 3.14
print(type(x)) # <class 'float'>
x = 3 + 4j
print(type(x)) # <class 'complex'>
• Common data types:
o int: whole numbers
o float: decimal numbers
o str: text
o bool: True or False
o complex: numbers with imaginary parts
o double is not there in Python
Memory is Allocation to Variables
Stack/Namespace Private Heap Space
x Instance Object/Obj.
4
Reference 214876 id (address reference)
Variable
y
4.5
478965
x = 4 # Python creates an integer object 4 & binds the name x
y = 4.5 # to the reference of that object.
#Reference Variable is created
©2026 in Namespace
Rishabh & it refers to Instance
Singh [@itsindrajput] Obj,to
| Feel free Class Obj or Function Obj.
share
Everything in Python is an Object
When you create a variable, Python creates an object in memory to store the value.
• The variable name acts as a reference (or pointer) to that object.
Memory is Allocation to Variables
Stack/Namespace Private Heap Space
x Object
4
214876 id (address reference)
y
4.5 Now this will become
478965
Garbage Block
8.1
587469
x=4 Dynamic Typing and Rebinding: We can reassign a variable to a
y = 4.5 new value, and it will point to a different object. x = 8.1
x = 8.1
• First, x points to an integer object.
• Then, x points to a new float object 8.1
Stack Memory Heap Memory
Stores variable names and references (not Stores actual objects/data (like int, str, list,
actual values). etc.).
Local variables and function calls live here Python’s memory manager handles allocation
temporarily. and deallocation in the heap.
Reference Counting and Garbage Collection
• Python tracks how many references point to each object using a reference counter.
• When an object’s reference count drops to zero, Python’s Garbage Collector frees the
memory.
Concept Explanation
Variable A name pointing to an object in memory
Object Something that can store data and has method to handle data.
Stored in heap memory.
Variable Name Stored in stack memory
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Memory Management Automatic via reference counting and garbage collector
id() Returns the memory address of an object
⑤ id() Function Shows Memory Address
• The id() function returns the memory address (unique ID) of an object.
a=5
b=5
• print(id(a)) # prints the memory address of the object 5. Same ID for same immutable object
• print(id(b)) # Same as a if value is same
• In Python:
o Everything is an object. And there are 3 types of object:
1. Instance Obj. 2. Class Obj. 3. Function Obj.
o Variables are names (references) pointing to objects stored in memory
o id() shows the location (address) of the object in memory
⑥ print() Function
• Used to display output on the screen.
• print("Hello, World!")
• You can print multiple values:
• a = 5, b =6, c = 7 ->
• a, b, c = 5, 6, 7 ->
• print(a, b, c) #567
• print(a, b, c, sep="-") # 5-6-7
print("Hello", end=" ") # Prints on same line
print("World") # Output: Hello World
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Foundation of Python
① import Statement in Python
The import statement is used to bring code from one Python module into another. This is a
cornerstone of code organization, reusability, and modularity in Python.
What is a Module?
• A module is a .py file containing Python code (variables, functions, classes).
• Types:
o Built-in (e.g., sys, math, os)
o User-defined (custom .py files)
Why Use import?
• Code Reusability – Use functions/variables across multiple programs.
• Better Organization – Modular approach for large projects.
• Namespace Management – Avoid naming conflicts.
How Python Finds Modules
Python searches in:
1. Current directory
2. PYTHONPATH (env variable)
3. Standard library path
o Access search paths using [Link]
Ways to Import Modules
1. Import entire module
import my
print(my.x)
2. Import with alias
import my as m
print([Link]("Bob"))
3. Import specific items
from my import x, greet
print(x, greet("Charlie"))
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
4. Import specific items with alias
from my import x as my_x
5. Import all items (⚠ not recommended)
from my import *
Custom Module Paths using [Link]
import sys
[Link](r'C:/.../oops_basics')
import oops
print(oops.student_1)
② Keywords
Keywords in Python are reserved words that have special meanings and purposes within the
language syntax. They cannot be used as identifiers (names for variables, functions, classes, etc.).
How to List All Keywords:
import keyword
print("There are total", len([Link]), "Keywords in Python")
print([Link])
Example Output (Python 3.8):
• Total: 35
• Examples: if, else, elif, for, while, import, def, class, try, except, lambda, yield, with, is, not,
and, or, etc.
③ Operators
Operators are special symbols or keywords in Python that perform operations on values (operands).
1. Arithmetic Operators
Used to perform mathematical operations:
Operator Meaning Example
+ Addition 3+2→5
- Subtraction 3-2→1
* Multiplication 3*2→6
/ Division 3 / 2 → 1.5
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
// Floor Division 3 // 2 → 1
% Modulus 3%2→1
** Exponentiation 2 ** 3 → 8
2. Relational (Comparison) Operators
Used to compare two values. They return a Boolean value (True or False).
Operator Meaning Example
> Greater than 3 > 2 → True
< Less than 3 < 2 → False
>= Greater or equal 3 >= 2
<= Less or equal 3 <= 2
== Equal 3 == 2
!= Not Equal 3 != 2
3. Logical Operators
Used to combine conditional statements:
Operator Meaning Example
and Logical AND True and False → False
or Logical OR True or False → True
not Logical NOT not True → False
4. Bitwise Operators
Perform operations on integers at the binary (bit) level.
Operator Meaning A B A&B A | B (OR) A^B
(AND) (XOR)
& AND
0 0 0 0 0
| OR 0 1 0 1 1
^ XOR 1 0 0 1 1
~ NOT (invert) 1 1 1 1 0
<< Left Shift
>> Right Shift
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
5. Assignment Operators
Used to assign values to variables:
Operator Meaning
= Assign
+= Add and assign
-= Subtract and assign
*= Multiply and assign
/= Divide and assign
//= Floor divide and assign
%= Modulus and assign
**= Exponent and assign
&=, ` =, ^=, >>=, <<=` – Bitwise compound assignments
6. Identity Operators
Used to compare memory locations:
Operator Meaning
is True if same object
is not True if different
7. Membership Operators
Used to test for membership:
Operator Meaning
in True if found
not in True if not found
Note: ++ and -- are not valid operators in Python.
④ input() Function
Purpose: Used to take user input from the keyboard.
Syntax: input("Enter something: ")
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Characteristics:
• Takes only one argument (the prompt string).
• Always returns a string.
• Can be converted to other types using conversion functions like int(), float(), etc.
Example:
name = input("Enter your name: ")
age = int(input("Enter your age: "))
print("Hello", name, "You are", age, "years old.")
🔗 For detailed explanations and examples, visit the GitHub repository!
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit-2
🔗 For detailed explanations and examples, visit the GitHub repository!
Type Casting:
Type casting in Python involves converting a variable's data type into
another. This can be done implicitly by Python or explicitly by the programmer
using built-in functions.
Example:
print(7 + "7") # TypeError: unsupported operand type(s) for +: 'int' and 'str'
print(str(7) + "7") #77
print(7 + int("7")) #14
Implicit Type Casting
Python automatically converts one data type to another in certain situations,
usually to prevent data loss. For example, when adding an integer to a float,
Python will implicitly convert the integer to a float before performing the
addition.
Example:
num_int, num_float = 123, 1.23
num_new = num_int + num_float
print("Value of num_new:",num_new) # 124.23
print("Data type of num_new:", type(num_new)) # <class 'float'>
Explicit Type Casting
Programmers can manually convert data types using built-in functions
like int(), float(), str(), bool(), etc. This is useful when you need a variable to be
of a specific type for an operation.
Example:
string_num = "15"
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
number = int(string_num)
print(number + 10) #25
Common Type Casting Functions:
int(): Converts to an integer,
float(): Converts to a float,
str(): Converts to a string, and
bool(): Converts to a boolean.
Important Points
• Loss of data: float → int truncates the decimal.
• Conversion errors: Trying to convert an invalid string raises a ValueError.
Example:
x = 4.5
y = int(x)
print(y) #4
s1 = "abc"
s2 = int(s1)
print(s2) # ValueError: invalid literal for int() with base 10: 'abc'
f1 = "3.142"
f2 = int(f1)
print(f2) # ValueError
f3 = "3.142"
f4 = int(float(f3))
print(f4) #3
Some Other Conversion Methods:
bin() – Converts an integer to binary (base 2)
oct() – Converts an integer to octal (base 8)
hex() – Converts an integer to hexadecimal (base 16)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Example:
print(bin(10)) # Output: '0b1010', 0b prefix means binary
print(oct(10)) # Output: '0o12', 0o prefix means octal
print(hex(255)) # Output: '0xff'
Summary Table:
Function Description Example Result
bin(x) Decimal → Binary bin(10) '0b1010'
oct(x) Decimal → Octal oct(10) '0o12'
hex(x) Decimal → Hexadecimal hex(255) '0xff'
int(x, base) Any base → Decimal int("0xff", 16) 255
Function Input Output Purpose
ord() 'A' 65 Character → Unicode
integer
chr() 65 'A' Unicode integer →
Character
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Decision Making (Conditional Statements)
1. Indentation and Block Creation in Python
• Indentation is the whitespace (usually 4 spaces or a tab) used at the
beginning of a line to define a block of code.
• Unlike many other languages (like C, C++, Java), Python uses indentation
instead of braces {} to define code blocks.
• A colon : is used at the end of the control statement (if, else, elif) to
denote the start of a block.
Syntax:
if condition:
statement1
statement2 # Both are part of the 'if' block
statement_outside_if # This is outside the 'if' block
2. Simple if Statement
• The if statement evaluates a condition. If it is True, the indented block
below it runs.
• If it's False, nothing happens.
Syntax:
if condition:
# Block of code
Example:
number = int(input("Enter a number: "))
if number > 0:
print("Positive")
if number <= 0:
print("Non Positive")
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
3. if...else Statement
• If the if condition is True, it runs the if block.
• Otherwise, it runs the else block.
Syntax:
if condition:
# True block
else:
# False block
Example:
number = int(input("Enter a number: "))
if number > 0:
print("Positive Number")
else:
print("Non Positive")
4. if...elif...else (Ladder)
• Used when you have multiple conditions to check.
• The program checks each condition in order from top to bottom.
• It executes the first block where the condition is True, then skips the
rest.
Syntax:
if condition1:
# block1
elif condition2:
# block2
elif condition3:
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
# block3
else:
# fallback block
Example: Grading System
marks = int(input("Enter your marks: "))
if 90 < marks <= 100:
print("Grade -> A")
elif 80 < marks <= 90:
print("Grade -> B")
elif 70 < marks <= 80:
print("Grade -> C")
elif 60 < marks <= 70:
print("Grade -> D")
elif 50 <= marks <= 60:
print("Grade -> E")
else:
print("Grade -> F")
5. Single-Line if...else (Ternary Expression)
• Python allows a shorthand way of writing an if...else statement.
• Useful for simple decisions in one line.
Syntax:
result = "value_if_true" if condition else "value_if_false"
Example: Even or Odd
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
# Method 1
number = int(input("Enter a number: "))
result = "Even" if number % 2 == 0 else "Odd"
print(result)
# Method 2
number = int(input("Enter a number: "))
print("Even") if number % 2 == 0 else print("Odd")
# Method 3 (one-liner)
print("Even" if int(input("Enter a number: ")) % 2 == 0 else "Odd")
⚠️ Important Notes
❌ Python does not support the conditional operator ? : like C/C++.
✅ The switch statement, common in other programming languages, was not a
built-in feature in Python versions prior to 3.10. However, Python 3.10
introduced structural pattern matching, which includes
the match and case keywords, effectively providing the functionality of
a switch statement.
6. Switch Case
# This code runs only in python 3.10 or above versions
def number_to_string(argument):
match argument:
case 0:
return "zero"
case 1:
return "one"
case 2:
return "two"
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
case default: # OR case _:
return "something"
head = number_to_string(2)
print(head)
🧮 Summary Table
Statement Type Description Syntax Example
if Executes if condition is if a > b:
True
if...else Two-way decision if a > b: ... else: ...
if...elif...else Multi-way decision if a > b: ... elif a == b: ... else: ...
Ternary (One-line) One-line if-else "Even" if n % 2 == 0 else "Odd"
Switch Case Available from Python match argument:
Alternative 3.10 version. case 1:
case _:
🧪Practice Question:
1 Write a Python script to calculate the area of a rectangle.
Hint: Use the formula Area = length × breadth. Take length and breadth as input from the user.
length = float(input("Enter The Length of the Rectangle: "))
breadth = float(input("Enter The Breadth of the Rectangle: "))
area = length * breadth
print("Area of Rectangle", area)
print("Area of Rectangle = {:.2f}".format(area))
print(f"Area of Rectangle = {area:.2f}")
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
2 Write a Python script to calculate simple interest.
Hint: Use the formula SI = (Principal × Rate × Time) / 100. Take all values as input from the user.
principal = float(input("Enter the Principal: "))
rate = float(input("Enter the Rate: "))
time = float(input("Enter the Time: "))
si = principal*rate*time/100
print(f"Simple Intrest = {si:.2f}")
3 Write a Python script to remove the last digit from a given number.
Hint: Use integer division //10 to remove the last digit.
number = int(input("Enter a number: "))
last_digit = number % 10
rem = number // 10
print("Removed last digit = ", last_digit)
print("Remaining number = ", rem)
4 Write a Python script to swap the values of two variables.
Hint: Use a third variable or Python’s swapping feature.
a, b = int(input("Enter 1st Number: ")), int(input("Enter 2nd Number: "))
temp = a
a=b
b = temp
print(f"After Swap \n1st Number: {a} \n2nd Number: {b}")
5 Write a Python script to check whether a given number is divisible by 5 or not.
Hint: Use the modulus operator % to check if the remainder is 0.
print("Divisible By 5") if (int(input("Enter a number: "))%5==0) else print("Not Divisible By 5")
6 Write a Python script to print two given words in dictionary (alphabetical) order.
Hint: Use if...else to compare the words and print accordingly.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
str1 = input("Enter 1st Word: ")
str2 = input("Enter 2nd Word: ")
if ([Link]() < [Link]()):
print(f"Words in dictionary order: {str1}, {str2}")
else:
print(f"Words in dictionary order: {str2}, {str1}")
7 Write a Python script to check whether a given number is a three-digit
number or not.
Hint: A number is three-digit if it is between 100 and 999 (both inclusive).
n = int(input("Enter a number to check whether it is a three-digit number or not: "))
if 100 <= abs(n) <= 999:
print("It is a 3-digit number")
else:
print("It is not a 3-digit number")
8 Write a Python script to check whether a given year is a leap year or not.
Hint: A year is a leap year if it's divisible by 4 but not by 100, unless it's also divisible by 400.
9️ Write a Python script to check whether a given number is positive,
negative, or zero.
Hint: Use if, elif, and else to check the sign of the number.
n = int(input("Enter a number to check whether it is positive, negative, or zero: "))
if (n>0):
print("Positive")
elif (n<0):
print("Negative")
else:
print("Zero")
10 Write a Python script to take a complex number as input and display
whether the real part or the imaginary part is greater.
Hint: Use complex() to accept input and compare real and imag attributes.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit-3: Loops in Python
🔗 For detailed explanations and examples, visit the GitHub repository!
Loops in Python:
Loops are essential control flow structures in Python, allowing for repeated
execution of code blocks based on conditions. Python supports two primary
types of loops: for loops and while loops. Although Python does not have a
native do-while loop, its functionality can be imitated using a while loop with
a break statement.
Types of Loops in Python
1. while Loop
• A while loop repeatedly executes a block of code as long as a specified
condition is True. Once the condition becomes False, the loop stops
executing.
Syntax:
while condition:
statement1
statement2
# Code block (executed repeatedly while condition is True)
# Code after the loop
Example 1: Print "Python3" five times
n=1
while n <= 5:
print("Python3")
n += 1
Example 2: Print first N natural numbers
n = int(input("Enter a number: "))
i=1
while i <= n:
print(i, end=" ")
i += 1
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Example 3: Sum of first N natural numbers
number = int(input("Enter a number: "))
i=1
total = 0
while i <= number:
total += i
i += 1
print("Sum =", total)
2. for Loop
• A for loop iterates over elements in a sequence (such as a list, tuple, or
range), executing a block of code for each element. The number of
iterations matches the number of elements in the sequence.
Syntax:
for variable in iterable-sequence:
statement1
statement2
# Code block (executes for each element in iterable)
Example: Unicode of characters in a string
string = "Rajput"
for char in string:
print(char, "->", ord(char))
Example: Print numbers from 1 to 5 using range
for i in range(1, 6):
print(i)
Simulating a do-while Loop
Python does not have a built-in do-while loop. However, its behavior can be
mimicked using a while True: loop and a break.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Example:
while True:
number = int(input("Enter a number between 1 and 10: "))
if 1 <= number <= 10:
print("Valid number entered:", number)
break
else:
print("Number is out of range. Please try again.")
Jump Statements in Python
Jump statements alter the normal flow of execution in a program. Python
includes three main jump statements:
1. break
• Used to exit the loop prematurely when a condition is met.
2. continue
• Skips the rest of the code inside the loop for the current iteration and
goes to the next iteration.
3. return
• Exits a function and optionally returns a value.
Example: Check if a number is prime using break
n = int(input("Enter a number: "))
i=2
while i < n:
if n % i == 0:
break
i += 1
if i == n:
print(n, "is a Prime Number")
else:
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
print(n, "is Not a Prime Number")
Example: Using else with while loop
n = int(input("Enter a number: "))
i=2
while i < n:
if n % i == 0:
print(n, "is Not a Prime Number")
break
i += 1
else:
print(n, "is a Prime Number")
The range() Function
Often used in for loops to generate a sequence of numbers.
Syntax:
range(start, stop, step)
• start: starting value (default = 0)
• stop: up to but not including this value
• step: increment (default = 1)
Example:
for i in range(0, 10, 2):
print(i)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Key Differences Between for and while
Feature for Loop while Loop
Iteration Iterates over a sequence or Repeats while condition is
Basis range True
Use Case Known number of iterations Unknown number of
iterations
Readability More concise and readable for More flexible with complex
sequences conditions
Summary
• Loops help repeat tasks efficiently.
• while is used when the end condition is not known beforehand.
• for is best for iterating through a sequence.
• Python lacks a built-in do-while loop, but similar behavior can be
achieved.
• break, continue, and return control loop execution flow.
• The range() function is a handy tool in for loops.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit - 4.1: Python range() Function
🔗 For detailed explanations and examples, visit the GitHub repository!
1. What are Iterables in Python?
An iterable is any Python object capable of returning its members one at a
time. These are objects you can loop over using a for loop.
Iterable word comes from ‘iteration’ which means repetition of the process.
Examples of Iterables:
• range
• list
• tuple
• string
• dictionary
• set
# All these are iterable:
for i in [1, 2, 3]:
print(i)
for ch in "hello":
print(ch)
2. range() in Python
What is range()?
• range() is a built-in class used to generate a sequence of numbers.
• It creates an immutable sequence of integers (you cannot change
elements).
• Works on the principle of Arithmetic Progression (AP).
• Commonly used in loops (especially for loops).
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
3. Syntax of range()
There are three forms of using range():
range(start, stop, step) # step can be +ve or -ve
range(stop) # starts from 0, step = +1
range(start, stop) # step = +1
• start: The number from which the sequence starts (inclusive).
• stop: The number at which the sequence stops (exclusive).
• step: The difference between each number (default is 1).
Examples:
r = range(1, 8, 2) Output: 1
for i in r: 3
print(i) 5
7
print(list(range(5))) # Output: [0, 1, 2, 3, 4]
print(list(range(1, 6))) # Output: [1, 2, 3, 4, 5]
print(list(range(1, 10, 2))) # Output: [1, 3, 5, 7, 9]
print(list(range(10, 3, -2))) # Output: [10, 8, 6, 4]
4. Characteristics of range
Property Explanation
Immutable Cannot change elements after creation
Iterable Can be looped using for loop
Returns values in AP Sequence with common difference
Only stores integers No floats or strings allowed
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
5. Accessing Range Elements
You can access elements of a range object using indexing:
Examples:
r = range(2, 10, 3)
print(r[0]) # Output: 2
print(r[1]) # Output: 5
print(r[2]) # Output: 8
Using a loop:
r = range(2, 10, 3) # 2, 5, 8
for e in r:
print(e, e**2)
# Output:
#24
# 5 25
# 8 64
6. Creating Range Objects in Different Ways
➤ Method 1: Only stop value
r = range(5) # same as range(0, 5, 1)
print(list(r)) # [0, 1, 2, 3, 4]
➤ Method 2: start and stop
r = range(3, 8) # [3, 4, 5, 6, 7]
➤ Method 3: start, stop, and step
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
r = range(1, 10, 2) # [1, 3, 5, 7, 9]
r = range(10, 3, -2) # [10, 8, 6, 4]
7. range() is a Class
You can check it using type():
r = range(5)
print(type(r)) # Output: <class 'range'>
It behaves like a generator, meaning it does not store all values in memory
(efficient for large ranges).
8. Practical Examples Using range()
Sum of first 10 numbers:
print(sum(range(1, 11))) # Output: 55
Print even numbers between 1 to 20:
for i in range(2, 21, 2):
print(i)
Print numbers in reverse:
for i in range(5, 0, -1):
print(i)
9. Convert range to list or tuple
print(list(range(5))) # [0, 1, 2, 3, 4]
print(tuple(range(3, 8))) # (3, 4, 5, 6, 7)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
10. Edge Cases
Negative step:
print(list(range(10, 1, -2))) # [10, 8, 6, 4, 2]
Empty result:
print(list(range(5, 1))) # [ ] –> because default step is +1
Summary (Key Takeaways)
• range() generates a sequence of numbers.
• It is a memory-efficient, immutable object.
• Frequently used in for loops.
• Syntax: range(start, stop, step) (start is inclusive, stop is exclusive).
• Use list() or tuple() to view contents.
• Works only with integers.
# Example: Table of 7
for i in range(1, 11):
print(f"7 x {i} = {7*i}")
Practice Exercises
1. Print squares of numbers from 1 to 5.
2. Print all odd numbers from 1 to 20.
3. Print numbers in reverse from 10 to 1.
4. Print the table of 7 using range.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit - 4.2: List In Python
🔗 For detailed explanations and examples, visit the GitHub repository!
① What is a List?
• A list is a built-in Python class used to store multiple values in a single
variable.
• It is:
o Iterable – can be traversed element by element.
o Mutable – elements can be changed after creation.
o Growable – you can dynamically add/remove items.
o Heterogeneous – can store items of different data types (int, float, str,
bool, etc.).
o Indexed – elements can be accessed by index (positive or negative).
Examples:
l1 = [10, 40, 20, 30]
type(l1) # <class 'list'>
l2 = [40, True, 4.5, 3+4j, 10, 'mysirg']
type(l2) # <class 'list'>
l3 = [] # empty list
type(l3) # <class 'list'>
② How to Create a List Object?
Use square brackets [] or the list() constructor.
numbers = [1, 2, 3]
empty = list()
mixed = list([1, 'a', 3.5])
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Using Constructor:
list_from_str = list("hello") # ['h', 'e', 'l', 'l', 'o']
list_from_range = list(range(5)) # [0, 1, 2, 3, 4]
③ How to Access List Elements?
Access using index:
l1 = [50, 20, 80, 10, 60, 40]
print(l1[0]) # 50
print(l1[1], l1[2]) # 20 80
print(l1[1:3]) # [20,80]
print(l1[::-1]) # [40, 60, 10, 80, 20, 50]
Index starts at 0. Invalid indexes raise IndexError.
④ Concept of Negative Indexing
• Python supports negative indexing to access items from the end.
l1 = [50, 20, 80, 10, 60, 40]
print(l1[-1]) # 40 (last element)
print(l1[-2]) # 60 (second last)
⑤ Accessing List Elements via for Loop
l1 = [50, 20, 80, 10, 60, 40]
for x in l1:
print(x, end=' ')
Alternatively using a while loop:
i=0
while i < len(l1):
print(l1[i], end=' ')
i += 1
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
⑥ How to Delete an Element from a List?
Use del, remove(), or pop():
l1 = [50, 20, 80, 10, 60, 40]
del l1[2] # Deletes element at index 2
[Link](10) # Removes first occurrence of value 10
[Link](3) # Removes and returns element at index 3
[Link]() # Remove last
[Link]() # Remove all
⑦ How to Edit an Element of a List?
Directly assign a new value:
l1[2] = 45
l1[4] = 90
Accessing index outside range raises IndexError.
⑧ How to Add Elements to a List?
Two common methods:
1. append(value) – Adds to the end.
2. insert(index, value) – Inserts at specified index.
[Link](70)
[Link](2, 100)
If index is out of bounds in insert, Python appends at the end.
3. [Link](iterable)
The extend() method adds all elements of an iterable (like another list, tuple,
set, or string) to the end of the current list.
Syntax:
[Link](iterable)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Example:
l2 = [2, 9, 5, 7, 1]
l3 = [10, 20, 40, 50, 60]
[Link](l3) # This will append all elements of l3 to l2
print(l2) # [2, 9, 5, 7, 1, 10, 20, 40, 50, 60]
• The extend() method adds all elements of l3 to the end of l2.
• It modifies l2 in-place and does not return a new list.
⑨ Packing and Unpacking
Packing: Combining multiple variables into a list or tuple. Multiple values into
a list.
a=5
b=6
c = 10
# Packing: Values are combined into a list
l2 = [a, b, c]
print(l2) # Output: [5, 6, 10]
Unpacking: Breaking a list into individual variables. Assigning list elements to
variables.
Note: The number of variables on the left must exactly match the number
of elements in the list.
l1 = [20, 50, 30] # Unpacking: Each value in the list is assigned to a variable
a, b, c = l1
print(a) # Output: 20
print(b) # Output: 50
print(c) # Output: 30
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
⑩ Common Built-in Methods
Method Description Example Code Output
append(x) Add item x to end of list l = [1, 2]; [1, 2, 3]
[Link](3)
insert(i, x) Insert x at index i l = [1, 3]; [1, 2, 3]
[Link](1, 2)
extend(iter) Add all elements from l = [1]; [Link]([2, [1, 2, 3]
iterable 3])
pop(i) Remove and return item l = [1, 2, 3]; returns 2, list:
at index i [Link](1) [1, 3]
remove(x) Remove first occurrence l = [1, 2, 2]; [1, 2]
of value x [Link](2)
clear() Remove all items from list l = [1, 2]; [Link]() []
index(x) Return index of first l = [1, 2, 3]; 1
occurrence of x [Link](2)
count(x) Return count of x in list l = [1, 2, 2, 3]; 2
[Link](2)
sort() Sort list in ascending l = [3, 1, 2]; [Link]() [1, 2, 3]
order (in-place)
reverse() Reverse the list in-place l = [1, 2, 3]; [3, 2, 1]
[Link]()
Method Description Example
len() Returns the number of elements in an iterable len([1, 2, 3]) → 3
min() Returns the smallest element in an iterable min([5, 2, 8]) → 2
max() Returns the largest element in an iterable max([5, 2, 8]) → 8
sum() Returns the sum of all elements in an iterable sum([1, 2, 3]) → 6
sorted() Returns a new sorted list from the elements of sorted([3, 1, 2]) →
an iterable [1, 2, 3]
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Notes:
• These functions work with lists, tuples, and other iterable types.
• sorted() returns a new list; it does not change the original list.
• For strings, min() and max() return characters based on ASCII values.
⑪ list() Constructor
print(list(range(3))) # [0, 1, 2]
print(list()) # []
• Converts other iterable objects to a list.
list("abc") # ['a', 'b', 'c']
list((1, 2, 3)) # [1, 2, 3]
⑫ Comparison Operators on Lists: [==, !=, <, <=, >, >=]
Lists can be compared element by element using:
l1 = [1, 2, 3]
l2 = [2, 3, 1]
l3 = [1, 2, 3, 4, 5]
l4 = [1, 2, 3]
print(l1 == l2) # False - order matters
print(l1 == l3) # False - different elements
print(l1 == l4) # True - same elements in same order
print(l1>l2) # False
⑬ Concatenation Operator: Using + to combine lists:
l1 = [1, 5, 9]
l2 = [2, 3, 1]
l3 = l1 + l2
print(l3) # Output: [1, 5, 9, 2, 3, 1]
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
[1, 2] + [3, 4] # [1, 2, 3, 4]
⑭ Repetition Operator
The asterisk (*) symbol performs different operations based on the data types
involved:
• Multiplication: When used between two numbers (integers or floats), it
performs multiplication.
Examples:
2*3=6
3.4 * 4.5 = 15.3 (Note: May show slight precision differences due to
floating-point representation)
• Repetition Operator: When used between a list and an integer, it repeats
the list multiple times.
Example:
[1, 2] * 3 = [1, 2, 1, 2, 1, 2]
Using * to repeat elements:
[1, 2] * 3 # [1, 2, 1, 2, 1, 2]
⑮ List of Lists (Nested Lists)
Lists can contain other lists as elements.
# Simple list # List with a nested list
l1 = [5, 4.5, True, "rks"] l2 = [5, 4.5, True, [9, 4, 7]]
print(l1) # [5, 4.5, True, 'rks'] print(l2) # [5, 4.5, True, [9, 4, 7]]
print(l2[3][0]) # 9
# 2D list (matrix-like structure) # Accessing first element of each row
l3 = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] print(l3[0][0]) # 1
print(l3[0]) # [1, 2, 3] print(l3[1][0]) # 4
print(l3[1]) # [4, 5, 6] print(l3[2][0]) # 7
print(l3[2]) # [7, 8, 9]
# Invalid access (index out of range)
print(l3[2][3]) # IndexError
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
matrix = [[1, 2], [3, 4], [5, 6]]
print(matrix[1][1]) # 4
⑯ List Object Attributes & Methods
# Use help() to view the documentation for the built-in list class in Python.
# help(list)
# Use dir() to list all attributes (methods and variables) of the list class.
# print(dir(list))
In Python, every class contains attributes, which include both variables and
functions (methods). Attributes are not directly used with list, but methods like
append(), pop() etc. are part of its functionality.
l1 = [5, 4.5, True, "rks"] # l1 is an object (instance) of the built-in list class.
l1.f1() # Attempting to call a method named 'f1' on the list object.
AttributeError: 'list' object has no attribute 'f1'
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
➢ Since the list class has no method named f1, this will raise an AttributeError:
➢ This demonstrates that only the methods defined in the list class can be
called on a list object using dot notation.
List Element Deletion Methods
l = [3, 5, 6, 7, 8, 1, 9, 1]
1. del Statement
del l[1] # Removes the element at index 1 (value 5).
print(l) # Output: [3, 6, 7, 8, 1, 9, 1]
• del is a statement, not a method.
• It directly modifies the list by removing the specified index.
2. remove() Method
[Link](1) # Removes the first occurrence of value 1.
print(l) # Output: [3, 6, 7, 8, 9, 1]
• Deletes by value (not by index).
• Removes only the first matching element.
• Raises a ValueError if the specified value is not found.
3. pop() Method
[Link]() # Removes and returns the last item (default behavior).
print(l) # Output: [3, 6, 7, 8, 9]
print([Link](1)) # Removes and returns the item at index 1 (value 6).
print(l) # Output: [3, 7, 8, 9]
• Deletes by index.
• Returns the deleted item.
• If no index is provided, removes the last element.
• Raises an IndexError if the specified index is out of range.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
⑰ List Comprehension
A concise way to create lists.
squares = [x**2 for x in range(5)]
# [0, 1, 4, 9, 16]
Supports conditions:
even = [x for x in range(10) if x % 2 == 0]
⑱ Taking List Input from User
# Input: 10 20 30
user_input = input("Enter elements: ").split()
numbers = [int(x) for x in user_input]
⑲ Mutability & Hashability
• Lists are mutable – you can change, add, or delete elements.
• Lists are not hashable – they cannot be used as dictionary keys or added
to sets.
hash([1, 2, 3]) # TypeError
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit - 4.3: Str In Python
🔗 For detailed explanations and examples, visit the GitHub repository!
1. Introduction to str in Python
• In Python, a str is a sequence of Unicode characters.
• It is immutable, iterable, hashable, and ordered.
Example:
s = 'technology'
print(s) # technology
print(type(s)) # <class 'str'>
print(hash(s)) # Hashable (returns integer hash value)
2. Creating a String Object
Ways to create strings:
# Using quotes
str1 = "hello"
str2 = 'hello'
str3 = """hello"""
str4 = '''hello'''
# Using str() constructor
str5 = str() # Empty string
str6 = str(123) # '123'
str7 = str(3.14) # '3.14'
str8 = str([1,2,3]) # '[1, 2, 3]'
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
3. Indexing in Strings
• Strings support both positive and negative indexing.
name = "rishabh"
print(name[0]) #r
print(name[-1]) # h
4. Accessing String Elements
Ways to access:
1. By index
2. Using loop
3. Using slicing
s = "Hello"
# Direct access
print(s[0]) #H
# Looping
for char in s:
print(char)
# Slicing
print(s[1:4]) # ell
5. Built-in Functions on Strings
s = 'mindful'
print(len(s)) #7
print(min(s)) # d (based on ASCII)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
print(max(s)) #u
print(sorted(s)) # ['d', 'f', 'i', 'l', 'm', 'n', 'u']
sum() does not work on strings as it's designed for numerical values.
6. Concatenation and Repetition
# Concatenation (+)
print("abc" + "de") # 'abcde'
# Repetition (*)
print("ab" * 3) # 'ababab'
# Mixing with numbers
print(2 + 4) #6
7. Comparison Operators on Strings
Used for dictionary order / lexicographical comparison.
print("apple" < "banana") # True
print("Patna" < "Bhopal") # False
print("Loyal" < "Loyality") # True
• ASCII value-based comparison:
o A-Z: 65–90
o a-z: 97–122
8. Common String Methods
All string methods return a new string — they do not modify the original string
because strings in Python are immutable.
s = "hello world"
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
print([Link]()) # 'HELLO WORLD'
print(s) # 'hello world' (original string unchanged)
s2 = [Link]("world", "Python")
print(s2) # 'hello Python'
print(s) # 'hello world'
Method Description Example Output
upper() Converts to uppercase 'hello'.upper() 'HELLO'
lower() Converts to lowercase 'HELLO'.lower() 'hello'
capitalize() Capitalizes the first letter 'hello'.capitalize() 'Hello'
title() Capitalizes first letter of 'hello world'.title() 'Hello
every word World'
strip() Removes leading/trailing ' hello '.strip() 'hello'
whitespace
replace() Replaces part of the string 'hi'.replace('h', 'b') 'bi'
startswith() Checks if string starts with 'python'.startswith('py') True
given value
endswith() Checks if string ends with 'hello'.endswith('o') True
given value
find() Returns index of first 'hello'.find('l') 2
occurrence
count() Counts number of 'hello'.count('l') 2
occurrences
isalpha() Checks if all characters are 'abc'.isalpha() True
alphabets
isdigit() Checks if all characters are '123'.isdigit() True
digits
isalnum() Checks if all characters are 'abc123'.isalnum() True
alphanumeric
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
9️. String Formatting
Using .format() method:
name = "Rishabh"
age = 25
print("My name is {} and I am {} years old.".format(name, age))
f-Strings (Python 3.6+):
print(f"My name is {name} and I am {age} years old.")
10. split() and join()
# split() — Converts string to list
s = "Python is awesome"
words = [Link]()
print(words) # ['Python', 'is', 'awesome']
# join() — Converts list to string
joined = "-".join(words)
print(joined) # Python-is-awesome
11. Slicing Operator
s = "australia"
print(s[0:9:1]) # australia
print(s[0:9:2]) # asrla
print(s[9:0:-1]) # ailartsu
print(s[0:4]) # aust
print(s[:4]) # aust
print(s[::2]) # asrla [start:end:2]
print(s[::-1]) # ailartsua (reversed string)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
If start and end is not specified, the behavior depends on the value of step:
• If step is positive (step > 0):
o start defaults to 0 (beginning of the sequence).
o print(s[:7:1]) # austral
o end will be last index but inclusive.
o print(s[0::2]) # asrla
• If step is negative (step < 0):
o start defaults to the last element of the sequence.
o print(s[:7:-1]) # a
o end will be start index at 0 inclusive.
o print(s[9::-1]) # ailartsua
Summary Table
Feature Example Output / Behavior
Immutable s[0] = 'H' Error
Concatenation "a" + "b" 'ab'
Repetition "ab" * 3 'ababab'
Indexing "abc"[0] 'a'
Slicing "python"[1:4] 'yth'
Length len("abc") 3
Loop for i in "hi" h, i
Convert to string str(123) '123'
Split / Join "a b".split() ['a', 'b']
' '.join(['a','b']) 'a b'
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit - 4.4: Tuple In Python
🔗 For detailed explanations and examples, visit the GitHub repository!
Introduction to Tuples
• A tuple is a built-in, ordered and immutable collection of items.
• Defined using parentheses () or the tuple() constructor.
• Once created, elements cannot be changed, added, or removed.
• Tuples are:
o Ordered (indexed)
o Iterable and have sequence
o Can hold heterogeneous data types (mixed types)
# Example
t = (1, 'hello', 3.14)
print(type(t)) # <class 'tuple'>
Because of immutability:
• No methods like append(), insert(), extend(), pop(), remove(),
clear(), or del exit in tuple class.
Creating Tuples
t1 = (1, 2, 3)
print(type(t1)) # <class 'tuple'>
t2 = (10) # NOT a tuple!
print(type(t2)) # <class 'int'>
t3 = (10,) # Valid single-element tuple
print(type(t3)) # <class 'tuple'>
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Always use a comma for a single-element tuple: (value,)
# Using tuple() constructor
t = tuple([1, 2, 3]) # From list
t = tuple("abc") # From string -> ('a', 'b', 'c')
Indexing and Accessing Elements
• Tuples support both positive and negative indexing
t = (10, 20, 30, 40, 50)
print(t[0], t[-1]) # 10 50
• Accessing elements using loops
# Using while loop
i=0
while i < len(t):
print(t[i], end=" ")
i += 1
# Using for loop
for item in t:
print(item, end=" ")
Built-in Functions
t = (5, 1, 7, 2, 4, 9)
print(len(t)) #6
print(max(t)) #9
print(min(t)) #1
print(sum(t)) # 28
print(sorted(t)) # [1, 2, 4, 5, 7, 9]
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Tuple Operators
• Concatenation
t1 = (1, 2)
t2 = (3, 4)
print(t1 + t2) # (1, 2, 3, 4)
• Repetition
print(t1 * 3) # (1, 2, 1, 2, 1, 2)
Comparison Operators
• Tuples are compared element by element
(1, 2) == (1, 2) # True
(1, 2) < (2, 1) # True
(10, 20) > (10, 10) # True
Tuple Methods
Only two methods are available:
• count(value) → Returns number of occurrences
• index(value) → Returns the index of the first occurrence
t = (10, 20, 30, 20, 10)
print([Link](10)) #2
print([Link](30)) #2
# [Link](100) # ValueError if not found
Slicing Tuples
• Works like lists
t = (9, 5, 8, 2, 4, 7, 1)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
print(t[2:7:2]) # (8, 4, 1)
print(t[::-1]) # (1, 7, 4, 2, 8, 5, 9)
Taking User Input into Tuple
# Input: 1,2,3,4
t = tuple([int(i) for i in input("Enter numbers (comma-separated):
").split(',')])
print(t) # (1, 2, 3, 4)
Immutability Deep Dive
• You cannot change tuple elements:
t = (1, 2, 3)
# t[0] = 100 # TypeError
• However, tuples can contain mutable objects:
t = ([1, 2], 3)
t[0][0] = 100
print(t) # ([100, 2], 3)
Advanced Tip: Tuple Packing and Unpacking
# Packing
t = 1, 2, 3
print(t) # (1, 2, 3)
print(type(t)) # <class 'tuple'>
# Unpacking
a, b, c = t
print(a, b, c) #123
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Useful for swapping variables:
a, b = 5, 10
a, b = b, a
print(a, b) # 10 5
Use Cases of Tuples
• The data should not be modified.
• You need to return multiple values.
• The data is used as a constant lookup or config.
• You want better performance than a list.
Summary Table
Feature Tuple
Mutability Immutable
Brackets ()
Methods Available count(), index()
Supports Slicing, Allows Duplicates Yes
Can Store Mixed Types Yes
Can Nest Other Tuples/Lists Yes
Tuple vs List
Feature Tuple List
Mutability Immutable Mutable
Syntax (1, 2, 3) [1, 2, 3]
Performance Faster (read-only) Slower
Use Cases Fixed data, dict keys Dynamic data
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit - 4.5: Set In Python
🔗 For detailed explanations and examples, visit the GitHub repository!
Introduction to Set:
• A Set is a built-in data type in Python used to store unordered,
unindexed, and unique elements.
• Sets are iterables but not sequences, so they:
o Do not support indexing or slicing
o Do not guarantee insertion order
Key Characteristics:
Feature Supported
Indexing No
Slicing No
Iteration (for loop) Yes
Mutability of set object Yes
Elements must be Immutable (e.g., int, str, tuple)
Syntax:
# Using curly braces
s = {1, 2, 3}
# Using constructor
s = set([1, 2, 3])
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Creating Set Objects:
s1 = {10, 9, 8}
print(s1, type(s1)) # {8, 9, 10} <class 'set'>
s2 = {9, 8, 9, 7, 6, 8, 1}
print(s2) # {1, 6, 7, 8, 9} # Duplicates removed
Empty Set:
s3 = {} # This creates an empty dictionary
s4 = set() # This creates an empty set
Invalid:
set(10) # Error: int object is not iterable
set(10, 20, 30) # Error: set() takes only one argument
Valid:
print(set("fintech")) # {'f', 'i', 'n', 't', 'e', 'c', 'h'}
Removing Duplicates from a List:
l1 = [20, 10, 50, 20, 30, 50, 20, 10]
result = list(set(l1))
print(result)
Accessing Elements:
s = {10, 9, 8}
for i in s:
print(i)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
# Convert to list for index access
l = list(s)
print(l[0])
Common Set Operations:
s = {3, 1, 9, 2, 5, 7}
print(len(s)) #6
print(min(s)) #1
print(max(s)) #9
print(sum(s)) # 27
print(sorted(s)) # [1, 2, 3, 5, 7, 9]
Unsupported Operations:
# s1 + s2 → Not allowed
# s1 * 2 → Not allowed
s1 = {1, 2, 3}
s2 = {4, 5}
print(s1 + s2) # TypeError
print(s1 * 2) # TypeError
Comparison Operators on Sets:
• Uses subset and superset logic, not element-wise.
s1 = {1, 2, 3}
s2 = {3, 1, 2}
s3 = {9, 8, 7, 6, 1, 3, 2}
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
print(s1 == s2) # True (Same elements, order ignored)
print(s1 < s3) # True (s1 is subset of s3)
print(s3 > s1) # True
Set Methods (Mutating):
add() – Adds a single immutable item
s = {10}
[Link](20)
[Link]("text")
[Link]((1, 2)) # Tuples are allowed
update() – Adds multiple iterable items
[Link]([30, 40], {50})
# Elements are added individually
remove() vs discard()
s = {1, 2, 3}
[Link](2) # Removes 2
# [Link](5) # KeyError if element not present
[Link](5) # No error if element not found
pop() – Removes and returns an arbitrary element
s = {1, 2, 3}
print([Link]()) # e.g. 1
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
clear() – Empties the set
[Link]()
Set Operations (Non-Mutating):
s1 = {1, 2, 3}
s2 = {2, 3, 4, 5}
# Intersection
print([Link](s2)) # {2, 3}
# Union
print([Link](s2)) # {1, 2, 3, 4, 5}
# Subset & Superset
print([Link](s2)) # False
print([Link](s1)) # False
Set Comprehension:
Syntax:
new_set = {expression for item in iterable if condition}
Example 1:
numbers = [1, 2, 2, 3, 4]
squares = {i**2 for i in numbers}
print(squares) # {16, 1, 4, 9}
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Example 2 – Extracting vowels:
text = input("Enter a sentence: ")
vowels = {ch for ch in text if [Link]() in "aeiou"}
print(vowels)
Notes for Comparison with Other Types:
Feature Set List/Tuple/String
Ordered? No Yes
Indexable? No Yes
Unique items Yes No
Mutable? Yes List , Tuple
Hashable? No Tuple (if elements are hashable)
Caution:
• Set elements must be immutable: int, str, tuple (with immutable
items)
• Cannot include lists, dicts, or other sets directly as elements.
Use Cases of Sets in Python:
• Removing duplicates from collections
• Fast membership testing (x in set)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
• Performing mathematical set operations (union, intersection,
difference)
• Extracting unique values
Summary:
• Use set() to define a new set.
• Sets are unordered, unindexed, and store only unique, immutable
elements.
• Indexing, slicing, +, and * operations are not supported.
• Use methods like add(), update(), remove(), discard(), pop(), and
clear().
• Useful for deduplication, filtering, and set operations.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit - 4.6: Dictionary In Python
🔗 For detailed explanations and examples, visit the GitHub repository!
Introduction to Dictionary (dict):
• A dict, is a built-in data type that stores data in key-value pairs.
• Think of it like a real-world dictionary: each key (word) maps to a
value (definition).
• Dictionaries are iterable. And Dictionaries are not in a sequence
(means elements should store in a systemic order i.e indexing
concept). You can iterate over keys, values, or both.
• Indexing is not applicable to dict object. So we can't perform slicing
operation as well.
• Keys must be immutable types, such as strings, numbers, or tuples,
while values can be of any data type.
• Dict. are created using curly braces {} or the dict() constructor.
✦ Key Characteristics:
Property Description
Ordered Maintains insertion order of keys.
Mutable Can be modified after creation.
Iterable Can loop over keys, values, or both.
Indexed No positional indexing like lists or strings.
Duplicate Keys Not allowed; the last assignment overrides earlier
ones.
Keys Only str, int, float, bool, or tuple (with immutable
Immutable elements) can be keys.
Values Flexible Can be any data type (string, list, object, etc).
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Set vs Dict in Python:
1. s1 = {10, 20, 30}
2. print(type(s1)) # <class 'set'>
◉ A set is an unordered collection of unique items (only keys, no values).
✦ You cannot assign values to elements in a set.
1. d1 = {
2. 1: "Rahul",
3. 2: "Aman",
4. 3: "Tarun",
5. 4: "Vinit"
6. }
7. print(type(d1)) # <class 'dict'>
➤ A dictionary contains key-value pairs, where each key maps to a
corresponding value.
Creating Dictionaries:
# Method 1: Using curly braces
d1 = {101: "Delhi", 102: "Mumbai"}
# Method 2: Using dict() constructor
d2 = dict(a="Ram", b="Sita") # {'a': 'Ram', 'b': 'Sita'}
# Empty dict
d3 = {}
d4 = dict()
# Invalid syntax: keys must be valid identifiers
# d5 = dict(1="Ram", 2="Lakhan") # SyntaxError
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Accessing Dictionary Elements:
1. products = {401: "Laptop", 402: "Smartphone", 403:
"Headphones", 404: "Smartwatch"}
2.
3. print(products) # Direct print
4.
5. print(products[402]) # Access via key
6. print(products[404])
7.
8. for K in products:
9. print(K, products[K])
# Iterating keys and accessing values
Tip: Accessing a non-existent key raises KeyError.
Use .get(key) for safe access.
print([Link](999, "Not Found")) # Default fallback
Modifying and Adding Elements:
1. courses = {601: "Data Structures", 602: "Web Development",
603: "Machine Learning", 604: "Cyber Security"}
2.
3. courses[601] = "Data Science" # Edit existing key
4. courses[605] = "Operating System" # Add new key-value pair
5.
6. del courses[603] # Delete a key-value pair
8. print(courses)
How to Add New Elements to Dictionary:
1. employees = {701: "Amit Sharma", 702: "Riya Verma", 703:
"Nikhil Rao", 704: "Sneha Das"}
2. employees[705] = "Rishabh Singh"
# Simple assignment to a new key adds a new item.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Deleting Elements:
del courses[601] # Remove specific key
[Link](605) # Remove and return value by key
[Link]() # Remove last inserted item (LIFO)
[Link]() # Empty the dictionary
Dictionary Methods: items(), keys(), values():
1. days = {1: "Monday", 2: "Tuesday", 3: "Wednesday", 4:
"Thursday", 5: "Friday"}
2.
3. print([Link]()) # Returns a view of (key, value) tuples
4. for i in [Link]():
5. print(i)
6.
7. for k, v in [Link]():
8. print(k, v)
1. print([Link]()) # dict_keys([1, 2, 3, 4, 5])
2. print([Link]()) # dict_values(['Monday', 'Tuesday',
...])
3. #These methods return views, not lists.
#To convert: list([Link]()), etc.
Built-in Functions on Dictionaries:
items = {1: "Milk", 2: "Bread", 3: "Eggs"}
print(len(items)) # Total elements
print(min(items)) # Smallest key
print(max(items)) # Largest key
print(sum(items)) # Sum of keys (if numeric)
print(sorted(items)) # Sorted list of keys
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
To operate on values:
print(sorted([Link]()))
Concatenation and Repetition — Not Allowed Directly
• dict1 + dict2 – Not allowed
• dict1 * 2 – Not allowed
Python 3.9+: Use Pipe Operator |
a = {1: 'a'}
b = {2: 'b'}
c=a|b # {1: 'a', 2: 'b'}
Comparisons:
a = {1: 'apple', 2: 'banana'}
b = {2: 'banana', 1: 'apple'}
c = {1: 'apple', 2: 'orange'}
print(a == b) # True (same items)
print(a != c) # True
a > b, a < b — Not supported
Dictionary Comprehension:
• Powerful way to create dictionaries using expressions.
• Syntax: {key_expr: value_expr for item in iterable}
squares = {x: x**2 for x in range(1, 6)}
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Use with conditions:
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
Best Practices:
• Use .get() to avoid KeyError.
• Use meaningful keys (e.g., employee_id, username).
• Use dictionary comprehension for cleaner logic.
• Use in to check key existence:
• if 101 in d:
• print("Exists")
Common Interview Tips:
Topic Tip
Hashing Dict keys must be hashable (immutable).
Performance Lookup and insertion are O(1) average time.
Avoid dict as key Nested mutable types can't be keys.
JSON compatibility Only string keys are allowed in JSON.
Deep copy Use [Link]() if dict contains nested dicts.
Bonus: Set vs Dictionary:
Feature Set Dictionary
Syntax {1, 2, 3} {key: value}
Structure Unordered collection of unique Key-value mapping
elements
Keys/Values Only elements Both keys and values
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Access No indexing or key access Keys used to access
values
Duplicate Last value
Keys overwrites
Summary Cheatsheet:
d = {'a': 1, 'b': 2}
d['a'] # Access
d['c'] = 3 # Add
d['b'] = 20 # Modify
del d['a'] # Delete
# Safe access
[Link]('x', 'NA') # 'NA'
# Looping
for k, v in [Link]():
print(k, v)
# Comprehension
{x: x*x for x in range(5)}
# Merge
merged = d1 | d2 # Python 3.9+
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit - 5: Function In Python
🔗 For detailed explanations and examples, visit the GitHub repository!
What is a Function?
A function is a block of reusable code that performs a specific task. Instead
of repeating code, we define it once and use it whenever needed.
Definition: A function is a named block of code that performs a specific task
when it is called.
Why Use Functions?
• Avoid repetition (DRY: Don't Repeat Yourself)
• Organize code into logical sections
• Improve readability and modularity
• Make code reusable and maintainable
Syntax of Function
➤ Function Definition
def function_name(parameters):
# block of code
➤ Function Calling
function_name(arguments)
Example
def greet():
print("Hello", "Rishabh")
greet()
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Local vs Global Variables
Local Variable:
A variable declared inside a function and accessible only within it.
def show():
x = 10 # local variable
print(x)
show()
# print(x) ❌ Error – x is not accessible outside
Global Variable:
A variable declared outside all functions and accessible everywhere.
x = 100 # global variable
def display():
print(x)
display()
# If you modify a global variable inside a function, use the global
keyword.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
x = 50
def update():
global x
x = 200
update()
print(x) # Output: 200
Types of Functions Based on Input and Output
Type Input Output
1. Takes Nothing, Returns Nothing
2. Takes Something, Returns Nothing
3. Takes Nothing, Returns Something
4. Takes Something, Returns Something
1. Takes Nothing, Returns Nothing
def add():
print("Enter two numbers:")
a = int(input())
b = int(input())
print("Sum =", a + b)
add()
2. Takes Something, Returns Nothing
def multiplication(a, b): # a and b are formal parameters
result = a * b
print("Result =", result)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
multiplication(10, 20) # 10 and 20 are actual arguments
3. Takes Nothing, Returns Something
def volume():
print("Enter dimensions of cuboid:")
l = int(input())
w = int(input())
h = int(input())
return l * w * h
result = volume()
print("Volume =", result)
4. Takes Something, Returns Something
def factorial(n):
result = 1
for i in range(1, n + 1):
result *= i
return result
num = int(input("Enter a number: "))
print("Factorial =", factorial(num))
Function with Default Arguments
def greet(name="User"):
print("Hello", name)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
greet("Rishabh")
greet()
Function with Return Statement
• Can return single or multiple values
• Stops execution of function
def calculate(a, b):
return a + b, a - b
sum_result, diff_result = calculate(10, 5)
print("Sum =", sum_result)
print("Difference =", diff_result)
Lambda (Anonymous) Functions
Used for small, one-line functions.
square = lambda x: x * x
print(square(5)) # Output: 25
Built-in vs User-defined Functions
• Built-in: Provided by Python (print(), len(), sum(), etc.)
• User-defined: Defined by programmers using def
Recursion in Functions
A function calling itself.
def factorial(n):
if n == 0 or n == 1:
return 1
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
return n * factorial(n - 1)
print(factorial(5))
Summary Table
Concept Description
def Keyword to define a function
Parameters Variables passed to function
Arguments Actual values passed
return Sends back result
Scope Local vs Global
lambda Anonymous function
Recursion Function calling itself
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit – 5.1: Keyword and Positional Arguments
🔗 For detailed explanations and examples, visit the GitHub repository!
📘 Python Function Arguments:
1. Actual vs. Formal Parameters (or Arguments vs. Parameters)
Definitions:
• Actual Parameters (Arguments): The values you pass when calling a
function.
• Formal Parameters: The variables listed in the function definition
that receive the values.
💡 Quick Analogy:
Think of calling someone on the phone:
• You (caller) provide the actual number — that’s the argument.
• The phone receives it as a formal input — that’s the parameter.
🔁 Rewording:
• Arguments: Appear in the function call.
• Parameters: Defined in the function header (definition).
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
🧠 Pro Tip:
Always match the number and order of arguments to the parameters—
unless you use default values, keyword arguments, or *args/**kwargs.
2. Default Arguments
✅ Concept:
• Allows you to assign default values to parameters in a function.
• If the caller doesn’t provide that argument, Python uses the default
value.
🧪 Example:
def f3(a, b, c=0):
print("Sum =", a + b + c)
f3(13, 15) # Output: Sum = 28
💥 Gotcha:
# Non default arguments (i.e. 'c') can't come after default
arguments (i.e. 'b')
def f4(a,b=0,c):
result = a+b+c
print("Sum =",result) # 28
f4(13,15)
# SyntaxError: parameter without a default follows parameter with a
default
❗ Non-default arguments cannot follow default arguments.
Always put parameters with default values at the end of the parameter list.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
✅ Correct Pattern:
def f5(a=0,b=0,c=0): # Default Arguments:
result = a+b+c
print("Sum =",result)
f5() # 0
f5(5) # 5
f5(6,7) # 13
f5(9,8,4) # 21
🧠 Pro Tips:
• Use default arguments to make your functions more flexible and
reusable.
• Don’t overuse default values for mutable types like lists or
dictionaries—this can lead to shared state bugs. Use None instead.
1. def add_student(name, student_list=None):
2. if student_list is None:
3. student_list = [] # Create new list if isn’t passed
4. student_list.append(name)
5. return student_list
6.
7. students_group_1 = add_student("Alice")
8. print("Group 1:", students_group_1) # ➤ ['Alice']
9.
10. custom_list = ["Eve"]
11. updated_list = add_student("Charlie", custom_list)
12. print("Custom List:", updated_list) # ➤ ['Eve', 'Charlie']
3. Positional vs Keyword Arguments
✅ Positional Arguments:
• Passed by position.
• Order matters.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
def f1(a, b):
print("a =", a, "b =", b)
f1(2, 3) #a=2b=3
f1(3, 2) #a=3b=2
✅ Keyword Arguments:
• Passed by explicit naming.
• Order doesn’t matter.
def f1(a,b):
print("a =",a,"b =",b)
f1(b=2,a=3) #a=3b=2
⚖️Mixed Usage (Positional + Keyword):
You can pass arguments using both position and keyword, but positional
arguments must always come first.
def f1(a, b):
print("a =", a, "b =", b)
f1(2, b=3) # ✅ Valid
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
# Output: a = 2 b = 3
💥 Gotcha
1- Duplicate Values: Cannot Assign the Same Parameter Twice
def f1(a, b):
print("a =", a, "b =", b)
# f1(2, a=3) # ❌ Invalid
2 - Positional after Keyword: Keyword Arguments Cannot Be Followed by
Positional Arguments
def f1(a, b):
print("a =", a, "b =", b)
# f1(a=2, 3) # ❌ Invalid
🧠 Pro Tips:
• When readability is important or you’re passing many arguments,
prefer keyword arguments.
• In APIs or libraries, this makes your calls more robust and self-
documenting:
Rule Valid? Example
Positional before keyword ✅ Yes f1(1, b=2)
Assigning the same parameter twice ❌ No f1(1, a=2)
Keyword argument followed by positional ❌ No f1(a=1, 2)
# Good practice
create_user(name="Alice", age=30, country="USA")
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
✅ Summary Table
Feature Description Example Notes
Actual Argument Value passed during f1(3, 5) Caller side
function call
Formal Variable receiving value def f1(a, b) Function side
Parameter in definition
Default Uses default if no value def f1(a, Optional
Argument passed b=0)
Positional Matched by order f1(1, 2) Fast, but
Argument fragile
Keyword Matched by name f1(b=2, Clearer
Argument a=1)
Invalid Order Positional after keyword f1(a=2, 3) ❌
SyntaxError
Duplicate Same arg assigned twice f1(2, a=3) ❌ TypeError
assignment
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
🧠 Additional Tips & Tricks (Advanced Insight)
Tip #1: Use *args and **kwargs for Flexible APIs
def log(message, *values, **options):
print(message)
for v in values:
print(v)
if [Link]('uppercase'):
print([Link]())
Tip #2: Document Default Parameters Clearly
Always document your default values in function docstrings. This improves
API clarity.
Tip #3: Avoid Mutable Defaults
def buggy(a, b=[]): # 🚫 Shared default!
[Link](a)
return b
✅ Fix:
def fixed(a, b=None):
if b is None:
b = []
[Link](a)
return b
Tip #4: Keyword-Only Arguments (Python 3+)
You can force users to pass parameters as keywords:
def register_user(name, *, role="student", age=None):
print(name, role, age)
register_user("Rishabh", role="teacher")
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit – 5.2: Recursion in Python
🔗 For detailed explanations and examples, visit the GitHub repository!
🧠 Introduction: Function calling itself is called recursion.
Recursion involves a function calling itself directly or indirectly to solve a
problem by breaking it down into simpler and more manageable parts.
Example of Infinite Recursion (No Base Case)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Recursion is widely used for tasks that can be divided into identical
subtasks.
Recursive function is defined like any other function, but it includes a call to
itself. The syntax and structure of a recursive function follow the typical
function definition, with the addition of one or more conditions that lead to
the function calling itself.
Output: 10
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
🔁 What is Recursion?
• Recursion is a programming technique where a function calls itself to
solve a problem.
• It breaks down complex problems into simpler sub-problems of the
same type.
• A recursive function must have:
o Recursive Case: Part where the function calls itself.
o Base Case: A condition under which the function stops calling
itself to avoid infinite recursion.
Analogy: Recursion is like looking into a mirror placed in front of another
mirror—multiple reflections of the same thing getting smaller.
⚙️ Structure of a Recursive Function
def function_name(parameters):
if base_condition:
return base_result # Base Case
else:
return some_expression + function_name(smaller_parameters)
# Recursive Case
Example of Infinite Recursion (No Base Case)
def f1():
print("Hi")
f1() # Recursive call without base case – leads to infinite recursion
print("Bye")
f1()
• Problem: This function never stops, eventually causing a
RecursionError: maximum recursion depth exceeded.
• Lesson: Always define a base case to terminate the recursion.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Basic Example – Sum of Natural Numbers
def f1(n):
if n == 1: # Base Case
return 1
return n + f1(n-1) # Recursive Case
print(f1(4)) # Output: 10 (1+2+3+4)
Breakdown:
• f1(4) → 4 + f1(3)
• f1(3) → 3 + f1(2)
• f1(2) → 2 + f1(1)
• f1(1) → returns 1
So, it becomes → 4 + 3 + 2 + 1 = 10
🎯 Example – Factorial Using Recursion
def factorial(n):
if n == 0:
return 1 # Base Case
return n * factorial(n-1) # Recursive Case
print(factorial(5)) # Output: 120
• factorial(5) → 5 * factorial(4) → 5 * 4 * 3 * 2 * 1 = 120
🪜 Concept: Problem Solving with Recursion
General Formula:
f(n) = n + f(n-1) (for n > 1)
f(1) = 1 (base case)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Example:
f1(100) = 100 + f1(99)
Each time, the function breaks the problem into a smaller problem (n-1)
until it reaches the base case.
🧩 3-Step Approach to Build a Recursive Function
✅ Step 1: Assume the function is already built
def sum(n): # This will sum numbers from 1 to n
✅ Step 2: Recursive Case – Call the function for a smaller problem
sum(n-1) # Adds numbers up to n-1
n + sum(n-1) # Combine it with current n
✅ Step 3: Base Case – When to stop calling
if n == 1:
return 1 # Simplest case, stops recursion
💡 Final Order: Write in sequence → Step 1, Step 3, Step 2
📐 Example – Sum of Squares of First n Natural Numbers
def sum_of_sq(n): # Step 1
if n == 1: # Step 3 (Base Case)
return 1
return n**2 + sum_of_sq(n-1) # Step 2 (Recursive Case)
print(sum_of_sq(4)) # Output: 30 (1^2 + 2^2 + 3^2 + 4^2 = 30)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
🔄 Recursion Flow (Visualization)
Calling sum_of_sq(4) leads to:
• 4^2 + sum_of_sq(3)
• 3^2 + sum_of_sq(2)
• 2^2 + sum_of_sq(1)
• sum_of_sq(1) returns 1
→ Backtrack: 1 + 4 + 9 + 16 = 30
⚠️ Points to Remember
• Always ensure a base case exists.
• Recursion must progress toward the base case.
• Python has a recursion depth limit (usually 1000).
• Recursion uses more memory due to call stack overhead.
🧠 Why Use Recursion?
• Great for problems naturally defined recursively:
o Tree traversals
o Fibonacci sequence
o Factorials
o Backtracking (e.g., Sudoku, N-Queens)
o Divide & Conquer algorithms (e.g., Merge Sort, Quick Sort)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit – 5.3: Lambda in Python
🔗 For detailed explanations and examples, visit the GitHub repository!
🔥 1. What is lambda in Python?
• lambda is a keyword in Python used to define anonymous functions
(functions without a name).
• These are inline functions, defined in a single line and typically used
for short operations.
Syntax:
lambda arguments: expression
Example:
add = lambda a, b: a + b
print(add(3, 4)) # Output: 7
🧠 2. Comparison with def Functions
Using def:
def add(a, b):
return a + b
Using lambda:
add = lambda a, b: a + b
Feature def function lambda expression
Named function Yes No (anonymous, unless
assigned)
Supports multi- Yes ❌ No (single expression
line? only)
Return keyword Required Implicit return
Readability Better for complex Ideal for quick small
logic operations
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
✅ 3. Lambda Function Behaviour (as Object)
💡 Lambda functions behave just like normal functions — they're objects
stored in memory and referenced by variables.
1. def add(a,b):
2. return a+b
3. s= add(3,4)
4. print(s) # 7
5.
6. y = add
7. print(y) # <function add at
0x0000020B759D1440>
8.
9. print(id(add)) # 1532913325120
10. print(id(y)) # 1532913325120
11.
12. print(y is add) # True, bez both are referencing
to same object.
13.
14. print(add(5,6)) # 11
15. print(y(5,6)) # 11
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
📌 4. Direct Execution Without Assignment
You can call a lambda directly without assigning it to a variable:
print((lambda a, b: a + b)(3, 5)) # Output: 8
print((lambda x: x**2)(6)) # Output: 36
⚠️ This approach is not reusable.
✅ 5. Reusability with Variables
Assign the lambda to a variable for repeated use:
square = lambda x: x * x
print(square(5)) # Output: 25
✅ 6. Lambda in Data Structures
You can store lambda functions in lists, dicts, etc.
operations = {
"add": lambda a, b: a + b,
"sub": lambda a, b: a - b,
"mul": lambda a, b: a * b
}
print(operations["mul"](4, 5)) # Output: 20
✅ 7. Lambda with Built-in Functions
i) map() applies a function to every item in an iterable.
1. numbers = [1,2,3,4]
2. sq = list(map(lambda x: x**2, numbers))
3. print(sq) # [1, 4, 9, 16]
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
ii) filter() returns only the items that satisfy a condition (i.e., where the
lambda returns True).
1. data = [1,4,5,6,7,8,10]
2. evendata = list(filter(lambda y:y%2==0,data))
3. print(evendata)
iii) reduce() applies a function cumulatively to the elements of a sequence.
1. from functools import reduce
2. numbers = [1,2,3,4]
3. listmul = reduce(lambda x,y : x*y, numbers)
4. print(listmul) # 24
Function Purpose Lambda Role
map() Transform each element Defines how to transform
filter() Select elements based on Defines the condition to keep
condition
reduce() Collapse all elements to one Defines how to combine
value cumulatively
✅ 8. Lambda in sorted()
students = [('John', 82), ('Jane', 91), ('Dave', 74)]
sorted_students = sorted(students, key=lambda x: x[1])
print(sorted_students)
# [('Dave', 74), ('John', 82), ('Jane', 91)]
✅ 9. Lambda in GUI / Web / Functional Programming
Often used in:
• Tkinter callbacks
• Flask route functions
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
• Event handlers
• Decorators (advanced use)
✅ 10. Recursive Lambda (Advanced Use)
Python normally restricts lambda from self-referencing. But you can work
around this.
⚠️ Naive (won't work without assignment):
f = lambda n: 1 if n==0 or n==1 else n*f(n-1)
print(f(5)) # 120
✔️ Advanced: Using Named Function Inside
factorial = (lambda f: lambda n: 1 if n <= 1 else n * f(f)(n-1))(lambda f:
lambda n: 1 if n <= 1 else n * f(f)(n-1))
print(factorial(5)) # 120
✅ This is called Y combinator or self-application trick, useful for recursion
in anonymous functions.
✅ 11. Lambda with if-else Logic
max_val = lambda a, b: a if a > b else b
print(max_val(10, 20)) # Output: 20
✅ 12. Lambda Function Limitations
• Only one expression allowed (no if/else, loops, try/except unless all
in one line).
• Hard to debug and not suitable for complex logic.
• Can harm readability when overused or nested deeply.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
✅ Summary:
Concept Example
Basic usage lambda a,b: a+b
Assign to var add = lambda a,b: a+b
Call directly (lambda a,b: a+b)(3,4)
With map() map(lambda x:x*x, list)
With filter() filter(lambda x:x%2==0, list)
With sorted() sorted(list, key=lambda x: x[1])
Recursion f = lambda n: 1 if n<=1 else n*f(n-1)
Ternary logic lambda a,b: a if a>b else b
🧠 Final Tip for Mastery
Use lambda when:
• The function is short and used temporarily.
• You want a clean, concise alternative to def.
• Inside higher-order functions like map, filter, sorted, reduce.
Avoid it when:
• Logic is complex.
• Readability is crucial.
• You need multi-line functionality or docstrings.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit – 6.1: Introduction to OOPs
🔗 For detailed explanations and examples, visit the GitHub repository!
🧠 Procedural Programming:
Series of instruction to accomplish a task.
Procedural Programming organizes code into a set of functions that call each
other to perform tasks, improving reusability and efficiency. For example, you can
create functions like Max and Min to find the maximum or minimum values in a
list, which can be reused without rewriting code. It starts with a main function
that calls other functions for specific tasks, helping to manage larger programs.
However, it can become complex when dealing with large software systems that
require passing many data fields between functions.
🔥 Object-Oriented Programming:
Object-Oriented Programming (OOP) improves code organization for large
software systems by using objects instead of functions. Each object represents a
real-world entity, holding both data and methods. For instance, a university
system can have classes for Student, Faculty, and Course. A Student class might
include name, address, mobile number, course taken, and professor teaching.
OOP reduces data transfer between functions and allows objects to interact easily.
Classes and Objects in OOPs
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
In Python, classes and objects are fundamental concepts in object-oriented
programming (OOP). A class serves as a blueprint for creating objects, which are
individual instances of that class.
What is a Class?
A class defines a new data type that encapsulates data and the functions that
operate on that data. It specifies what attributes (data members) and behaviors
(methods) the objects created from the class will have.
⚙️ Creating a Class:
To create a class in Python, you use the class keyword followed by the class
name. Here is an example of a Complex class that represents complex numbers:
1. class Student:
2. name = "Abhi"
3. def display(self):
4. print([Link])
The Complex class has two data members, real and imag, and two methods, print
and add, for complex numbers.
What is Object?
An object is an instance of a class. When you create an object, you allocate
memory for it and initialize its data members. For example, C1 and C2 are objects
of the Complex class. Each object holds its own values for real and imag.
1. class Student:
2. name = "Abhi"
3. def display(self):
4. print([Link])
5. s1 = Student() # Object 1
6. s2 = Student() # Object 1
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Classes vs. Objects
A class is like a blueprint for a house, while an object is an actual house built
from that blueprint. The class defines the structure and behavior, and objects are
the tangible instances created based on that definition.
45123
45123 <- id
💡 Comparison with Other Languages
In languages like C++ and Java, there are primitive types (e.g., int, float)
and class types. Python differs because every type in Python is a class, and even
basic variables are instances of classes. This uniformity simplifies the language's
design and usage.
📌 Constructors in Python
A constructor is a special method used to initialize objects when they are
created. In Python, the __init__ method serves as the constructor. It sets up the
initial state of an object by assigning values to its data members.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
🧩 The self Reference
self is a special reference used within class methods to refer to the current
instance of the class. It allows access to the object's data members and other
methods. This is similar to the this keyword in C++ and Java.
✅ Using Methods to Manipulate Objects
Methods like print and add perform specific operations on an object's data
members. The print method displays the complex number in a readable format,
while the add method adds the real and imaginary parts of
another Complex object to the current object.
✔️Accessing Members with the Dot Operator
The dot operator (.) is used to access an object's methods and data members.
For example, [Link]() calls the print method of the C1 object,
and [Link] accesses the real data member of C1.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
🎯 Advantages of Object-Oriented Programming
Object-oriented programming (OOP) is a widely used programming paradigm that
organizes software design around objects. The main advantages include:
• Modularity: Code is organized into separate classes, making it easier to
manage and maintain.
• Reusability: Classes can be reused across different programs, reducing
redundancy.
• Scalability: OOP makes it easier to scale software by adding new classes
and objects.
• Maintainability: Encapsulation ensures that objects manage their own
data, leading to fewer bugs and easier updates.
Top Interview Questions
Why is OOP more suitable for large applications?
How does OOP improve code reusability and maintenance?
Can a class exist without objects? Explain.
Can objects exist without a class?
Why do we say data and behavior are bundled in OOP?
What happens internally when we create an object?
Is OOP a programming language? Explain.
How is procedural programming different from object-oriented programming?
What is a programming paradigm?
Why are classes compared to common nouns and objects to proper nouns?
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit – 6.2: Type Of Variables / Functions
🔗 For detailed explanations and examples, visit the GitHub repository!
1. Instance Object Variable [IOV]:
Defined using self.<var> inside methods.
Specific to each object (instance) of the class.
Example: self.a = a → t1.a, t2.a are IOVs.
2. Class Object Variables [COV]:
And there is no static keyword in python.
Defined inside class but outside all methods.
Shared by all instances of the class.
Example: x = 10 → x is a COV.
3. Local Variable [LC]:
Defined inside a method and not using self.
Scope is limited to the function/method where declared.
Examples: m1 = 4, a (the parameter in __init__), and self (function parameter).
4. Global Variable [GC]:
Defined outside any class or function.
Accessible throughout the module.
Example:
1. class Test:
2. x = 10
3. def f1():
4. m1 = 4
5. def __init__(self,a):
6. self.a = a
7.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
8. t1 = Test(5)
9. t2 = Test(7)
# All the variables name in the above code:
x, m1, a, t1.a, t2.a, self, t1, t2, Test, f1, __init__
Variable Type Explanation
x COV Declared at class level (shared by all objects)
m1 LV Local to method f1()
a LV Argument to __init__()
self.a IOV Instance-specific variable
t1.a/t2.a IOV Access to instance variable a
self LV Local parameter of __init__
t1, t2 GV Created at module level
Test GV Class object reference at global level
f1 COV Method is an attribute of the class — technically it’s a class
attribute referencing a function object
__init__ COV Same as f1 — attribute referencing a constructor function
object
Types of Functions:
1. Instance method
2. Static method
3. Class method
4. Non-member function
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
1. Instance Method
• These are regular methods inside a class.
• They always take self as the first parameter.
• self refers to the current object.
• Used to access and modify instance variables (unique to each object).
class Test:
def f1(self): # Instance method
self.a = 5 # Setting instance variable
Key Points:
• Called using object like obj.f1().
• Used when you want to work with instance-specific data.
2. Static Method
• Defined using the @staticmethod decorator.
• Does not take self or cls as the first parameter.
• Cannot access instance (self) or class (cls) data.
• Acts like a regular function, but lives in the class namespace.
class Test:
@staticmethod
def f2(): # Static method
print("This is a static method")
Key Points:
• Can be called using class or object: Test.f2() or obj.f2().
• Best used for utility/helper functions related to the class.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
3. Class Method
• Defined using the @classmethod decorator.
• Takes cls as the first parameter, referring to the class itself.
• Can access/modify class-level variables (shared across all objects).
class Test:
@classmethod
def f3(cls): # Class method
cls.x = 10 # Modifying class variable
Key Points:
• Use when you want to work with the class itself, not specific instances.
4. Non-Member Function
• Functions that are outside any class.
• They are not related to any class or object.
def fun4():
print("I am a non-member function!")
Key Points:
• Regular functions, not object-oriented.
• Called normally: fun4().
Instance Object Variable (IOV) vs. Class Object Variable (COV)
1. Instance Object Variable (IOV)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
• Variables unique to each object.
• Created using self inside instance methods or __init__.
• Stored in the object’s __dict__.
class Test:
def __init__(self):
[Link] = "Rishabh" # IOV
def set_age(self):
[Link] = 22 # IOV
t1 = Test() # Object 1
t2 = Test() # Object 2
t1.set_age()
Access Methods:
• Inside class: via [Link]
• Outside class: via [Link] (e.g., [Link])
Key Points:
• Each object gets its own copy of these variables.
• Not shared between objects.
2. Class Object Variable (COV) / Static Variable
• Created inside the class but outside any method.
• Shared among all objects.
• Stored in the class’s __dict__.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
class Test:
x = 10 # COV
def set_var(self):
Test.y = 20 # Another COV created dynamically
@staticmethod
def set_static():
Test.z = 30 # Yet another COV
@classmethod
def set_class(cls):
cls.w = 40 # Accessing COV using class reference
Access Methods:
• Inside class: via [Link] or [Link] (in class method)
• Outside class: via [Link] or [Link]
Key Points:
• Shared by all instances of the class.
• Can be created or modified using class name or cls.
Example Summary:
Here's your example explained in steps:
class Test:
x1 = 7 # COV created
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
def f1(self):
self.a = 10 # IOV created
Test.x2 = 5 # COV created or modified
@staticmethod
def f2():
Test.x3 = 9 # COV created
print("Hello", Test.x3)
@classmethod
def f3(cls):
cls.x4 = 22 # COV created using cls
Test.x5 = 11 # Another COV
print(Test.x5, "Hey", cls.x4)
t1 = Test() # Instance created
Test.x4 = 17 # Set COV x4 directly
Test.f2() # Static method call
Test.f3() # Class method call
After this code:
• x1, x2, x3, x4, x5 are all Class Object Variables
• a is an Instance Object Variable (inside t1)
• All class variables are shared, but instance variable a belongs only to t1.
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Quick Recap Table:
Type Keyword First Accesses Called By
Param
Instance (default) self Instance [Link]()
Method variables
Static Method @staticmethod None None [Link]() /
[Link]()
Class Method @classmethod cls Class [Link]() /
variables [Link]()
Non-member (outside class) None None Directly as function
Function
Top 15 Interview Questions:
Why does Python lack strict data hiding?
How does __init__() differ from constructors in Java/C++?
What is self in Python and why is it required?
How does self link a method to a specific instance?
What is the difference between class variables and instance variables?
What happens when an instance variable and a class variable have the same name?
Can we create instance variables outside the class? If yes, how?
What happens if __init__() is not defined in a class?
Is __init__() a constructor? Why or why not?
Why common nouns are converted into classes in OOP?
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit – 6.3: Attributes of a Class
🔗 For detailed explanations and examples, visit the GitHub repository!
Class Object vs Instance Object (Recap)
Class Object
• Created once when a class is defined.
• Contains:
o Class variables (static variables)
o Class methods
o Static methods
Instance Object
• Created multiple times from the same class.
• Each instance has its own copy of instance variables.
__init__() Method (Constructor)
• A special method automatically called when an object is created.
• Used to initialize instance variables.
• First parameter is always self.
class Test:
def __init__(self, a):
self.a = a
➡ self.a is an instance object variable
Types of Variables in Python
Python has 4 types of variables:
Local Variables
• Declared inside a function
• Scope is limited to that function
def fun():
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
x = 10 # local variable
Global Variables
• Declared outside all functions and classes
• Accessible throughout the program
x = 5 # global variable
def fun():
print(x)
Instance Object Variables
• Belong to individual objects
• Created using:
o [Link] inside class methods
o [Link] outside the class
class Test:
def __init__(self):
self.a = 10 # instance variable
t1 = Test()
t2 = Test()
➡ t1.a and t2.a are separate
Class Object Variables (Static Variables)
• Belong to the class
• Shared by all objects
• Created using the class name
class Test:
x = 5 # class variable
Test.x = 7
➡ Same x used by all instances
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Types of Methods in Python
Python has 4 types of functions/methods:
Instance Methods
• Work on instance objects
• First parameter is self
• Can access instance variables
class Test:
def show(self):
print("Instance method")
Static Methods
• Do not work on class or instance data
• No self or cls
• Defined using @staticmethod
class Test:
@staticmethod
def fun():
print("Static method")
Class Methods
• Work on class object
• First parameter is cls
• Defined using @classmethod
class Test:
x = 10
@classmethod
def show(cls):
print(cls.x)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Non-Member Functions
• Defined outside any class
• Normal functions
def fun():
print("Non-member function")
Creating & Accessing Variables
Instance Variables
✔ Using Object
t1.a = 11
✔ Using self inside class
self.a = 11
Class Variables
✔ Using Class Name (Recommended)
Test.x = 7
✔ Accessing
print(Test.x)
print(t1.x)
Important Points to Remember
• ✔ Only one class object exists per class
• ✔ Each instance has its own instance variables
• ✔ Class variables are shared
• ✔ self → instance reference
• ✔ cls → class reference
• ✔ Static methods cannot access instance variables directly
• ✔ Practice is essential for mastery
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
Unit – 6.4: Local Vs Global Variables
🔗 For detailed explanations and examples, visit the GitHub repository!
1️⃣ Introduction
• Many programmers use local and global variables unknowingly.
• This session clarifies:
o Scope of variables
o Name conflicts
o Use of global keyword
o Use of globals() function
2️⃣ Local Variables
🔹 Definition
• A local variable is defined inside a function.
• Its scope is limited to that function only.
• It cannot be accessed outside the function.
🔹 Characteristics
• Created when the function is called
• Destroyed after function execution
• Not accessible globally
🔹 Example
def fun():
x = 10 # local variable
print(x)
fun()
print(x) # ❌ Error: x is not defined
Key Point
➡ Local variables exist only inside their function
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
3️⃣ Global Variables
🔹 Definition
• A global variable is declared outside all functions and classes.
• It can be accessed anywhere in the program.
🔹 Characteristics
• Created when the program starts
• Exists until the program ends
• Accessible inside and outside functions
Example
x = 10 # global variable
def fun():
print(x)
fun()
print(x)
Output:
10
10
4️⃣ Local vs Global Variable (Same Name Conflict)
🔹 Problem Scenario
When a variable name is same in local and global scope:
x = 10
def fun():
x = 20
print(x)
fun()
print(x)
Output:
20
10
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
🔹 Explanation
• Assignment inside a function makes the variable local by default
• Global variable remains unchanged
5️⃣ Accessing Global Variable Inside a Function (Name Conflict)
🔹 Using global Keyword
• To modify a global variable inside a function, use global
x = 10
def fun():
global x
x = 20
fun()
print(x)
Output:
20
Key Rule
➡ Without global, Python treats the variable as local
6️⃣ Using globals() Function
🔹 What is globals()?
• A built-in function
• Returns a dictionary of all global variables
🔹 Example
x = 10
def fun():
globals()['x'] = 50
fun()
print(x)
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
➡ Output:
50
When to Use
• When:
o You want to avoid global keyword
o You want dynamic access to global variables
8️⃣ Comparison Table
Feature Local Variable Global Variable
Defined Inside function Outside all functions
Scope Function only Entire program
Lifetime During function execution Program lifetime
Access outside function ❌ No ✔ Yes
Modification inside function ✔ Yes ❌ (needs global)
9️⃣ Exam-Oriented Points 📌
• Default behavior: Assignment inside function → local variable
• global keyword tells Python:
"This variable belongs to global scope"
• globals() returns:
• dict → {variable_name: value}
🔚 Conclusion
• Understanding scope rules avoids bugs
• Overuse of global variables is not recommended
• Prefer:
o Function arguments
o Return values
• Practice examples to master the concept
©2026 Rishabh Singh [@itsindrajput] | Feel free to share
🎉Thanks For Reaching Till The End!
Your Journey into Python doesn't stop here — it’s just
getting Started.
Let’s Connect
If you found this helpful, feel free to share it. I’d love to connect,
collaborate, or exchange ideas around technology. Explore more or
reach out through the links below.
Portfolio GitHub Linkedin X 🖇️Instagram
Keep Learning. Keep Building.
Thanks again for reading — wishing you continued success and
growth in your development journey!
— Rishabh Singh
©2026 Rishabh Singh [@itsindrajput] | Feel free to share