Python Programming for Beginners to Advanced Level Learners
Python Programming for Beginners to Advanced Level Learners
Table Of Content
Overview
Pythonic Code Style
The Zen of Python
History and Versions
History of Python
Who Invented Python?
Evolution of Python – The Major Python Versions
Python 0.9.0
Python 1.0
Python 2.0
Python 3.0
EOL for Python 2.x
Current Version of Python
What's New in Python 3.11?
Python in the Future
Frequently Asked Questions About Python History
1. Who created Python?
2. Why is Python called Python?
3. When was Python's first version released?
4. What was the first version of Python?
5. When was the Python 3.0 version released?
Features
Easy to Learn
Dynamically Typed
Interpreter Based
Interactive
Multi-paradigm
Standard Library
Open Source and Cross Platform
GUI Applications
Database Connectivity
Extensible
Active Developer Community
Python vs C++
What is Python?
Features
Python Example
What is C++?
Features
C++ Example
Comparison Between Python and C++ across Various Aspects
Compiled vs Interpreted
Cross platform
Portability
Speed of Development
Easy to Learn
Static vs Dynamic Typing
OOP Concepts
Garbage Collection
Application Areas
Difference Between Python and C++
Hello World Program
Hello World Program in Python
Steps
Python Program to Print Hello World
Different Ways to Write and Execute Hello World Program
Using Python Interpreter Command Prompt Mode
Using Python Interpreter Script Mode
Using Shebang #! in Linux Scripts
FAQs
1. Why is the first program called Hello World?
2. Installation of Python is required to run Hello World program?
3. How do I run a Python program without installing it?
4. First Program Vs Hello World Program in Python?
5. Which is/are the method to print Hello World or any message?
Application Areas
Data Science
Machine Learning
Web Development
Computer Vision and Image processing
Embedded Systems and IoT
Job Scheduling and Automation
Desktop GUI Applications
Console-based Applications
CAD Applications
Game Development
Python Interpreter and Its Modes
Python Interpreter
Python Interpreter - Interactive Mode
Python Interpreter - Scripting Mode
Python Interpreter - Using Shebang #!
Interactive Python - IPython
Environment Setup
Local Environment Setup
Downloading Python
Installing Python
Install Python on Ubuntu Linux
Install Python on other Linux
Using Yum Command
Install Python on Windows
Macintosh Installation
Setting up PATH
Setting path at Unix/Linux
Setting path at Windows
Python Environment Variables
Running Python
Interactive Interpreter
Script from the Command-line
Integrated Development Environment
Virtual Environment
Python Virtual Environment
What is a Virtual Environment in Python?
Creation of Virtual Environments in Python using venv
Activating Virtual Environment
Checking If Python is Running Inside a Virtual Environment?
Deactivating Virtual Environment
Syntax
Python - Syntax
First Python Program
Python - Interactive Mode Programming
Python - Script Mode Programming
Python Identifiers
Python Reserved Words
Python Lines and Indentation
Python Multi-Line Statements
Quotations in Python
Comments in Python
Using Blank Lines in Python Programs
Waiting for the User
Multiple Statements on a Single Line
Multiple Statement Groups as Suites
Command Line Arguments in Python
Variables
Python Variables
Memory Addresses
Creating Python Variables
Example to Create Python Variables
Printing Python Variables
Example to Print Python Variables
Deleting Python Variables
Example
Getting Type of a Variable
Example: Printing Variables Type
Casting Python Variables
Example
Case-Sensitivity of Python Variables
Python Variables - Multiple Assignment
Python Variables - Naming Convention
Example
Example
Example
Python Local Variables
Example
Python Global Variables
Example
Constants in Python
Python vs C/C++ Variables
Data Types
Python Data Types
Types of Data Types in Python
1. Python Numeric Data Types
Example of Numeric Data Types
2. Python String Data Type
Example of String Data Type
3. Python Sequence Data Types
(a) Python List Data Type
Example of List Data Type
(b) Python Tuple Data Type
Example of Tuple data Type
(c) Python Range Data Type
Example of Range Data Type
4. Python Binary Data Types
(a) Python Bytes Data Type
Example of Bytes Data Type
(b) Python Bytearray Data Type
Example of Byte Array Data Type
(c) Python Memoryview Data Type
Example of Memoryview Data Type
5. Python Dictionary Data Type
Example of Dictionary Data Type
6. Python Set Data Type
Example of Set
7. Python Boolean Data Type
Example of Boolean Data Type
8. Python None Type
Example of None Type
Getting Data Type
Example
Setting Data Type
Example
Primitive and Non-primitive Data Types
1. Primitive Types
2. Non-primitive Types
Python Data Type Conversion
Example
Data Type Conversion Functions
Type Casting
Python Type Casting
Python Implicit Casting
Python Explicit Casting
Python int() Function
String to Integer
Binary String to Integer
Octal String to Integer
Hexa-Decimal String to Integer
Python float() Function
Python str() Function
Integer to string
Float to String
Conversion of Sequence Types
Data Type Conversion Functions
Unicode System
What is a Unicode System?
Character Encoding
Python's Unicode Support
Example
Example
Example
Example
Literals
What are Python Literals?
Different Types of Python Literals
Python Integer Literal
1. Decimal Literal
2. Octal Literal
3. Hexadecimal Literal
Example
Python Float Literal
Example of Float Literal
Example of Float Scientific Notation Literal
Python Complex Literal
Example of Complex Type Literal
Python String Literal
Example of String Literal
Example of String Literal With Double Quotes Inside String
Python List Literal
Example of List Type Literal
Python Tuple Literal
Example of Tuple Type Literal
Example of Tuple Type Literal Without Parenthesis
Python Dictionary Literal
Example of Dictionary Type Literal
Operators
Python Operators
Types of Python Operators
Python Arithmetic Operators
Example of Python Arithmetic Operators
Python Comparison Operators
Example of Python Comparison Operators
Python Assignment Operators
Example of Python Assignment Operators
Python Bitwise Operators
Example of Python Bitwise Operators
Python Logical Operators
Example of Python Logical Operators
Python Membership Operators
Example of Python Membership Operators
Python Identity Operators
Example of Python Identity Operators
Python Operators Precedence
Arithmetic Operators
Python Arithmetic Operators
Types of Arithmetic Operators
Addition Operator
Example to add two integer numbers
Example to add integer and float numbers
Example to add two complex numbers
Subtraction Operator
Example to subtract two integer numbers
Example to subtract integer and float numbers
Example to subtract complex numbers
Multiplication Operator
Example to multiply two integers
Example to multiply integer and float numbers
Example to multiply complex numbers
Division Operator
Example to divide two numbers
Example to divide two float numbers
Example to divide complex numbers
Modulus Operator
Example for modulus operation on integers
Example for modulus operation on floats
Exponent Operator
Example of exponent operator
Floor Division Operator
Example of floor division operator
Precedence and Associativity of Arithmetic Operators
Arithmetic Operators with Complex Numbers
Addition and subtraction of complex numbers
Multiplication of complex numbers
Division of complex numbers
Comparison Operators
Python Comparison Operators
Different Comparison Operators in Python
Example
Example
Comparison of Float Number
Example
Comparison of Complex numbers
Example
Example
Comparison of Booleans
Example
Comparison of Sequence Types
Example
Example
Example
Comparison of Dictionary Objects
Example
Assignment Operators
Python Assignment Operator
Example of Assignment Operator in Python
Augmented Assignment Operators in Python
Example
Augmented Addition Operator (+=)
Augmented Subtraction Operator (-=)
Augmented Multiplication Operator (*=)
Augmented Division Operator (/=)
Augmented Modulus Operator (%=)
Augmented Exponent Operator (**=)
Augmented Floor division Operator (//=)
Logical Operators
Python Logical Operators
Example
Logical "and" Operator
Logical "and" Operator Truth Table
Logical "or" Operator
Logical "or" Operator Truth Table
Logical "not" Operator
Logical "not" Operator Truth Table
How does the Python interpreter evaluate the logical operators?
Python Logical Operators Examples
Example 1: Logical Operators With Boolean Conditions
Example 2: Logical Operators With Non- Boolean Conditions
Example 3: Logical Operators With Strings and Tuples
Example 4: Logical Operators To Compare Sequences (Lists)
Bitwise Operators
Python Bitwise Operators
Python Bitwise AND Operator (&)
Example of Bitwise AND Operator in Python
Python Bitwise OR Operator (|)
Example of Bitwise OR Operator in Python
Python Bitwise XOR Operator (^)
Example of Bitwise XOR Operator in Python
Python Bitwise NOT Operator (~)
Example of Bitwise NOT Operator in Python
Python Bitwise Left Shift Operator (<<)
Example of Bitwise Left Shift Operator in Python
Python Bitwise Right Shift Operator (>>)
Example of Bitwise Right Shift Operator in Python
Membership Operators
Python Membership Operators
Types of Python Membership Operators
The 'in' Operator
The 'not in' Operator
Membership Operator with Lists and Tuples
Example
Membership Operator with Sets
Membership Operator with Dictionaries
Identity Operators
Python Identity Operators
Python 'is' Operator
Example of Python Identity 'is' Operator
Python 'is not' Operator
Example of Python Identity 'is not' Operator
Python Identity Operators Examples with Explanations
Example 1
Example 2
Example 3
Python Operator Precedence
Python Operator Precedence
Python Operator Precedence Table
Python Operator Precedence Example
Comments
Python Comments
Example
Single Line Comments in Python
Example: Standalone Single-Line Comment
Example: Inline Single-Line Comment
Multi Line Comments in Python
Consecutive Single-Line Comments
Multi Line Comment Using Triple Quoted Strings
Using Comments for Documentation
Python Docstrings
Accessing Docstrings
User Input
Provide User Input in Python
Python User Input Functions
The input() Function
The raw_input() Function
Taking Numeric Input in Python
The print() Function
Numbers
Python - Number Types
Python − Integer Numbers
Binary Numbers in Python
Octal Numbers in Python
Hexa-decimal Numbers in Python
Python − Floating Point Numbers
Python − Complex Numbers
Number Type Conversion
Theoretic and Representation Functions
Power and Logarithmic Functions
Trigonometric Functions
Angular conversion Functions
Mathematical Constants
Hyperbolic Functions
Special Functions
Random Number Functions
Built-in Mathematical Functions
Booleans
Python Booleans (bool)
Example
Example
Python Boolean Expression
Example
Control Flow
Decision Making Statements
The if Statements
The match Statement
Loops or Iteration Statements
The for Loop
The while Loop
Jump Statements
The break Statement
The continue Statement
Decision Making
Types of Decision Making Statements in Python
Single Statement Suites
Example
if...else statement
Example
Nested if statements
Example
if Statement
Python If Statement
Syntax of the if Statement
Flow Diagram (Flowchart) of the if Statement
Example of Python if Statement
Python if-else Statement
Python if else Statement
Syntax of if-else Statement
Flowchart of if-else Statement
Python if-else Statement Example
Python if elif else Statement
Syntax of Python if elif else Statement
How if elif else Works?
Example
Python if elif else Statement Example
Nested if Statement
Syntax of Nested if Statement
Flowchart of Nested if Statement
Example of Nested if Statement
Nested if Statement with else Condition
Syntax
Example
Match-Case Statement
Python match-case Statement
Syntax
Example
Combined Cases in Match Statement
Example
List as the Argument in Match Case Statement
Example
Using "if" in "Case" Clause
Example
Loops
Python Loops
Flowchart of a Loop
Types of Loops in Python
Python Loop Control Statements
For Loops
Syntax of Python for Loop
Flowchart of Python for Loop
Python for Loop with Strings
Example
Python for Loop with Tuples
Example
Python for Loop with Lists
Example
Python for Loop with Range Objects
Syntax
Example
Python for Loop with Dictionaries
Example
Example
Example
Using else Statement with For Loop
Example
Python for-else Loops
Python - For Else Loop
Flowchart of For Else Loop
Syntax of For Else Loop
Example of For Else Loop
For-Else Construct without break statement
Example
Example
For-Else with break statement and if conditions
Example
While Loops
Python while Loop
Syntax of while Loop
Flowchart of While loop
Example 1
Example 2
Python Infinite while Loop
Example
Python while-else Loop
Flowchart of While loop with else Statement
Example
Single Statement Suites
Example
break Statement
Python break Statement
Syntax of break Statement
Flow Diagram of break Statement
break Statement with for loop
Example
break Statement with while loop
Example
break Statement with Nested Loops
Example
Continue Statement
Python continue Statement
Syntax of continue Statement
Flow Diagram of continue Statement
Python continue Statement with for Loop
Example
Python continue Statement with while Loop
Example: Checking Prime Factors
pass Statement
Python pass Statement
Syntax of pass Statement
Example of pass Statement
Dumpy Infinite Loop with pass Statement
Example
Using Ellipses (...) as pass Statement Alternative
Example
Nested Loops
Python Nested for Loop
Python Nested for Loop Syntax
Python Nested for Loop Example
Python Nested while Loop
Python Nested while Loop Syntax
Python Nested while Loop Example
Functions
Types of Python Functions
Defining a Python Function
Syntax to Define a Python Function
Example to Define a Python Function
Calling a Python Function
Example to Call a Python Function
Pass by Reference vs Value
Example
Example
Example
Python Function Arguments
Example
Types of Python Function Arguments
Positional or Required Arguments
Example
Keyword Arguments
Example 1
Example 2
Default Arguments
Example
Positional-only arguments
Example
Keyword-only arguments
Example
Arbitrary or Variable-length Arguments
Example
Order of Python Function Arguments
Python Function with Return Value
Example
The Anonymous Functions
Syntax
Example
Scope of Variables
Global vs. Local variables
Example
Default Arguments
Python Default Arguments
Example of Default Arguments
Example: Calling Function Without Keyword Arguments
Mutable Objects as Default Argument
Example
Keyword Arguments
Keyword Arguments
Calling Function With Keyword Arguments
Order of Keyword Arguments
Example
Example
Example
Keyword-Only Arguments
Keyword-Only Arguments
Example of Keyword-Only Arguments
Example: Using "sep" as non-keyword Argument
Using Keyword-Only argument in User-Defined Method
Example
Example
Positional Arguments
Positional Arguments
Positional Arguments Examples
Example 1
Example 2
Example 3
Example 4
Difference between Positional and Keyword argument
Positional-Only Arguments
Positional Only Arguments
Example
Positional-Only Arguments Examples
Example 1
Example 2
Example 3
Arbitrary or, Variable-length Arguments
Arbitrary Arguments (*args)
Arbitrary Arguments Example
Required Arguments With Arbitrary Arguments
Example
Arbitrary Keyword Arguments (**kwargs)
Example
Multiple Arguments With Arbitrary Keyword Arguments
Example
Python Variable Scope
Types of Scope for Variables in Python
Local Variables
Example
Global Variables
Example
Nonlocal Variables
Example
Namespace and Scope of Python Variables
Python globals() Function
Example
Python locals() Function
Example
Namespace Conflict in Python
Example
Example
Example
Example
Function Annotations
Function Annotations
Example
Function Annotations With Return Type
Example
Function Annotations With Expression
Example
Function Annotations With Default Arguments
Example 1
Example 2
Example 3
Example 4
Modules
Python Modules
Example of Python Module
Python Built-in Modules
Python User-defined Modules
Creating a Python Module
The import Statement
The from ... import Statement
The from...import * Statement
The import ... as Statement
Locating Modules
The PYTHONPATH Variable
Namespaces and Scoping
Example
Module Attributes
Example
The __name__Attribute
The dir( ) Function
The reload() Function
Packages in Python
Built-in Functions
Built-in Functions in Python?
How to Use Built-in Function in Python?
Example of Using Built-in Functions
List of Python Built-in Functions
Built-in Mathematical Functions
Advantages of Using Built-in Functions
Frequently Asked Questions about Built-in Functions
How do I handle errors with built-in functions?
Can we extend the functionality of built-in functions?
Can I create my built-in functions?
How do I use built-in functions?
Strings
Creating Python Strings
Example
Accessing Values in Strings
Updating Strings
Escape Characters
String Special Operators
String Formatting Operator
Double Quotes in Python Strings
Example
Triple Quotes
Example
Python Multiline Strings
Example
Arithmetic Operators with Strings
Getting Type of Python Strings
Example
Built-in String Methods
Built-in Functions with Strings
Python Slicing Strings
Python String Indexing
Example
Python String Negative & Positive Indexing
Example
Example
Python String Slicing
Example
Python String Slicing With Negative Indexing
Example
Default Values of Indexes with String Slicing
Example
Example
Example
Example
Return Type of String Slicing
Example
Modify Strings
Converting a String to a List
Example
Using the Array Module
Example
Using the StringIO Class
Example
String Concatenation
Concatenate Strings in Python
String Concatenation using '+' operator
Example
Concatenating String with space
Example
String Concatenation By Multiplying
Example
String Concatenation With '+' and '*' Operators
Example
String Formatting
Using % operator
Example
Using format() method
Example
Using f-string
Example
Using String Template class
Example
Escape Characters
Escape Character
Example
Example
Escape Characters in Python
Escape Characters Example
String Methods
Case Conversion Methods
Alignment Methods
Split and Join Methods
Boolean String Methods
Find and Replace Methods
Translation Methods
String Exercises
Example 1
Example 2
Example 3
Exercise Programs
Lists
Python Lists
Accessing Values in Lists
Updating Lists
Delete List Elements
Python List Operations
Indexing, Slicing, and Matrixes
Python List Methods
Built-in Functions with Lists
Access List Items
Access List Items
Accessing List Items with Indexing
Example
Access List Items with Negative Indexing
Example
Access List Items with Slice Operator
Example
Access Sub List from a List
Example
Change List Items
Change List Items
Syntax
Example
Change Consecutive List Items
Example
Change a Range of List Items
Example
Example
Add List Items
Add List Items
Adding List Items Using append() Method
Example
Adding List Items Using insert() Method
Example
Adding List Items Using extend() Method
Example
Remove List Items
Removing List Items
Remove List Item Using remove() Method
Example
Remove List Item Using pop() Method
Example
Remove List Item Using clear() Method
Example
Remove List Item Using del Keyword
Example
Example
Loop Lists
Loop Through List Items
Loop Through List Items with For Loop
Syntax
Example
Loop Through List Items with While Loop
Syntax
Example
Loop Through List Items with Index
Example
Iterate using List Comprehension
Example
Iterate using the enumerate() Function
Example
List Comprehension
List Comprehension in Python
Syntax of Python List Comprehension
Example of Python List Comprehension
List Comprehensions and Lambda
Example
Nested Loops in Python List Comprehension
Example
Conditionals in Python List Comprehension
Example
List Comprehensions vs For Loop
Example Using For Loop
Example Using List Comprehension
Example
Advantages of List Comprehension
Sort Lists
Sorting Lists in Python
Sorting Lists Using sort() Method
Syntax
Example of Sorting List in Lexicographical Order
Example of Sorting List in Numerical Order
Sorting Lists Using sorted() Method
Syntax
Example
Sorting List Items with Callback Function
Example Using str.lower() as key Parameter
Example Using user-defined Function as key Parameter
Copy Lists
Copying a List in Python
Shallow Copy on a Python List
Example of Shallow Copy
Deep Copy on a Python List
Example of Deep Copy
Copying List Using Slice Notation
Example
Copying List Using the list() Function
Example
Copying List Using the copy() Function
Example
Join Lists
Join Lists in Python
Join Lists Using Concatenation Operator
Example
Join Lists Using List Comprehension
Example
Join Lists Using append() Function
Example
Join Lists Using extend() Function
Example
List Methods
Python List Methods
Printing All the List Methods
Methods to Add Elements to a List
Methods to Remove Elements from a List
Methods to Access Elements in a List
Copying and Ordering Methods
List Exercises
Python List Exercise 1
Python List Exercise 2
Python List Exercise 3
Tuples
Accessing Values in Tuples
Updating Tuples
Delete Tuple Elements
Python Tuple Operations
Indexing, Slicing, and Matrixes
No Enclosing Delimiters
Built-in Functions with Tuples
Access Tuple Items
Access Tuple Items
Accessing Tuple Items with Indexing
Example
Accessing Tuple Items with Negative Indexing
Example
Accessing Range of Tuple Items with Negative Indexing
Example
Access Tuple Items with Slice Operator
Example
Accessing Sub Tuple from a Tuple
Example
Update Tuples
Updating Tuples in Python
Updating Tuples Using Concatenation Operator
Example
Updating Tuples Using Slicing
Example
Updating Tuples Using List Comprehension
Example
Updating Tuples Using append() function
Example
Unpack Tuple Items
Unpack Tuple Items
Example
ValueError While Unpacking a Tuple
Example
Unpack Tuple Items Using Asterisk (*)
Example 1
Example 2
Example 3
Loop Tuples
Loop Through Tuple Items
Loop Through Tuple Items with For Loop
Syntax
Example
Loop Through Tuple Items with While Loop
Syntax
Example
Loop Through Tuple Items with Index
Example
Join Tuples
Joining Tuples in Python
Joining Tuples Using Concatenation ("+") Operator
Example
Joining Tuples Using List Comprehension
Example
Joining Tuples Using extend() Function
Example
Join Tuples using sum() Function
Syntax
Example
Joining Tuples using for Loop
Example
Tuple Methods
Python Tuple Methods
Listing All the Tuple Methods
Finding the Index of a Tuple Item
Syntax
Return value
Example
Counting Tuple Items
Syntax
Return Value
Example
Example
Python Tuple Exercises
Python Tuple Exercise 1
Python Tuple Exercise 2
Python Tuple Exercise 3
Sets
Sets in Python
Creating a Set in Python
Using Curly Braces
Using the set() Function
Duplicate Elements in Set
Adding Elements in a Set
Removing Elements from a Set
Membership Testing in a Set
Set Operations
Python Set Comprehensions
Syntax
Example
Filtering Elements Using Set Comprehensions
Nested Set Comprehensions
Example
Frozen Sets
Example
Access Set Items
Access Set Items
Access Set Items Using For Loop
Example
Access Set Items Using List Comprehension
Example
Access Subset From a Set
Example
Checking if Set Item Exists
Example
Add Set Items
Add Set Items
Add Set Items Using the add() Method
Syntax
Example
Add Set Items Using the update() Method
Syntax
Example: Adding a Single Set Item
Example: Adding any Sequence Object as Set Items
Example
Add Set Items Using Union Operator
Example
Example
Add Set Items Using Set Comprehension
Example
Remove Set Items
Remove Set Items
Remove Set Item Using remove() Method
Example
Example
Remove Set Item Using discard() Method
Example
Remove Set Item Using pop() Method
Example
Example
Remove Set Item Using clear() Method
Example
Remove Items Existing in Both Sets
Example
Remove Items Existing in Either of the Sets
Example
Remove Uncommon Set Items
Example
The intersection() Method
Syntax
Return value
Example
Symmetric Difference Update of Set Items
Example
Symmetric Difference of Set Items
Example
Loop Sets
Loop Through Set Items
Loop Through Set Items with For Loop
Syntax
Example
Loop Through Set Items with While Loop
Example
Iterate using Set Comprehension
Example
Iterate through a Set Using the enumerate() Function
Example
Loop Through Set Items with add() Method
Example
Join Sets
Join Sets in Python
Join Python Sets Using "|" Operator
Example
Join Python Sets Using union() Method
Example
Join Python Sets Using update() Method
Example
Join Python Sets Using Unpacking Operator
Example
Join Python Sets Using Set Comprehension
Example
Join Python Sets Using Iterative Addition
Example
Copy Sets
Python Copy Sets
Copy Sets Using the copy() Method
Syntax
Return Value
Example
Copy Sets Using the set() Function
Example
Copy Sets Using Set Comprehension
Example
Set Operators
Set Operators in Python
Python Set Union Operator (|)
Example
Python Set Intersection Operator (&)
Example
Python Set Difference Operator (-)
Example
Python Set Symmetric Difference Operator
Example
Python Subset Testing Operation
Example
Set Methods
Understanding Set Methods
Python Set Methods
Adding and Removing Elements
Set Operations
Set Exercises
Python Set Exercise 1
Python Set Exercise 2
Python Set Exercise 3
Dictionaries
Dictionaries in Python
Key Features of Dictionaries
Example 1
Example 2
Example 3
Creating a Dictionary
Example
Accessing Dictionary Items
Modifying Dictionary Items
Removing Dictionary Items
Iterating Through a Dictionary
Properties of Dictionary Keys
Python Dictionary Operators
Python Dictionary Methods
Built-in Functions with Dictionaries
Access Dictionary Items
Access Dictionary Items
Access Dictionary Items Using Square Brackets []
Example 1
Example 2
Access Dictionary Items Using get() Method
Syntax
Example 1
Example 2
Example 3
Access Dictionary Keys
Example
Access Dictionary Values
Example 1
Example 2
Example 3
Access Dictionary Items Using the items() Function
Example
Change Dictionary Items
Change Dictionary Items
Modifying Dictionary Values
Example
Updating Multiple Dictionary Values
Example
Conditional Dictionary Modification
Example
Modify Dictionary by Adding New Key-Value Pairs
Example: Using Assignment Operator
Example: Using the setdefault() Method
Modify Dictionary by Removing Key-Value Pairs
Example: Using the del Statement
Example: Using the pop() Method
Example: Using the popitem() Method
Add Dictionary Items
Add Dictionary Items
Add Dictionary Item Using Square Brackets
Example
Add Dictionary Item Using the update() Method
Example
Add Dictionary Item Using Unpacking
Example
Add Dictionary Item Using the Union Operator (|)
Example
Add Dictionary Item Using the "|=" Operator
Example
Add Dictionary Item Using the setdefault() Method
Example
Add Dictionary Item Using the collections.defaultdict() Method
Example
Remove Dictionary Items
Remove Dictionary Items
Remove Dictionary Items Using del Keyword
Example 1
Example 2
Remove Dictionary Items Using pop() Method
Example
Remove Dictionary Items Using popitem() Method
Example
Remove Dictionary Items Using clear() Method
Example
Remove Dictionary Items Using Dictionary Comprehension
Example
Dictionary View Objects
The items() Method
Syntax
Return value
Example
The keys() Method
Syntax
Return value
Example
The values() Method
Syntax
Return value
Example
Loop Dictionaries
Loop Through Dictionaries
Loop Through Dictionary Using a For Loop
Example: Iterating over Keys
Example: Iterating over Key-Value Pairs
Loop Through Dictionary Using dict.items() Method
Example
Loop Through Dictionary Using dict.keys() Method
Example
Loop Through Dictionary Using dict.values() Method
Example
Copy Dictionaries
Copy Dictionaries
Shallow Copy
Example: Using the copy() Method
Example: Using the dict() Method
Deep Copy
Example
Copy Dictionaries Using copy() Method
Syntax
Example
Nested Dictionaries
Nested Dictionaries
Creating a Nested Dictionary in Python
Example: Direct Assignment
Example: Using a Loop
Adding Items to a Nested Dictionary in Python
Example
Accessing Items of a Nested Dictionary in Python
Example: Using Direct Indexing
Example: Using the get() Method
Deleting a Dictionary from a Nested Dictionary
Example
Iterating Through a Nested Dictionary in Python
Example
Dictionary Methods
Dictionary Methods
Dictionary Exercises
Dictionary Exercise 1
Dictionary Exercise 2
Dictionary Exercise 3
Dictionary Exercise Programs
Arrays
Arrays in Python
What are arrays?
Array Representation
Creating Array in Python
Syntax
Example
Basic Operations on Python Arrays
Accessing Array Element
Example
Insertion Operation
Example
Deletion Operation
Search Operation
Example
Update Operation
Example
Access Array Items
Accessing array items in Python
Using indexing
Example
Using iteration
Example
Using enumerate() function
Example
Accessing a range of array items in Python
Example
Add Array Items
Adding Elements to Python Array
Using append() method
Syntax
Example
Using insert() method
Syntax
Example
Using extend() method
Syntax
Example
Remove Array Items
Removing array items in Python
Remove First Occurrence
Syntax
Example
Remove Items from Specific Indices
Syntax
Example
Loop Arrays
Python for Loop with Array
Example
Python while Loop with Array
Example
Python for Loop with Array Index
Example
Copy Arrays
Copy Arrays Using Assignment Operator
Example
Copy Arrays Using Deep Copy
Example
Reverse Arrays
Ways to Reverse an Array in Python
Using slicing operation
Example
Reverse an Array Using reverse() Method
Example
Reverse an Array Using reversed() Method
Example
Using for Loop
Example
Sort Arrays
Sort Arrays Using a Sorting Algorithm
Example
Sort Arrays Using sort() Method of List
Example
Sort Arrays Using sorted() Method
Example
Join Arrays
Join two Arrays in Python
Using append() Method
Example: Join Two Arrays by Appending Elements
Using + operator
Example: Join Two Arrays by Converting to List Objects
Using extend() Method
Example: Join Two Arrays using extend() Method
Array Methods
Python Array Class
Adding and Removing Elements
Information and Utility Methods
Manipulating Array Elements
Conversion Methods
Array Exercises
Example 1
Example 2
Example 3
Exercise Programs
File Handling
File Handling in Python
Opening a File in Python
File Opening Modes
Example 1
Example 2
Reading a File in Python
Example: Using read() method
Example: Using readline() method
Example: Using readlines() method
Writing to a File in Python
Example: Using the write() method
Example: Using the writelines() method
Closing a File in Python
Example
Using "with" Statement for Automatic File Closing
Example
Handling Exceptions When Closing a File
Write to File
Opening a File for Writing
The open() Function
File Modes for Writing
Writing to a File Using write() Method
Example
Writing to a File Using writelines() Method
Example
Writing to a New File
Example
Writing to a New File in Binary Mode
Writing Binary Data to a File
Converting Text Strings to Bytes
Writing to an Existing File
Example
Writing to a File in Reading and Writing Modes
Using the seek() Method
Read Files
Opening a File for Reading
Reading a File Using read() Method
Syntax
Example
Reading a File Using readline() Method
Syntax
Example
Reading a File Using readlines() Method
Syntax
Example
Using "with" Statement
Example
Reading a File in Binary Mode
Writing to a Binary File
Example
Reading Integer Data From a File
Writing an Integer to a Binary File
Reading an Integer from a Binary File
Reading Float Data From a File
Writing a Float to a Binary File
Reading Float Numbers from a Binary File
Reading and Writing to a File Using "r+" Mode
Syntax
Parameters
Example
Reading and Writing to a File Simultaneously in Python
Example
Reading a File from Specific Offset
Example
Renaming and Deleting Files
Renaming and Deleting Files in Python
Renaming Files in Python
Syntax
Parameters
Example
Deleting Files in Python
Syntax
Parameters
Example
Directories
Directories in Python
Checking if a Directory Exists
Example
Creating a Directory
Example
The mkdir() Method
Example
Get Current Working Directory
Syntax
Example
Listing Files and Directories
Example
Changing the Current Working Directory
Syntax
Example
Removing a Directory
Syntax
Example
File Methods
Python OS File/Directory Methods
Python OS.Path Method
OOP Concepts
Procedural Oriented Approach
Python - OOP Concepts
Attributes
Behaviour
Principles of OOPs Concepts
Class & Object
Example
Encapsulation
Example
Inheritance
Syntax
Example
Polymorphism
Example
Base Overloading Methods in Python
Overloading Operators in Python
Classes and Objects
What is a Class in Python?
Creating Classes in Python
Example
What is an Object?
Creating Objects of Classes in Python
Accessing Attributes of Objects in Python
Built-In Class Attributes in Python
Example
Built-in Class of Python data types
Example
Garbage Collection(Destroying Objects) in Python
Example
Data Hiding in Python
Example
Class Attributes
Class Attributes (Variables)
Accessing Class Attributes
Example
Output
Modifying Class Attributes
Example
Output
Significance of Class Attributes
Built-In Class Attributes
Access Built-In Class Attributes
Example
Output
Instance Attributes
Example
Output
Instance Attributes Vs Class Attributes
Class Methods
Creating Class Methods in Python
Using classmethod() Function
Syntax
Example
Output
Using @classmethod Decorator
Syntax
Example
Access Class Attributes in Class Method
Example
Dynamically Add Class Method to a Class
Example
Dynamically Delete Class Methods
Example
Static Methods
What is the Python Static Method?
How to Create a Static Method in Python?
Using staticmethod() Function
Syntax
Example
Using @staticmethod Decorator
Syntax
Example
Advantages of Static Method
Constructors
Creating a constructor in Python
Types of Constructor in Python
Default Constructor in Python
Example
Parameterized Constructor
Example
Python - Instance Methods
Example
Python Multiple Constructors
Example
Access Modifiers
Access Modifiers in Python
Example
Another Example
Name Mangling
Python Property Object
Syntax
Parameters
Getters and Setter Methods
Example
Example
Inheritance
What is Inheritance in Python?
Creating a Parent Class
Syntax
Creating a Child Class
Syntax
Types of Inheritance
Python - Single Inheritance
Example
Python - Multiple Inheritance
Syntax
Example
Output
Method Resolution Order (MRO)
Python - Multilevel Inheritance
Example
Python - Hierarchical Inheritance
Example
Python - Hybrid Inheritance
Example
The super() function
Example
Polymorphism
What is Polymorphism in Python?
Ways of implementing Polymorphism in Python
Duck Typing in Python
Example
Method Overriding in Python
Example
Output
Overloading Operators in Python
Example
Method Overloading in Python
Example
Method Overriding
Method Overriding in Python
Example
Example
Base Overridable Methods
Method Overloading
Method Overloading in Python
Example
Example
Implement Method Overloading Using MultipleDispatch
Example
Output
Dynamic Binding
Example
Duck Typing
Dynamic Typing
Why is Python Called Dynamically Typed?
Abstraction
Types of Python Abstraction
Python Abstract Class
Create an Abstract Class
Example: Create an Abstract Class
Abstract Method Overriding
Example
Output
Encapsulation
Implementing Encapsulation in Python
Example 1
Example 2
What is Name Mangling?
Interfaces
Interfaces in Python
Rules for implementing Python Interfaces
Ways to implement Interfaces in Python
Formal Interface
Example
Output
Informal Interface
Example
Output
Packages
Create a Python Package
Example to Create a Python Package
Define Package List
Example to Define a Package List
Package Installation
Inner Classes
Inner Class in Python
Syntax
Example
Types of Inner Class
Multiple Inner Class
Example
Multilevel Inner Class
Example
Anonymous Class and Objects
Example
Syntax
Create an Anonymous Class
Create an Anonymous Object
Anonymous Class and Object Example
Singleton Class
Creating Singleton Classes in Python
Using __init__
Example
Using __new__
Example
Wrapper Classes
Example
Enums
Enums in Python
Example
Example
Example
Accessing Modes in Enums
Example
Iterating through Enums
Example
Reflection
The type() Function
Example
The isinstance() Function
Syntax
Example
The issubclass() Function
The callable() Function
Example
The getattr() Function
Example
The setattr() Function
The hasattr() Function
The dir() Function
Example
Example
Example
Syntax Errors
Python Syntax Errors
What is a Syntax Error?
Common Causes of Syntax Errors
How to Identify Syntax Errors
Reading Error Messages
Using an Integrated Development Environment (IDE)
Running Code in Small Chunks
Using Version Control
Fixing Syntax Errors
Read the Error Message Carefully
Locate the Error
Understand the Nature of the Error
Correct the Syntax
Exceptions Handling
Exception Handling in Python
Assertions in Python
The assert Statement
What is an Exception?
Handling an Exception in Python
Syntax
Example
Example
The except Clause with No Exceptions
The except Clause with Multiple Exceptions
The try-finally Clause
Example
Argument of an Exception
Example
Raising an Exceptions
Syntax
Example
User-Defined Exceptions
Standard Exceptions
The try-except Block
Python Try-Except Block
Syntax
Example
Handling Multiple Exceptions
Syntax
Example
Using Else Clause with Try-Except Block
Syntax
Example
The Finally Clause
Syntax
Example
The try-finally Block
Python Try-Finally Block
Syntax
Example
Exception with Arguments
Example
Raising Exceptions
Raising Exceptions in Python
Raising Built-in Exceptions
Example
Raising Custom Exceptions
Creating Custom Exceptions
Example
Re-Raising Exceptions
Example
Exception Chaining
Exception Chaining
Example
The raise . . from Statement
The raise . . from None Statement
The __context__ and __cause__ Expression
Nested try Block
Nested try Block in Python
Example 1
Example 2
Example 3
Example 4
User-Defined Exceptions
User-Defined Exceptions in Python
How to Create a User-Defined Exception
Step 1 − Define the Exception Class
Step 2 − Initialise the Exception
Step 3 − Optionally Override "__str__" or "__repr__"
Raising User-Defined Exceptions
Syntax
Example
Handling User-Defined Exceptions
Syntax
Example
Complete Example
Logging
Logging in Python
Benefits of Logging
Components of Python Logging
Logging Levels
Usage
Basic Logging Example
Output
Configuring Logging
Example
Logging Handlers
Types of Logging Handlers
Assertions
Assertions in Python
The assert Statement
Using Assertions
Example
Custom Error Messages
Handling AssertionError
Assertions vs. Exceptions
Built-in Exceptions
Standard Built-in Exceptions in Python
IndexError
ModuleNotFoundError
KeyError
ImportError
StopIteration
TypeError
ValueError
NameError
ZeroDivisionError
KeyboardInterrupt
Hierarchy of Built-in Exceptions
How to Use Built-in Exceptions
Handling Exceptions with try-except Blocks
Handling Multiple Exceptions
Using "else" and "finally" Blocks
Explicitly Raising Built-in Exceptions
Syntax
Example
Multithreading
Comparison with Processes
Thread Handling Modules in Python
The _thread Module
The threading Module
Starting a New Thread
Starting a New Thread Using the _thread Module
Starting a New Thread Using the Threading Module
Synchronising Threads
Example
Multithreaded Priority Queue
Example
Thread Life cycle
States of a Thread Life Cycle in Python
Example: Python Thread Life Cycle Demonstration
Example: Using a Synchronisation Primitive
Creating a Thread
Creating Threads with Functions
Example
Creating Threads by Extending the Thread Class
Example
Creating Threads using start_new_thread() Function
Example
Starting a Thread
Starting a Thread in Python
Example
Example
Joining the Threads
Joining the Threads in Python
Example
Example
Naming the Threads
Naming the Threads in Python
Example
Dynamically Assigning Names to the Python Threads
Example
Example
Thread Scheduling
Scheduling Threads using the Timer Class
Example
Scheduling Threads using the sched Module
Key Classes and Methods of the sched Module
Example
Example
Thread Pools
What is a Thread Pool?
Using Python ThreadPool Class
Example
Using Python ThreadPoolExecutor Class
The Future Class
The ThreadPoolExecutor Class
Example
Main Thread
Accessing the Main Thread
Example
Example
Main Thread Behaviour in Python
Example
Main Thread Waiting for Other Threads
Example
Thread Priority
Setting the Thread Priority Using Sleep()
Example
Adjusting Python Thread Priority on Windows
Example
Prioritising Python Threads Using the Queue Module
Example
Daemon Threads
Overview of Daemon Threads
Difference Between Daemon & Non-Daemon Threads
Creating a Daemon Thread in Python
Example
Example
Managing the Daemon Thread Attribute
Example
Synchronising Threads
Thread Synchronisation using Locks
Example
Output
Condition Objects for Synchronizing Python Threads
Example
Output
Synchronising threads using the join() Method
Example
Output
Additional Synchronisation Primitives
Inter-Thread Communication
The Event Object
Example
Output
The Condition Object
Example
Example
Thread Deadlock
How to Avoid Deadlocks in Python Threads
Locking Mechanism with the Lock Object
The acquire() Method
The release() Method
Example
Semaphore Object for Synchronisation
The acquire() Method
The release() Method
Interrupting a Thread
Thread Interruption using Event Object
Example
Thread Interruption using a Flag
Example
Network Programming
Socket Programming
Python Socket Programming
What are Sockets?
Python socket Module
Syntax
Parameters
Return Type
Server Socket Methods
Client Socket Methods
connect() method
send() method
sendall() method
sendto() method
recv() method
recvfrom() method
Python - Socket Server
Example of Server Socket
Python - Socket Client
Example of Client Socket
Python File Transfer with Socket Module
Server Code
Client Code
The Python socketserver Module
Server Code
Client Code
URL Processing
The urllib.parse Module
urlparse(urlstring)
Example
parse_qs(qs))
urlsplit(urlstring)
urlunparse(parts)
Example
urlunsplit(parts)
The urllib.request Module
urlopen() function
Example
The Request Object
Syntax
Parameters
Example
Sending Data
Sending Headers
The urllib.error Module
URLError
HTTPError
Generics
Defining a Generic Function
Calling the Generic Function with Different Data Types
Defining a Generic Class
Python Miscellaneous
Date and Time
What are Tick Intervals
Example
What is TimeTuple?
Getting the Current Time
Getting the Formatted Time
Getting the Calendar for a Month
The time Module
The calendar Module
Python datetime Module
Python date Object
Syntax
Example
date class attributes
Example
Class Methods in Date Class
Example
Instance Methods in Date Class
Example
Python time Module
Syntax
Example
Class attributes
Example
Instance attributes
Example
Instance Methods of time Object
Python datetime object
Syntax
Example
Class attributes
Example
Instance Attributes of datetime Object
Example
Class Methods of datetime Object
Instance Methods of datetime Object
Example
Python timedelta Object
Syntax
Example
Example
Class Attributes of timedelta Object
Example
Instance Attributes of timedelta Object
Instance Methods of timedelta Object
Example
maths Module
Python maths Module
Importing maths Module
Methods of Python maths Module
Math Module - Theoretic and Representation Methods
Math Module - Power and Logarithmic Methods
Math Module - Trigonometric Methods
Math Module - Angular conversion Methods
Math Module - Mathematical Constants
Math Module - Hyperbolic Methods
Math Module - Special Methods
Example Usage
Iterators
Python Iterators
Iterables vs Iterators
Example of Python Iterator
Error Handling in Iterators
Example
Custom Iterator
Example
Example
Asynchronous Iterator
Example
Output
Generators
Python Generators
Syntax
Creating Generators
Using Generator Functions
Using Generator Expressions
Exception Handling in Generators
Output
Normal function vs Generator function
Example
Output
Example
Asynchronous Generator
Syntax
Example
Output
Example
Output
Closures
What is a Closure?
Nested Functions
Example
Output
Output
Variable Scope
Example
Output
Creating a closure
Example
Output
nonlocal Keyword
Output
Decorators
Defining Function Decorator
Examples of Python Decorators
Example 1
Example 2
@classmethod Decorator
Syntax
Example of @classmethod Decorator
@staticmethod Decorator
Syntax
Example of @staticmethod Decorator
@property Decorator
Syntax
Example of @property Decorator
Recursion
Components of Recursion
Base Case
Recursive Case
Binary Search using Recursion
Example
Output
Regular Expressions
Raw Strings
Metacharacters
The re.match() Function
Example
The re.search() Function
Example
Matching Vs Searching
Example
The re.findall() Function
Syntax
Parameters
Example
The re.sub() Function
Syntax
Example
Example
The re.compile() Function
Syntax
Flags
Example
The re.finditer() Function
Syntax
Example
Use Cases of Python Regex
Finding all Adverbs
Finding words starting with vowels
Regular Expression Modifiers: Option Flags
Regular Expression Patterns
Regular Expression Examples
Literal characters
Character classes
Special Character Classes
Repetition Cases
Nongreedy repetition
Grouping with Parentheses
Backreferences
Alternatives
Anchors
Special Syntax with Parentheses
PIP
Pip in Python
Installing pip
Installing Packages with pip
Syntax
Example
Example: Specifying Versions
Example: Installing Multiple Packages
Upgrading Packages
Syntax
Example
Listing Installed Packages
Detailed Information
Outdated Packages
Uninstalling Packages
Uninstalling a Single Package
Uninstalling Multiple Packages
Freezing Installed Packages
Using "pip freeze"
Using a requirements.txt File
Creating requirements.txt
Installing from requirements.txt
Using Virtual Environments
Creating a Virtual Environment
Activating the Virtual Environment
Deactivating the Virtual Environment
Deleting the Virtual Environment
Database Access
Database Access in Python
DB-API (Database API)
Using SQLite with Python
Working with SQLite
The sqlite3 Module
The Connection Object
The Cursor Object
Creating a Database Table
INSERT Operation
Example
READ Operation
Example
Update Operation
DELETE Operation
Performing Transactions
Example
COMMIT Operation
ROLLBACK Operation
The PyMySQL Module
Installing PyMySQL
MySQL Database Connection
Example
Handling Errors
Weak References
Example
The callback Function
Finalising Objects
WeakKeyDictionary
Example
WeakValueDictionary
Example
Serialisation
Serialisation in Python
Why Do We Use Serialization?
Serialization Libraries in Python
Serialisation Using Pickle Module
Serialising an Object
Deserializing an Object
Pickle Protocols
Pickler and Unpickler Classes
Using the Pickler Class
Using the Unpickler Class
Pickling Custom Class Objects
Example
Using JSON for Serialization
Serialisation
Deserialization
Using YAML for Serialization
Example: Serialize Data and Write to a YAML File
Example: Deserialize Data from a YAML File
Templating
Templating in Python
String Templates in Python
Creating a Template
Substituting Values
Substituting Values Using safe_substitute() Method
Installing Jinja2
Creating and Rendering Jinja2 Templates
Creating a Jinja2 Template
Rendering a Jinja2 Template
Advanced Jinja2 Features
Template Inheritance
Loops
Conditionals
Custom Filters
Output Formatting
Output Formatting in Python
Using String Modulo Operator (%)
Using the format() Method
Syntax
Return Value
Example
Using F-Strings
Example
Format Conversion Rule in Python
Template Strings
Example
The textwrap Module
textwrap.wrap(text, width=70)
textwrap.fill(text, width=70)
Example
The shorten() Function
Example
The pprint Module
PrettyPrinter Class
Syntax
Parameters
pprint() method
pformat() method
Example
Example Using pformat() Method
Example
Performance Measurement
Syntax
Parameters
Example
Output
Data Compression
CGI Programming
What is CGI?
Web Browsing
CGI Architecture Diagram
Web Server Support and Configuration
First CGI Program
Hello Word! This is my first CGI program
HTTP Header
CGI Environment Variables
GET and POST Methods
Passing Information using GET method
Simple URL Example:Get Method
Hello Malhar Lathkar
Simple FORM Example:GET Method
Passing Information Using POST Method
Passing Checkbox Data to CGI Program
Passing Radio Button Data to CGI Program
Passing Textarea Data to CGI Program
Passing Drop Down Box Data to CGI Program
Using Cookies in CGI
How Does It Work?
Setting up Cookies
Retrieving Cookies
File Upload Example
How To Raise a "File Download" Dialog Box?
XML Processing
What is XML?
XML Parser Architectures and APIs.
Parsing XML with SAX APIs
The make_parser Method
The parse Method
The parseString Method
Example
Parsing XML with DOM APIs
ElementTree XML API
Create an XML File
Example
Parse an XML File
Example
Modify an XML file
GUI Programming
Tkinter Programming
Example
Tkinter Widgets
Standard Attributes
Geometry Management
SimpleDialog
askinteger
askfloat
askstring
The FileDialog Module
askopenfile
ColorChooser
ttk module
Combobox Widget
Syntax
Example
Progressbar
Syntax
Parameters
Example
Notebook
Syntax
Example
Treeview
Syntax
Options
Example
The Complete Code
Sizegrip
Syntax
Example
Separator
Syntax
Example
Command-Line Arguments
Python Command Line Arguments
Example
Passing Arguments at the Time of Execution
Example
Example
Python getopt Module
getopt.getopt() method
Exception getopt.GetoptError
Python argparse Module
The add_argument() method
Command-Line Arguments
Python Command Line Arguments
Example
Passing Arguments at the Time of Execution
Example
Example
Python getopt Module
getopt.getopt() method
Exception getopt.GetoptError
Python argparse Module
The add_argument() method
Docstrings
Docstrings in Python
Single-Line Docstrings
Example
Multi-Line Docstrings
Example
Docstrings for Modules
Example
Docstrings for Classes
Example
Accessing Docstrings
Example
Best Practices for Writing Docstrings
Google Style Docstring
Example
NumPy/SciPy Style Docstring
Example
Sphinx Style Docstring
Example
Docstring vs Comment
JSON
JSON in Python
JSON Serialization
Example
JSON Deserialization
Example: Deserialize JSON string to Python object
Example: Deserialize JSON from File
Advanced JSON Handling
Example
JSONEncoder Class
Example
JSONDecoder class
Example
Sending Email
Sending Email in Python
Python smtplib.SMTP() Function
Setting Up an SMTP Server
Creating an SMTP Object
The Python smtpd Module
Setting Up an SMTP Debugging Server
Starting the SMTP Debugging Server
Sending an HTML email using Python
Constructing the HTML Email Message
Sending Attachments as an E-mail
Constructing an Email with Attachments
Sending Email Using Gmail's SMTP Server
Example
Further Extensions
Prerequisites for Writing Extensions
First look at a Python Extension
The Header File Python.h
The C Functions
The Method Mapping Table
Example
The Initialization Function
Example
Building and Installing Extensions
Importing Extensions
Passing Function Parameters
The PyArg_ParseTuple Function
Returning Values
The Py_BuildValue Function
Tools/Utilities
The dis Module
Example
The pdb Module
Example
The profile Module
Example
The tabnanny Module
Example
GUIs
IDLE
Jupyter Notebook
VS Code
PyCharm
Abstract Base Classes
Purpose of Abstract Base Classes
Defining a Standard Interface
Enforcing Implementation
Providing a Template for Future Development
Facilitating Polymorphism
Components of Abstract Base Classes
Example of Abstract Base Classes in Python
Output
Custom Exceptions
What are Custom Exceptions in Python?
Why to Use Custom Exceptions?
Creating Custom Exceptions
Define the Custom Exception Class
Raise the Custom Exception
Handle the Custom Exception
Example of Custom Exception
Output
Higher Order Functions
What is a Higher-Order Function?
Creating Higher Order Function with Nested Scopes
Example
Creating Higher-Order Functions with Callable Objects
Example
Higher-order functions with the 'functools' Module
Working with Higher-order functions using the wraps()
Working with Higher-order functions using the partial()
Working with Higher-order functions using the reduce()
Object Internals
Object Structure
Object Identity
Example
Object Type
Example
Object Value
Example
Memory Management
Example
Attributes and Methods
Example
Memory Management
Memory Management Components
Memory Allocation in Python
Stack − Static Memory Allocation
Heap − Dynamic Memory Allocation
Garbage Collection in Python
Reference Counting
Metaclasses
Creating Metaclasses in Python
Example
Creating Metaclasses Dynamically
Example
Example
Customising Metaclass Creation
Example
Example
Metaprogramming with Metaclasses
Defining Metaclasses
Example
Dynamic Code Generation with Metaclasses
Example
Reflection and Metaprogramming
Example
Mocking and Stubbing
Python Mocking
Key Characteristics of Mocking
Example of Python Mocking
Python Stubbing
Key Characteristics of Stubbing
Example of Python Stubbing
Python Mocking Vs. Stubbing
Monkey Patching
Steps to Perform Monkey Patching
Example of Monkey Patching
Define a Class or Module to Patch
Create a Patching Function or Method
Test the Monkey Patch
Drawbacks of Monkey Patching
Signal Handling
Commonly Used Signals
Setting a Signal Handler
Example
Signal Handling on Windows
Handling Timers and Alarms
Example
Getting Signal Names from Numbers
Example
Type Hints
Basic Data Types
Example
Collections Types
Example
Optional Types
Example
Union Types
Example
Any Type
Example
Type Aliases
Example
Generic Types
Example
Callable Types
Example
Literal Types
Example
NewType
Example
Automation Tutorial
Automation using Python
Python Libraries for Automation
Python Automation with "schedule" Module
Example
Python Web Scraping
Example
Automating Mouse Movements with "pyautogui"
Example
Automating Unit Testing in Python
Example
Humanize Package
Installation of Humanize Package
Different Utilities in Humanize Package
Number Utilities
Integer Formatting
Integer Word Representation
Ordinal Numbers
AP Numbers
Fractional Units
File Size Utilities
File Size Formatting using naturalsize()
Date Time Utilities
Natural Time
Natural Date
Natural Day
Precise Delta
Duration Utilities
Duration Formatting using natural delta()
Context Managers
How Context Managers Work?
Example
Python Context Manager Types
Synchronous Context Managers
Asynchronous Context Managers
Creating Custom Context Managers
Using the contextlib.contextmanager() Function
Using the contextlib.asynccontextmanager() Function
Coroutines
Key Characteristics of Coroutines
Subroutines Vs. Coroutines
Execution of Coroutines
Example of Basic Coroutine
Closing a Coroutine
Example
Chaining Coroutines for Pipelines
Example
Descriptors
Python Descriptors
How Python Descriptors Work?
Descriptor Methods
1. The __get__() Method
2. The __set__() Method
3. The __delete__() Method
Types of Python Descriptors
1. Data Descriptors
2. Non-data Descriptors
Data Descriptors Vs. Non-data Descriptors
Diagnosing and Fixing Memory Leaks
Causes of Memory Leaks in Python
1. Unreleased References
2. Circular References
3. Global Variables
4. Long-Lived Objects
5. Improper Use of Closures
Tools for Diagnosing Memory Leaks
1. Using the "gc" Module
2. Using "tracemalloc"
3. Using "memory_profiler"
Fixing Memory Leaks
Immutable Data Structures
Different Immutable Data Structures in Python
Tuples
Creating Tuples
Understanding Tuple Immutability in Python
Strings
Creating Strings
Understanding String Immutability in Python
Frozen Sets
Creating Frozen Sets
Understanding Frozen Sets Immutability in Python
Named Tuples
Creating Named Tuples
Understanding Named Tuples Immutability in Python
Overview
Python is a high-level, interpreted, interactive and object-oriented
scripting language. Python is designed to be highly readable. It uses
English words frequently whereas other languages use punctuation,
and it has fewer syntactic constructions than other languages.
1. Python is Interpreted − Python is processed at runtime by
the interpreter. You do not need to compile your program
before executing it. This is similar to PERL and PHP.
2. Python is Interactive − You can actually sit at a Python
prompt and interact with the interpreter directly to write your
programs.
3. Python is Object-Oriented − Python supports Object-
Oriented style or technique of programming that encapsulates
code within objects.
4. Python is a Beginner's Language − Python is a great
language for the beginner-level programmers and supports
the development of a wide range of applications from simple
text processing to WWW browsers to games.
Python 0.9.0
Python's first published version is 0.9. It was released in February 1991.
It consisted of features such as classes with inheritance, exception
handling, and core data types like lists and dictionaries..
Python 1.0
In January 1994, version 1.0 was released, armed with functional
programming tools, features like support for complex numbers etc and
module system which allows a better code organisation and reuse.
Python 2.0
Next major version − Python 2.0, was launched in October 2000. Many
new features such as list comprehension, garbage collection and
Unicode support were included with it. Throughout the 2000s, Python
2.x became the dominant version, gaining traction in industries ranging
from web development to scientific research. Various useful libraries
like NumPy, SciPy, and Django were also developed.
Python 3.0
Python 3.0, a completely revamped version of Python was released in
December 2008. The primary objective of this revamp was to remove a
lot of discrepancies that had crept in Python 2.x versions. Python 3 was
backported to Python 2.6. It also included a utility named python 2to3
to facilitate automatic translation of Python 2 code to Python 3. Python
3 provided new syntax, unicode support and Improved integer division.
Features
Python is a feature-rich, high-level, interpreted, interactive, and object-
oriented scripting language. Python is a versatile and very popular
programming language due to its features such as readability,
simplicity, extensive libraries, and many more. In this tutorial, we will
learn about the various features of Python that make it a powerful and
versatile programming language.
Easy to Learn
This is one of the most important reasons for the popularity of Python.
Python has a limited set of keywords. Its features such as simple
syntax, usage of indentation to avoid clutter of curly brackets and
dynamic typing that doesn't necessitate prior declaration of variables
help a beginner to learn Python quickly and easily.
Dynamically Typed
Python is a dynamically typed programming language. In Python, you
don't need to specify the variable time at the time of the variable
declaration. The types are specified at the runtime based on the
assigned value due to its dynamically typed feature.
Interpreter Based
Instructions in any programming language must be translated into
machine code for the processor to execute them. Programming
languages are either compiler based or interpreter based.
In case of a compiler, a machine language version of the entire source
program is generated. The conversion fails even if there is a single
erroneous statement. Hence, the development process is tedious for
the beginners. The C family languages (including C, C++, Java, C# etc)
are compiler based.
Python is an interpreter based language. The interpreter takes one
instruction from the source code at a time, translates it into machine
code and executes it. Instructions before the first occurrence of error
are executed. With this feature, it is easier to debug the program and
thus proves useful for the beginner level programmer to gain
confidence gradually. Python therefore is a beginner-friendly language.
Interactive
Standard Python distribution comes with an interactive shell that works
on the principle of REPL (Read – Evaluate – Print – Loop). The shell
presents a Python prompt >>>. You can type any valid Python
expression and press Enter. The Python interpreter immediately returns
the response and the prompt comes back to read the next expression.
>>> 2*3+1
7
>>> print ("Hello World")
Hello World
Multi-paradigm
Python is a completely object-oriented language. Everything in a
Python program is an object. However, Python conveniently
encapsulates its object orientation to be used as an imperative or
procedural language – such as C. Python also provides certain
functionality that resembles functional programming. Moreover, certain
third-party tools have been developed to support other programming
paradigms such as aspect-oriented and logic programming.
Standard Library
Even though it has a very few keywords (only Thirty Five), Python
software is distributed with a standard library made of a large number
of modules and packages. Thus Python has out of box support for
programming needs such as serialisation, data compression, internet
data handling, and many more. Python is known for its batteries
included approach.
Some of the Python's popular modules are:
1. NumPy
2. Pandas
3. Matplotlib
4. Tkinter
5. Maths
GUI Applications
Python's standard distribution has an excellent graphics library called
TKinter. It is a Python port for the vastly popular GUI toolkit called
TCL/Tk. You can build attractive user-friendly GUI applications in Python.
GUI toolkits are generally written in C/C++. Many of them have been
ported to Python. Examples are PyQt, WxWidgets, SimpleGUI etc.
Database Connectivity
Almost any type of database can be used as a backend with the Python
application. DB-API is a set of specifications for database driver
software to let Python communicate with a relational database. With
many third party libraries, Python can also work with NoSQL databases
such as MongoDB.
Extensible
The term extensibility implies the ability to add new features or modify
existing features. As stated earlier, CPython (which is Python's
reference implementation) is written in C. Hence one can easily write
modules/libraries in C and incorporate them in the standard library.
There are other implementations of Python such as Jython (written in
Java) and IPython (written in C#). Hence, it is possible to write and
merge new functionality in these implementations with Java and C#
respectively.
Python vs C++
Python is a general-purpose, high-level programming language. Python
is used for web development, Machine Learning, and other cutting-
edge software development. Python is suitable for both new and
seasoned C++ and Java programmers. Guido Van Rossam created
Python in 1989 at Netherlands' National Research Institute. Python was
released in 1991.
C++ is a middle-level, case-sensitive, object-oriented programming
language. Bjarne Stroustrup created C++ at Bell Labs. C++ is a
platform-independent programming language that works on Windows,
Mac OS, and Linux. C++ is close to hardware, allowing low-level
programming. This provides a developer control over memory,
improved performance, and dependable software.
Read through this article to get an overview of C++ and Python and
how these two programming languages are different from each other.
What is Python?
Python is currently one of the most widely used programming
languages. It is an interpreted programming language that operates at
a high level. When compared to other languages, the learning curve for
Python is much lower, and it is also quite straightforward to use.
Python is the programming language of choice for professionals
working in fields such as Artificial Intelligence, Machine Learning (ML),
Data Science, the Internet of Things (IoT), etc., because it excels at
both scripting applications and as standalone programmes.
In addition to this, Python is the language of choice because it is easy
to learn. Because of its excellent syntax and readability, the amount of
money spent on maintenance is decreased. The modularity of the
programme and the reusability of the code both contribute to its
support for a variety of packages and modules.
Using Python, we can perform −
1. Web development
2. Data analysis and machine learning
3. Automation and scripting
4. Software testing and many more
Features
Here is a list of some of the important features of Python −
1. Easy to learn − Python has a simple structure, few
keywords, and a clear syntax. This makes it easy for the
student to learn quickly. Code written in Python is easier to
read and understand.
2. Easy to maintain − The source code for Python is pretty
easy to keep up with.
3. A large standard library − Most of Python's library is easy
to move around and works on UNIX, Windows, Mac.
4. Portable − Python can run on a wide range of hardware
platforms, and all of them have the same interface.
Python Example
Take a look at the following simple Python program −
a = int(input("Enter value for a"))
b = int(input("Enter value for b"))
print("The number you have entered for a is ", a)
print("The number you have entered for b is ", b)
In our example, we have taken two variables "a" and "b" and assigned
some value to those variables. Note that in Python, we don’t need to
declare data type for variables explicitly, as the PVM will assign data
type as per the user’s input.
1. The input() function is used to take input from the user
through the keyboard.
2. In Python, the return type of input() is string only, so we
have to convert it explicitly to the type of data which we
require. In our example, we have converted to int type
explicitly through int( ) function.
3. print() is used to display the output.
Output
On execution, this Python code will produce the following output −
Enter value for a 10
Enter value for b 20
The number you have entered for a is 10
The number you have entered for b is 20
What is C++?
C++ is a statically typed, compiled, multi-paradigm, general-purpose
programming language with a steep learning curve. Video games,
desktop apps, and embedded systems use it extensively. C++ is so
compatible with C that it can build practically all C source code without
any changes. Object-oriented programming makes C++ a better-
structured and safer language than C.
Features
Let’s see some features of C++ and the reason for its popularity.
1. Middle-level language − It's a middle-level language since
it can be used for both systems development and large-scale
consumer applications like Media Players, Photoshop, Game
Engines, etc.
2. Execution Speed − C++ code runs quickly. Because it's
compiled and uses procedures extensively. Garbage
collection, dynamic typing, and other modern features impede
program execution.
3. Object-oriented language − Object-oriented programming
is flexible and manageable. Large apps are possible. Growing
code makes procedural code harder to handle. C++'s key
advantage over C.
4. Extensive Library Support − C++ has a vast library. Third-
party libraries are supported for fast development.
C++ Example
Let’s understand the syntax of C++ through an example written below.
#include
using namespace std;
int main() {
int a, b;
cout << "Enter The value for variable a \n";
cin >> a;
cout << "Enter The value for variable b";
cin >> b;
cout << "The value of a is "<< a << "and" << b;
return 0;
}
In our example, we are taking input for two variables "a" and "b" from
the user through the keyboard and displaying the data on the console.
Output
On execution, it will produce the following output −
Enter The value for variable a
10
Enter The value for variable b
20
The value of a is 10 and 20
Compiled vs Interpreted
Like C, C++ is also a compiler-based language. A compiler translates
the entire code in a machine language code specific to the operating
system in use and processor architecture.
Python is an interpreter-based language. The interpreter executes the
source code line by line.
Cross platform
When a C++ source code such as hello.cpp is compiled on Linux, it can
be only run on any other computer with Linux operating system. If
required to run on another OS, it needs to be compiled.
Python interpreter doesn't produce compiled code. Source code is
converted to byte code every time it is run on any operating system
without any changes or additional steps.
Portability
Python code is easily portable from one OS to another. C++ code is not
portable as it must be recompiled if the OS changes.
Speed of Development
C++ program is compiled to the machine code. Hence, its execution is
faster than interpreter based language.
Python interpreter doesn't generate the machine code. Conversion of
intermediate bytecode to machine language is done on each execution
of the program.
If a program is to be used frequently, C++ is more efficient than
Python.
Easy to Learn
Compared to C++, Python has a simpler syntax. Its code is more
readable. Writing C++ code seems daunting in the beginning because
of complicated syntax rules such as use of curly braces and semicolon
for sentence termination.
Python doesn't use curly brackets for marking a block of statements.
Instead, it uses indents. Statements of similar indent level mark a
block. This makes a Python program more readable.
OOP Concepts
Both C++ and Python implement object oriented programming
concepts. C++ is closer to the theory of OOP than Python. C++
supports the concept of data encapsulation as the visibility of the
variables can be defined as public, private and protected.
Python doesn't have the provision of defining the visibility. Unlike C++,
Python doesn't support method overloading. Because it is dynamically
typed, all the methods are polymorphic in nature by default.
C++ is in fact an extension of C. One can say that additional keywords
are added in C so that it supports OOP. Hence, we can write a C type
procedure oriented program in C++.
Python is a completely object oriented language. Python's data model
is such that, even if you can adapt a procedure oriented approach,
Python internally uses object-oriented methodology.
Garbage Collection
C++ uses the concept of pointers. Unused memory in a C++ program
is not cleared automatically. In C++, the process of garbage collection
is manual. Hence, a C++ program is likely to face memory related
exceptional behaviour.
Python has a mechanism of automatic garbage collection. Hence,
Python programs are more robust and less prone to memory related
issues.
Application Areas
Because C++ program compiles directly to machine code, it is more
suitable for systems programming, writing device drivers, embedded
systems and operating system utilities.
Python programs are suitable for application programming. Its main
area of application today is data science, machine learning, API
development etc.
Steps
The following are the steps to write a Python program to print Hello
World –
1. Step 1: Install Python. Make sure that Python is installed on
your system or not. If Python is not installed, then install it
from here: https://www.python.org/downloads/
2. Step 2: Choose Text Editor or IDE to write the code.
3. Step 3: Open Text Editor or IDE, create a new file, and write
the code to print Hello World.
4. Step 4: Save the file with a file name and extension ".py".
5. Step 5: Compile/Run the program.
In the above code, we wrote two lines. The first line is the Python
comment that will be ignored by the Python interpreter, and the second
line is the print() statement that will print the given message ("Hello
World") on the output screen.
Output
Hello World
Example
PS C:\> python
Python 3.11.2 (tags/v3.11.2:878ead1, Feb 7 2023, 16:38:35) [MSC
v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "licence" for more information.
>>> print ("Hello World")
Hello World
Example
$ python3
Python 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "licence" for more information.
>>> print ("Hello World")
Hello World
For Windows OS, open the command prompt terminal (CMD) and run
the program as shown below −
C:\>python hello.py
You also need to give the file executable permission by using the
chmod +x command
$ chmod +x hello.py
Then, you can run the program with following command line −
$ ./hello.py
FAQs
1. Why is the first program called Hello World?
It is just a simple program to test the basic syntax and
compiler/interpreter configuration of the Python programming
language.
Application Areas
Python is a general-purpose programming language. It is suitable for
the development of a wide range of software applications. Over the last
few years Python has been the preferred language of choice for
developers in the following application areas −
1. Data Science
2. Machine Learning
3. Web Development
4. Computer Vision and Image processing
5. Embedded Systems and IoT
6. Job Scheduling and Automation
7. Desktop GUI Applications
8. Console-based Applications
9. CAD Applications
10. Game Development
Data Science
Python's recent meteoric rise in the popularity charts is largely due to
its Data science libraries. Python has become an essential skill for data
scientists. Today, real time web applications, mobile applications and
other devices generate huge amounts of data. Python's data science
libraries help companies generate business insights from this data.
Libraries like NumPy, Pandas, and Matplotlib are extensively used to
apply mathematical algorithms to the data and generate visualisations.
Commercial and community Python distributions like Anaconda and
ActiveState bundle all the essential libraries required for data science.
Machine Learning
Python libraries such as Scikit-learn and TensorFlow help in building
models for prediction of trends like customer satisfaction, projected
values of stocks etc. based upon the past data. Machine learning
applications include (but not restricted to) medical diagnosis, statistical
arbitrage, basket analysis, sales prediction etc.
Web Development
Python's web frameworks facilitate rapid web application development.
Django, Pyramid, Flask are very popular among the web developer
community. etc. make it very easy to develop and deploy simple as well
as complex web applications.
Latest versions of Python provide asynchronous programming support.
Modern web frameworks leverage this feature to develop fast and high
performance web apps and APIs.
Computer Vision and Image processing
OpenCV is a widely popular library for capturing and processing
images. Image processing algorithms extract information from images,
reconstruct image and video data. Computer Vision uses image
processing for face detection and pattern recognition. OpenCV is a C++
library. Its Python port is extensively used because of its rapid
development feature.
Some of the application areas of computer vision are robotics, industrial
surveillance, automation, and biometrics etc.
Console-based Applications
Python is often employed to build CLI (command-line interface)
applications. Such scripts can be used to run scheduled CRON jobs such
as taking database backups etc. There are many Python libraries that
parse the command line arguments. The argparse library comes
bundled with Python’s standard library. You can use Click (part of Flask
framework) and Typer (included in FastAPI framework) to build console
interfaces to the web-based applications built by the respective
frameworks. Textual is a rapid development framework to build apps
that run inside a terminal as well as browsers.
CAD Applications
CAD engineers can take advantage of Python's versatility to automate
repetitive tasks such as drawing shapes and generating reports.
Autodesk Fusion 360 is a popular CAD software, which has a Python API
that allows users to automate tasks and create custom tools. Similarly,
SolidWorks has a built-in Python shell that allows users to run Python
scripts inside the software.
CATIA is another very popular CAD software. Along with a VBScript,
certain third-party Python libraries that can be used to control CATIA.
Game Development
Some popular gaming apps have been built with Python. Examples
include BattleField2, The Sims 4, World of Tanks, Pirates of the
Caribbean, and more. These apps are built with one of the following
Python libraries.
Pygame is one of the most popular Python libraries used to build
engaging computer games. Pygame is an open-source Python library
for making multimedia applications like games built on top of the
excellent SDL library. It is a cross-platform library, which means you can
build a game that can run on any operating system platform.
Another library, Kivy , is also widely used to build desktop as well as
mobile-based games. Kivy has a multi-touch interface. It is an open-
source and cross-platform Python library for rapid development of
game applications. Kivy runs on Linux, Windows, OS X, Android, iOS,
and Raspberry Pi.
PyKara library is based on both SDL (Software and Documentation
Localisation) and the Kyra engine. It is one of the fastest game
development frameworks. PyKara supports MPEG , MP3, Ogg Vorbis,
Wav, etc., multimedia formats.
Python Interpreter
Python is an interpreter-based language. In a Linux system, Python's
executable is installed in the /usr/bin/ directory. For Windows, the
executable (python.exe) is found in the installation folder (for example
C:\python311).
This tutorial will teach you How Python Interpreter Works in
interactive and scripted mode. Python code is executed by one
statement at a time method. Python interpreter has two components.
The translator checks the statement for syntax. If found correct, it
generates an intermediate byte code. There is a Python virtual machine
which then converts the byte code in native binary and executes it. The
following diagram illustrates the mechanism:
Python interpreter has an interactive mode and a scripted mode.
Note that even though Python executes the entire script in one go, but
internally it is still executed in line by line fashion.
In case of any compiler-based language such as Java, the source code
is not converted into byte code unless the entire code is error-free. In
Python, on the other hand, statements are executed until the first
occurrence of an error is encountered.
Let us introduce an error purposefully in the above code.
Open Compiler
print ("My first program")
price = 100
qty = 5
total = prive*qty #Error in this statement
print ("Total = ", total)
Note the misspelt variable prive instead of price. Try to execute the
script again as before −
C:\Users\Acer>python prog.py
My first program
Traceback (most recent call last):
File "C:\Python311\prog.py", line 4, in <module>
total = prive*qty
^^^^^
NameError: name 'prive' is not defined. Did you mean: 'price'?
Note that the statements before the erroneous statement are executed
and then the error message appears. Thus it is now clear that Python
script is executed in an interpreted manner.
You can now execute the script directly, without using it as a command-
line argument.
$ ./hello.py
IPython's magic functions are extremely powerful. Line magics let you
run DOS commands inside IPython. Let us run the dir command from
within IPython console
In [8]: !dir *.exe
Volume in drive F has no label.
Volume Serial Number is E20D-C4B9
Directory of F:\Python311
07-02-2023 16:55 103,192 python.exe
07-02-2023 16:55 101,656 pythonw.exe
2 File(s) 204,848 bytes
0 Dir(s) 105,260,306,432 bytes free
Environment Setup
First step in the journey of learning Python is to install it on your
machine. Today most computer machines, especially Linux OS, have
Python pre-installed. However, it may not be the latest version.
Python is available on a wide variety of platforms including Linux and
Mac OS X. Let's understand how to set up our Python environment.
1. Unix (Solaris, Linux, FreeBSD, AIX, HP/UX, SunOS, IRIX, etc.)
2. Win 9x/NT/2000
3. Macintosh (Intel, PPC, 68K)
4. OS/2
5. DOS (multiple versions)
6. PalmOS
7. Nokia mobile phones
8. Windows CE
9. Acorn/RISC OS
10.
BeOS
11.
Amiga
12.
VMS/OpenVMS
13.
QNX
14.
VxWorks
15.
Psion
Python has also been ported to the Java and .NET virtual machines
Downloading Python
The most up-to-date and current source code, binaries, documentation,
news, etc., is available on the official website of Python
https://www.python.org/
You can download Python documentation from
https://www.python.org/doc/. The documentation is available in HTML,
PDF, and PostScript formats.
Installing Python
Python distribution is available for a wide variety of platforms. You need
to download only the binary code applicable for your platform and
install Python.
If the binary code for your platform is not available, you need a C
compiler to compile the source code manually. Compiling the source
code offers more flexibility in terms of choice of features that you
require in your installation.
Here is a quick overview of installing Python on various platforms −
Even after the update, the latest version of Python may not be
available for install, depending upon the version of Ubuntu you are
using. To overcome this, add the deadsnakes repository.
$ sudo apt-get install software-properties-common
$ sudo add-apt-repository ppa:deadsnakes/ppa
Macintosh Installation
Recent Macs come with Python installed, but it may be several years
out of date. See http://www.python.org/download/mac/ for instructions
on getting the current version along with extra tools to support
development on the Mac. For older Mac OS's before Mac OS X 10.3
(released in 2003), MacPython is available.
Jack Jansen maintains it and you can have full access to the entire
documentation at his website −
http://www.cwi.nl/~jack/macpython.html. You can find complete
installation details for Mac OS installation.
Setting up PATH
Programs and other executable files can be in many directories, so
operating systems provide a search path that lists the directories that
the OS searches for executables.
The path is stored in an environment variable, which is a named string
maintained by the operating system. This variable contains information
available to the command shell and other programs.
The path variable is named as PATH in Unix or Path in Windows (Unix is
case sensitive; Windows is not).
In Mac OS, the installer handles the path details. To invoke the Python
interpreter from any particular directory, you must add the Python
directory to your path.
1 PYTHONPATH
It has a role similar to PATH. This variable tells the Python
interpreter where to locate the module files imported into a
program. It should include the Python source library directory
and the directories containing Python source code.
PYTHONPATH is sometimes preset by the Python installer.
2 PYTHONSTARTUP
It contains the path of an initialization file containing Python
source code. It is executed every time you start the
interpreter. It is named as .pythonrc.py in Unix and it contains
commands that load utilities or modify PYTHONPATH.
3 PYTHONCASEOK
It is used in Windows to instruct Python to find the first case-
insensitive match in an import statement. Set this variable to
any value to activate it.
4 PYTHONHOME
It is an alternative module search path. It is usually embedded
in the PYTHONSTARTUP or PYTHONPATH directories to make
switching module libraries easy.
Running Python
There are three different ways to start Python −
Interactive Interpreter
You can start Python from Unix, DOS, or any other system that provides
you a command-line interpreter or shell window.
Enter python on the command line.
Start coding right away in the interactive interpreter.
$python # Unix/Linux
or
python% # Unix/Linux
or
C:> python # Windows/DOS
1 -d
It provides debug output.
2 -O
It generates optimised bytecode (resulting in .pyo files).
3 -S
Do not run import sites to look for Python paths on startup.
4 -v
verbose output (detailed trace on import statements).
5 -X
disable class-based built-in exceptions (just use strings);
obsolete starting with version 1.6.
6 -c cmd
run Python script sent in as cmd string
7 file
run Python script from given file
If you are not able to set up the environment properly, then you can
take help from your system admin. Make sure the Python environment
is properly set up and working perfectly fine.
We have provided Python Online Compiler/Interpreter which helps
you to Edit and Execute the code directly from your browser. Try to
click the icon to run the following Python code to print conventional
"Hello, World!".
Below code box allows you to change the value of the code. Try to
change the value inside print() and run it again to verify the result.
Open Compiler
# This is my first Python program.
# This will print 'Hello, World!' as the output
print ("Hello, World!");
Print Page
Virtual Environment
Python Virtual Environment
Python virtual environments create a virtual installation of Python
inside a project directory. Users can then install and manage Python
packages for each project. This allows users to be able to install
packages and modify their Python environment without fear of breaking
packages installed in other environments.
The scripts folder of this virtual environment also contains pip utilities.
If you install a package from PyPI, that package will be active only in
the current virtual environment.
Syntax
Python - Syntax
The Python syntax defines a set of rules that are used to create a
Python Program. The Python Programming Language Syntax has many
similarities to Perl, C, and Java Programming Languages. However,
there are some definite differences between the languages.
If you are running an older version of Python, like Python 2.4.x, then
you would need to use a print statement without parentheses as in
print "Hello, World!". However in Python version 3.x, this produces
the following result −
Hello, World!
We assume that you have a Python interpreter path set in the PATH
variable. Now, let's try to run this program as follows −
$ python3 test.py
Let us try another way to execute a Python script. Here is the modified
test.py file −
Open Compiler
#!/usr/bin/python3
print ("Hello, World!")
Python Identifiers
A Python identifier is a name used to identify a variable, function, class,
module or other object. An identifier starts with a letter A to Z or a to z
or an underscore (_) followed by zero or more letters, underscores and
digits (0 to 9).
Python does not allow punctuation characters such as @, $, and %
within identifiers.
Python is a case sensitive programming language. Thus, Manpower
and manpower are two different identifiers in Python.
Here are naming conventions for Python identifiers −
1. Python Class names start with an uppercase letter. All other
identifiers start with a lowercase letter.
2. Starting an identifier with a single leading underscore
indicates that the identifier is a private identifier.
3. Starting an identifier with two leading underscores indicates a
strongly private identifier.
4. If the identifier also ends with two trailing underscores, the
identifier is a language-defined special name.
and as assert
glob if import
al
in is lambda
or pass raise
Quotations in Python
Python accepts single ('), double (") and triple (''' or" """) quotes to
denote string literals, as long as the same type of quote starts and
ends the string.
The triple quotes are used to span the string across multiple lines. For
example, all the following are legal −
word = 'word'
print (word)
sentence = "This is a sentence."
print (sentence)
paragraph = """This is a paragraph. It is
made up of multiple lines and sentences."""
print (paragraph)
Comments in Python
A comment is a programmer-readable explanation or annotation in the
Python source code. They are added with the purpose of making the
source code easier for humans to understand, and are ignored by
Python interpreter
Just like most modern languages, Python supports single-line (or end-of-
line) and multi-line (block) comments. Python comments are very much
similar to the comments available in PHP, BASH and Perl Programming
languages.
A hash sign (#) that is not inside a string literal begins a comment. All
characters after the # and up to the end of the physical line are part of
the comment and the Python interpreter ignores them.
Open Compiler
# First comment
print ("Hello, World!") # Second comment
You can also program your script in such a way that it should accept
various options. Command Line Arguments is an advanced topic and
should be studied a bit later once you have gone through the rest of
the Python concepts.
Variables
Python Variables
Python variables are the reserved memory locations used to store
values within a Python Program. This means that when you create a
variable you reserve some space in the memory.
Based on the data type of a variable, Python interpreter allocates
memory and decides what can be stored in the reserved memory.
Therefore, by assigning different data types to Python variables, you
can store integers, decimals or characters in these variables.
Memory Addresses
Data items belonging to different data types are stored in the
computer's memory. Computer's memory locations are having a
number or address, internally represented in binary form. Data is also
stored in binary form as the computer works on the principle of binary
representation. In the following diagram, a string May and a number
18 is shown as stored in memory locations.
If you know the assembly language, you will convert these data items
and the memory address, and give a machine language instruction.
However, it is not easy for everybody. Language translators such as
Python interpreters perform this type of conversion. It stores the object
in a randomly chosen memory location. Python's built-in id() function
returns the address where the object is stored.
>>> "May"
May
>>> id("May")
2167264641264
>>> 18
18
>>> id(18)
140714055169352
The data object (May) and its name (month) have the same id(). The
id() of 18 and age are also the same.
>>> id(month)
2167264641264
>>> id(age)
140714055169352
Here, 100, 1000.0 and "Zara Ali" are the values assigned to counter,
miles, and name variables, respectively. When running the above
Python program, this produces the following result −
100
1000.0
Zara Ali
You can delete a single object or multiple objects by using the del
statement. For example −
del var
del var_a, var_b
Example
Following examples shows how we can delete a variable and if we try to
use a deleted variable then Python interpreter will throw an error:
Open Compiler
counter = 100
print (counter)
del counter
print (counter)
Example
This example demonstrates case sensitivity of variables.
Open Compiler
x = str(10) # x will be '10'
y = int(10) # y will be 10
z = float(10) # z will be 10.0
print( "x =", x )
print( "y =", y )
print( "z =", z )
Here, an integer object is created with the value 1, and all three
variables are assigned to the same memory location. You can also
assign multiple objects to multiple variables. For example −
Open Compiler
a,b,c = 1,2,"Zara Ali"
print (a)
print (b)
print (c)
Here, two integer objects with values 1 and 2 are assigned to variables
a and b respectively, and one string object with the value "Zara Ali" is
assigned to the variable c.
Example
Following are valid Python variable names:
Open Compiler
counter = 100
_count = 100
name1 = "Zara"
name2 = "Nuha"
Age = 20
zara_salary = 100000
print (counter)
print (_count)
print (name1)
print (name2)
print (Age)
print (zara_salary)
Example
Following are invalid Python variable names:
Open Compiler
1counter = 100
$_count = 100
zara-salary = 100000
print (1 counter)
print ($count)
print (zara-salary)
Example
Once you use a variable to identify a data object, it can be used
repeatedly without its id() value. Here, we have a variable height and
width of a rectangle. We can compute the area and perimeter with
these variables.
>>> width=10
>>> height=20
>>> area=width*height
>>> area
200
>>> perimeter=2*(width+height)
>>> perimeter
60
Save the above script with .py extension and execute from command-
line. The result would be −
Area = 200
Perimeter = 60
Example
Following is an example to show the usage of local variables:
Open Compiler
def sum(x,y):
sum = x + y
return sum
print(sum(5, 10))
Example
Following is an example of global variables −
Open Compiler
x=5
y = 10
def sum():
sum = x + y
return sum
print(sum())
Constants in Python
Python doesn't have any formally defined constants, However you can
indicate a variable to be treated as a constant by using all-caps names
with underscores. For example, the name PI_VALUE indicates that you
don't want the variable redefined or changed in any way.
The naming convention using all-caps is sometimes referred to as
screaming snake case - where the all-caps (screaming) and the
underscores (snakes).
A Python variable refers to the object and not the memory location. An
object is stored in memory only once. Multiple variables are really the
multiple labels to the same object.
Data Types
Python Data Types
Python data types are actually classes, and the defined variables are
their instances or objects. Since Python is dynamically typed, the data
type of a variable is determined at runtime based on the assigned
value.
In general, the data types are used to define the type of a variable. It
represents the type of data we are going to store in a variable and
determines what operations can be done on it.
Each programming language has its own classification of data items.
With these data types, we can store different types of data values.
Types of Data Types in Python
Python supports the following built-in data types −
1. Numeric Data Types
a. int
b. flot
c. complex
a. list
b. tuple
c. range
a. bytes
b. bytearray
c. memoryview
a. set
b. frozenset
Python supports four different numerical types and each of them have
built-in classes in Python library, called int, bool, float and complex
respectively −
1. int (signed integers)
2. float (floating point real values)
3. complex (complex numbers)
10 0.0 3.14j
A list in Python is an object of the list class. We can check it with the
type() function.
>>> type([2023, "Python", 3.11, 5+6j, 1.23E-4])
<class 'list'>
A list can have items which are simple numbers, strings, tuples,
dictionaries, sets or objects of user defined class also.
The values stored in a Python list can be accessed using the slice
operator ([ ] and [:]) with indexes starting at 0 in the beginning of the
list and working their way to end -1. The plus (+) sign is the list
concatenation operator, and the asterisk (*) is the repetition operator.
Example of List Data Type
Open Compiler
list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]
tinylist = [123, 'john']
print (list) # Prints complete list
print (list[0]) # Prints first element of the list
print (list[1:3]) # Prints elements starting from 2nd to 3rd
print (list[2:]) # Prints elements starting from 3rd element
print (tinylist * 2) # Prints list two times
print (list + tinylist) # Prints concatenated lists
As in case of a list, an item in the tuple may also be a list, a tuple itself
or an object of any other Python class.
>>> (['One', 'Two', 'Three'], 1,2.0,3, (1.0, 2.0, 3.0))
To form a tuple, use of parentheses is optional. Data items separated
by comma without any enclosing symbols are treated as a tuple by
default.
>>> 2023, "Python", 3.11, 5+6j, 1.23E-4
(2023, 'Python', 3.11, (5+6j), 0.000123)
The main differences between lists and tuples are: Lists are enclosed in
brackets ( [ ] ) and their elements and size can be changed i.e. lists are
mutable, while tuples are enclosed in parentheses ( ( ) ) and cannot be
updated (immutable). Tuples can be thought of as read-only lists.
The following code is invalid with tuple, because we attempted to
update a tuple, which is not allowed. Similar case is possible with lists
−
Open Compiler
tuple = ( 'abcd', 786 , 2.23, 'john', 70.2 )
list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]
tuple[2] = 1000 # Invalid syntax with tuple
list[2] = 1000 # Valid syntax with list
Now let's modify above program to print the number starting from 2
instead of 0 −
Open Compiler
for i in range(2, 5):
print(i)
Again, let's modify the program to print the number starting from 1 but
with an increment of 2 instead of 1:
Open Compiler
for i in range(1, 5, 2):
print(i)
If you have an array object, you can create a memoryview using the
buffer interface as shown below −
Open Compiler
import array
arr = array.array('i', [1, 2, 3, 4, 5])
view = memoryview(arr)
print(view)
Note that items in the set collection may not follow the same order in
which they are entered. The position of items is optimised by Python to
perform operations over sets as defined in mathematics.
Python's Set is an object of built-in set class, as can be checked with
the type() function.
>>> type({2023, "Python", 3.11, 5+6j, 1.23E-4})
<class 'set'>
A set can store only immutable objects such as number (int, float,
complex or bool), string or tuple. If you try to put a list or a dictionary in
the set collection, Python raises a TypeError.
>>> {['One', 'Two', 'Three'], 1,2,3, (1.0, 2.0, 3.0)}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
Example
In the following example, we are getting the type of the values and
variables −
Open Compiler
# Getting type of values
print(type(123))
print(type(9.99))
# Getting type of variables
a = 10
b = 2.12
c = "Hello"
d = (10, 20, 30)
e = [10, 20, 30]
print(type(a))
print(type(b))
print(type(c))
print(type(d))
print(type(e))
Example
The following example, demonstrating how a variable's data type is set
based on the given value −
Open Compiler
# Declaring a variable
# And, assigning an integer value
x = 10
# Printing its value and type
print("x = ", x)
print("type of x = ", type(x))
# Now, assigning string value to
# the same variable
x = "Hello World!"
# Printing its value and type
print("x = ", x)
print("type of x = ", type(x))
1. Primitive Types
The primitive data types are the fundamental data types that are used
to create complex data types (sometimes called complex data
structures). There are mainly four primitive data types, which are −
1. Integers
2. Floats
3. Booleans, and
4. Strings
2. Non-primitive Types
The non-primitive data types store values or collections of values.
There are mainly four types of non-primitive types, which are −
1. Lists
2. Tuples
3. Dictionaries, and
4. Sets
Example
Following is an example which converts different values to integer,
floating point and string values respectively −
Open Compiler
print("Conversion to integer data type")
a = int(1) # a will be 1
b = int(2.2) # b will be 2
c = int("3.3") # c will be 3
print (a)
print (b)
print (c)
print("Conversion to floating point number")
a = float(1) # a will be 1.0
b = float(2.2) # b will be 2.2
c = float("3.3") # c will be 3.3
print (a)
print (b)
print (c)
print("Conversion to string")
a = str(1) # a will be "1"
b = str(2.2) # b will be "2.2"
c = str("3.3") # c will be "3.3"
print (a)
print (b)
print (c)
Type Casting
Python Type Casting
From a programming point of view, a type casting refers to converting
an object of one type into another. Here, we shall learn about type
casting in Python Programming.
Python Type Casting is a process in which we convert a literal of one
data type to another data type. Python supports two types of casting −
implicit and explicit.
In Python there are different data types, such as numbers, sequences,
mappings etc. There may be a situation where you have the available
data of one type but you want to use it in another form. For example,
the user has input a string but you want to use it as a number. Python's
type casting mechanism lets you do that.
is same as −
<<< a = 10
<<< a
10
<<< type(a)
<class 'int>
String to Integer
The int() function returns an integer from a string object, only if it
contains a valid integer representation.
<<< a = int("100")
<<< a
100
<<< type(a)
<class 'int'>
<<< a = ("10"+"01")
<<< a = int("10"+"01")
<<< a
1001
<<< type(a)
<class 'int'>
The int() function also returns integers from binary, octal and hexa-
decimal strings. For this, the function needs a base parameter which
must be 2, 8 or 16 respectively. The string should have a valid
binary/octal/Hexa-decimal representation.
is same as −
<<< a = 9.99
<<< a
9.99
<<< type(a)
<class 'float'>
The float() function returns a float object from a string, if the string
contains a valid floating point number, otherwise ValueError is raised.
<<< a = float("9.99")
<<< a
9.99
<<< type(a)
<class 'float'>
<<< a = float("1,234.50")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: could not convert string to float: '1,234.50'
The reason for the ValueError here is the presence of a comma in the
string.
For the purpose of string to float conversion, the scientific notation of
floating point is also considered valid.
<<< a = float("1.00E4")
<<< a
10000.0
<<< type(a)
<class 'float'>
<<< a = float("1.00E-4")
<<< a
0.0001
<<< type(a)
<class 'float'>
Integer to string
You can convert any integer number into a string as follows:
<<< a = str(10)
<<< a
'10'
<<< type(a)
<class 'str'>
Float to String
str() function converts floating point objects with both the notations of
floating point, standard notation with a decimal point separating
integer and fractional part, and the scientific notation to string object.
<<< a=str(11.10)
<<< a
'11.1'
<<< type(a)
<class 'str'>
<<< a = str(2/5)
<<< a
'0.4'
<<< type(a)
<class 'str'>
Unicode System
Example
Open Compiler
var = "3/4"
print (var)
var = "\u00BE"
print (var)
Example
In the following example, a string '10' is stored using the Unicode
values of 1 and 0 which are \u0031 and u0030 respectively.
Open Compiler
var = "\u0031\u0030"
print (var)
Example
In the following example, we have a string variable that consists of
ASCII characters. ASCII is a subset of the Unicode character set. The
encode() method is used to convert it into a bytes object.
Open Compiler
string = "Hello"
tobytes = string.encode('utf-8')
print (tobytes)
string = to bytes.decode('utf-8')
print (string)
The decode() method converts the byte object back to the str object.
The encoding method used is utf-8.
b'Hello'
Hello
Example
In the following example, the Rupee symbol ( ₹ ) is stored in the
variable using its Unicode value. We convert the string to bytes and
back to str.
Open Compiler
string = "\u20B9"
print (string)
tobytes = string.encode('utf-8')
print (tobytes)
string = to bytes.decode('utf-8')
print (string)
When you execute the above code, it will produce the following output
−
₹
b'\xe2\x82\xb9'
₹
Literals
What are Python Literals?
Python literals or constants are the notation for representing a fixed
value in source code. In contrast to variables, literals (123, 4.3, "Hello")
are static values or you can say constants which do not change
throughout the operation of the program or application. For example, in
the following assignment statement.
x = 10
1. Decimal Literal
Decimal literals represent the signed or unsigned numbers. Digitals
from 0 to 9 are used to create a decimal literal value.
Look at the below statement assigning decimal literal to the variable −
x = 10
y = -25
z=0
2. Octal Literal
Python allows an integer to be represented as an octal number or a
hexadecimal number. A numeric representation with only eight digit
symbols (0 to 7) but prefixed by 0o or 0O is an octal number in Python.
Look at the below statement assigning octal literal to the variable −
x = 0O34
3. Hexadecimal Literal
Similarly, a series of hexadecimal symbols (0 to 9 and a to f), prefixed
by 0x or 0X represents an integer in Hexadecimal form in Python.
Look at the below statement assigning hexadecimal literal to the
variable −
x = 0X1C
Example
Open Compiler
# Using Octal notation
x = 0O34
print ("0O34 in octal is", x, type(x))
# Using Hexadecimal notation
x = 0X1c
print ("0X1c in Hexadecimal is", x, type(x))
When you run this code, it will produce the following output −
0O34 in octal is 28 <class 'int'>
0X1c in Hexadecimal is 28 <class 'int'>
For a floating point number which is too large or too small, where the
number of digits before or after a decimal point is more, a scientific
notation is used for a compact literal representation. The symbol E or e
followed by positive or negative integer, follows after the integer part.
Operators
Python Operators
Python operators are special symbols used to perform specific
operations on one or more operands. The variables, values, or
expressions can be used as operands. For example, Python's addition
operator (+) is used to perform addition operations on two variables,
values, or expressions.
The following are some of the terms related to Python operators:
1. Unary operators: Python operators that require one operand
to perform a specific operation are known as unary operators.
2. Binary operators: Python operators that require two
operands to perform a specific operation are known as binary
operators.
3. Operands: Variables, values, or expressions that are used
with the operator to perform a specific operation.
- Subtraction a – b = -10
* Multiplicatio a * b = 200
n
/ Division b/a=2
% Modulus b%a=0
** Exponent a**b
=10**20
// Floor 9//2 = 4
Division
Output
a: 21 b: 10 a+b: 31
a: 21 b: 10 a-b: 11
a: 21 b: 10 a*b: 210
a: 21 b: 10 a/b: 2.1
a: 21 b: 10 a%b: 1
a: 2 b: 3 a**b: 8
a: 10 b: 5 a//b: 2
== Equal (a == b) is not
true.
Output
Line 1 - a is not equal to b
Line 2 - a is not equal to b
Line 3 - a is not less than b
Line 4 - a is greater than b
Line 5 - a is either less than or equal to b
Line 6 - b is either greater than or equal to b
= a = 10 a = 10
+= a += 30 a = a +
30
-= a -= 15 a = a - 15
*= a *= 10 a = a * 10
/= a /= 5 a=a/5
%= a %= 5 a=a%5
**= a **= 4 a = a ** 4
//= a //= 5 a = a // 5
|= a |= 5 a=a|5
^= a ^= 5 a=a^5
Output
a: 21 b: 10 c : 0
a: 21 c = a + b: 31
a: 21 c += a: 52
a: 21 c *= a: 1092
a: 21 c /= a : 52.0
a: 21 b: 10 c : 2
a: 21 c %= a: 2
a: 21 c **= a: 2097152
a: 21 c //= a: 99864
| OR a|b
^ XOR a^b
~ NOT ~a
Output
a= 20 : 0b10100 b= 10 : 0b1010
result of AND is 0 : 0b0
result of OR is 30 : 0b11110
result of XOR is 30 : 0b11110
result of COMPLEMENT is -21 : -0b10101
result of LEFT SHIFT is 80 : 0b1010000
result of RIGHT SHIFT is 5 : 0b101
or OR a or b
Output
True
True
False
Output
a: 10 b: 20 list: [1, 2, 3, 4, 5]
a is not present in the given list
b is not present in the given list
c: 2.0 list: [1, 2, 3, 4, 5]
c is available in the given list
Output
True
False
False
True
1 **
Exponentiation (raise to the power)
2 ~+-
Complement, unary plus and minus (method names for the
last two are +@ and -@)
3 * / % //
Multiply, divide, modulo and floor division
4 +-
Addition and subtraction
5 >> <<
Right and left bitwise shift
6 &
Bitwise 'AND'
7 ^|
Bitwise exclusive `OR' and regular `OR'
9 <> == !=
Equality operators
10 = %= /= //= -= += *= **=
Assignment operators
11 is is not
Identity operators
12 in not in
Membership operators
13 not or and
Logical operators
Arithmetic Operators
Python Arithmetic Operators
Python arithmetic operators are used to perform mathematical
operations such as addition, subtraction, multiplication, division, and
more on numbers. Arithmetic operators are binary operators in the
sense they operate on two operands. Python fully supports mixed
arithmetic. That is, the two operands can be of two different number
types. In such a situation.
+ Addition a + b = 30
- Subtraction a – b = -10
* Multiplicatio a * b = 200
n
/ Division b/a=2
% Modulus b%a=0
** Exponent a**b
=10**20
// Floor 9//2 = 4
Division
Addition Operator
The addition operator is represented by + symbol. It is a basic
arithmetic operator. It adds the two numeric operands on either side
and returns the additional result.
Subtraction Operator
The subtraction operator is represented by - symbol. It subtracts the
second operand from the first. The resultant number is negative if the
second operand is larger.
Result −
Subtraction of two integers
a = 10 b = 20 a-b = -10
a = 10 b = 20 b-a = 10
Multiplication Operator
The * (asterisk) symbol is defined as a multiplication operator in Python
(as in many languages). It returns the product of the two operands on
its either side. If any of the operands is negative, the result is also
negative. If both are negative, the result is positive. Changing the order
of operands doesn't change the result
Division Operator
The "/" symbol is usually called a forward slash. The result of the
division operator is the numerator (left operand) divided by the
denominator (right operand). The resultant number is negative if any of
the operands is negative. Since infinity cannot be stored in the
memory, Python raises ZeroDivisionError if the denominator is 0.
The result of the division operator in Python is always a float, even if
both operands are integers.
Modulus Operator
Python defines the "%" symbol, which is known as the Percent symbol,
as the Modulus (or modulo) operator. It returns the remainder after the
denominator divides the numerator. It can also be called Remainder
operator. The result of the modulus operator is the number that
remains after the integer quotient. To give an example, when 10 is
divided by 3, the quotient is 3 and remainder is 1. Hence, 10%3
(normally pronounced as 10 mod 3) results in 1.
Exponent Operator
Python uses ** (double asterisk) as the exponent operator (sometimes
called raised to operator). So, for a**b, you say a raised to b, or even
bth powers of a.
If in the exponentiation expression, both operands are integers, the
result is also an integer. In case either one is a float, the result is float.
Similarly, if either one operand is a complex number, the exponent
operator returns a complex number.
If the base is 0, the result is 0, and if the index is 0 then the result is
always 1.
Example of exponent operator
Open Compiler
a=10
b=2
print ("a=",a, "b=",b, "a**b=", a**b)
a=10
b=1.5
print ("a=",a, "b=",b, "a**b=", a**b)
a=7.7
b=2
print ("a=",a, "b=",b, "a**b=", a**b)
a=1+2j
b=4
print ("a=",a, "b=",b, "a**b=", a**b)
a=12.4
b=0
print ("a=",a, "b=",b, "a**b=", a**b)
print ("a=",a, "b=",b, "b**a=", b**a)
For example,
a=6+4j
b=3+2j
c=a*b
c=(18-8)+(12+12)j
c=10+24j
Complex class in Python doesn't support the modulus operator (%) and
floor division operator (//).
Comparison Operators
Python Comparison Operators
Comparison operators in Python are very important in Python's
conditional statements (if, else and elif) and looping statements (while
and for loops). The comparison operators are also called relational
operators. Some of the well known operators are "<" stands for less
than, and ">" stands for greater than operator.
Python uses two more operators, combining the "=" symbol with these
two. The "<=" symbol is for less than or equal to operator and the
">=" symbol is for greater than or equal to operator.
= Is equal to a==
= b
Example
Open Compiler
a=5
b=7
print (a>b)
print (a<b)
It will produce the following output −
False
True
Example
The following code demonstrates the use of Python's comparison
operators with integer numbers −
Open Compiler
print ("Both operands are integer")
a=5
b=7
print ("a=",a, "b=",b, "a>b is", a>b)
print ("a=",a, "b=",b,"a<b is",a<b)
print ("a=",a, "b=",b,"a==b is",a==b)
print ("a=",a, "b=",b,"a!=b is",a!=b)
Example
Open Compiler
print ("comparison of int and float")
a=10
b=10.0
print ("a=",a, "b=",b, "a>b is", a>b)
print ("a=",a, "b=",b,"a<b is",a<b)
print ("a=",a, "b=",b,"a==b is",a==b)
print ("a=",a, "b=",b,"a!=b is",a!=b)
Example
Open Compiler
print ("comparison of complex numbers")
a=10+1j
b=10.-1j
print ("a=",a, "b=",b,"a==b is",a==b)
print ("a=",a, "b=",b,"a!=b is",a!=b)
Example
Open Compiler
print ("comparison of complex numbers")
a=10+1j
b=10.-1j
print ("a=",a, "b=",b,"a<b is",a<b)
print ("a=",a, "b=",b,"a>b is",a>b)
It will produce the following output −
comparison of complex numbers
Traceback (most recent call last):
File "C:\Users\mlath\examples\example.py", line 5, in <module>
print ("a=",a, "b=",b,"a<b is",a<b)
^^^
TypeError: '<' not supported between instances of 'complex' and
'complex
Comparison of Booleans
Boolean objects in Python are really integers: True is 1 and False is 0. In
fact, Python treats any non-zero number as True. In Python, comparison
of Boolean objects is possible. "False < True" is True!
Example
Open Compiler
print ("comparison of Booleans")
a=True
b=False
print ("a=",a, "b=",b,"a<b is",a<b)
print ("a=",a, "b=",b,"a>b is",a>b)
print ("a=",a, "b=",b,"a==b is",a==b)
print ("a=",a, "b=",b,"a!=b is",a!=b)
Example
Open Compiler
print ("comparison of strings")
a='BAT'
b='BALL'
print ("a=",a, "b=",b,"a<b is",a<b)
print ("a=",a, "b=",b,"a>b is",a>b)
print ("a=",a, "b=",b,"a==b is",a==b)
print ("a=",a, "b=",b,"a!=b is",a!=b)
Example
Open Compiler
print ("comparison of tuples")
a=(1,2,4)
b=(1,2,3)
print ("a=",a, "b=",b,"a<b is",a<b)
print ("a=",a, "b=",b,"a>b is",a>b)
print ("a=",a, "b=",b,"a==b is",a==b)
print ("a=",a, "b=",b,"a!=b is",a!=b)
Example
Open Compiler
print ("comparison of dictionary objects")
a={1:1,2:2}
b={2:2, 1:1, 3:3}
print ("a=",a, "b=",b,"a==b is",a==b)
print ("a=",a, "b=",b,"a!=b is",a!=b)
Assignment Operators
Python Assignment Operator
The = (equal to) symbol is defined as an assignment operator in
Python. The value of the Python expression on its right is assigned to a
single variable on its left. The = symbol as in programming in general
(and Python in particular) should not be confused with its usage in
Mathematics, where it states that the expressions on either side of the
symbol are equal.
Example
The += operator is an augmented operator. It is also called cumulative
addition operator, as it adds "b" in "a" and assigns the result back to a
variable.
The following are the augmented assignment operators in Python:
1. Augmented Addition Operator
2. Augmented Subtraction Operator
3. Augmented Multiplication Operator
4. Augmented Division Operator
5. Augmented Modulus Operator
6. Augmented Exponent Operator
7. Augmented Floor division Operator
Example
age > 16 and marks > 80
percentage < 50 or attendance < 75
Along with the keyword False, Python interprets None, numeric zero of
all types, and empty sequences (strings, tuples, lists), empty
dictionaries, and empty sets as False. All other values are treated as
True.
There are three logical operators in Python. They are "and", "or" and
"not". They must be in lowercase.
ab a and
b
FF F
FT F
TF F
TT T
Logical "or" Operator
In contrast, the or operator returns True if any of the operands is True.
For the compound Boolean expression to be False, both the operands
have to be False.
ab a or
b
FF F
FT T
TF T
TT T
FT
TF
When you use integers as the operands, both are converted into
equivalent binary, the & operation is done on the corresponding bit
from each number, starting from the least significant bit and going
towards the most significant bit.
For the sake of convenience, use the standard 8-bit format for each
number, so that "a" is 00111100 and "b" is 00001101. Let us manually
perform an operation on each corresponding bit of these two numbers.
0011 1100
&
0000 1101
-------------
0000 1100
Convert the resultant binary back to integer. You'll get 12, which was
the result obtained earlier.
>>> int('00001100',2)
12
How does this take place? Let us use the binary equivalent of 60, and
perform the left shift by 2.
0011 1100
<<
2
-------------
1111 0000
Membership Operators
Python Membership Operators
The membership operators in Python help us determine whether an
item is present in a given container type object, or in other words,
whether an item is a member of the given container type object.
In the last case, "d" is a float but still it compares to True with 10 (an
int) in the list. Even if a number expressed in other formats like binary,
octal or hexadecimal are given the membership operators tell if it is
inside the sequence.
>>> 0x14 in [10, 20, 30, 40]
True
Example
However, if you try to check if two successive numbers are present in a
list or tuple, the in operator returns False. If the list/tuple contains the
successive numbers as a sequence itself, then it returns True.
Open Compiler
var = (10,20,30,40)
a = 10
b = 20
print ((a,b), "in", var, ":", (a,b) in var)
var = ((10,20),30,40)
a = 10
b = 20
print ((a,b), "in", var, ":", (a,b) in var)
Identity Operators
Python Identity Operators
The identity operators compare the objects to determine whether they
share the same memory and refer to the same object type (data type).
Python provided two identity operators; we have listed them as follows:
'is' Operator
'is not' Operator
The list and tuple objects behave differently, which might look strange
in the first instance. In the following example, two lists "a" and "b"
contain the same items. But their id() differs.
Example 2
Open Compiler
a=[1,2,3]
b=[1,2,3]
print ("id(a), id(b):", id(a), id(b))
print ("a is b:", a is b)
print ("b is not a:", b is not a)
The list or tuple contains the memory locations of individual items only
and not the items itself. Hence "a" contains the addresses of 10,20 and
30 integer objects in a certain location which may be different from
that of "b".
Example 3
print (id(a[0]), id(a[1]), id(a[2]))
print (id(b[0]), id(b[1]), id(b[2]))
Because of two different locations of "a" and "b", the "is" operator
returns False even if the two lists contain the same numbers.
1 (),[], {}
Parentheses and braces
2 [index], [index:index]
Subscription, slicing,
3 await x
Await expression
4 **
Exponentiation
5 +x, -x, ~x
Positive, negative, bitwise NOT
6 *, @, /, //, %
Multiplication, matrix multiplication, division, floor division,
remainder
7 +, -
Addition and subtraction
8 <<, >>
Left Shifts, Right Shifts
9 &
Bitwise AND
10 ^
Bitwise XOR
11 |
Bitwise OR
12 in, not in, is, is not, <, <=, >, >=, !=, ==
Comparisons, including membership tests and identity tests
13 not x
Boolean NOT
14 and
Boolean AND
15 or
Boolean OR
16 if – else
Conditional expression
17 lambda
Lambda expression
18 :=
Walrus operator
When you execute the above program, it produces the following result
−
Value of (a + b) * c / d is 90.0
Value of ((a + b) * c) / d is 90.0
Value of (a + b) * (c / d) is 90.0
Value of a + (b * c) / d is 50.0
Comments
Python Comments
Python comments are programmer-readable explanations or
annotations in the Python source code. They are added with the
purpose of making the source code easier for humans to understand,
and are ignored by the Python interpreter. Comments enhance the
readability of the code and help the programmers to understand the
code very carefully.
Example
If we execute the code given below, the output produced will simply
print "Hello, World!" to the console, as comments are ignored by the
Python interpreter and do not affect the execution of the program −
Open Compiler
# This is a comment
print("Hello, World!")
Python Docstrings
In Python, docstrings are a special type of comment that is used to
document modules, classes, functions, and methods. They are written
using triple quotes (''' or """) and are placed immediately after the
definition of the entity they document.
Docstrings can be accessed programmatically, making them an integral
part of Python’s built-in documentation tools.
Example of a Function Docstring
Open Compiler
def greet(name):
"""
This function greets the person whose name is passed as a
parameter.
Parameters:
name (str): The name of the person to greet
Returns:
None
"""
print(f"Hello, {name}!")
greet("Alice")
Accessing Docstrings
Docstrings can be accessed using the .__doc__ attribute or the help()
function. This makes it easy to view the documentation for any module,
class, function, or method directly from the interactive Python shell or
within the code.
Example: Using the .__doc__ attribute
Open Compiler
def greet(name):
"""
This function greets the person whose name is passed as a
parameter.
Parameters:
name (str): The name of the person to greet
Returns:
None
"""
print(greet.__doc__)
Print Page
User Input
Provide User Input in Python
In this chapter, we will learn how Python accepts the user input from
the console, and displays the output on the same console.
Every computer application should have a provision to accept input
from the user when it is running. This makes the application interactive.
Depending on how it is developed, an application may accept the user
input in the form of text entered in the console (sys.stdin), a graphical
layout, or a web-based interface.
Save the above code as hello.py and run it from the command-line.
Here's the output
C:\python311> python hello.py
Hello My name is Kiran
I am from Hyderabad
The program simply prints the values of the two variables in it. If you
run the program repeatedly, the same output will be displayed every
time. To use the program for another name and city, you can edit the
code, change name to say "Ravi" and city to "Chennai". Every time you
need to assign a different value, you will have to edit the program, save
and run, which is not the ideal way.
When the interpreter encounters input() function, it waits for the user
to enter data from the standard input stream (keyboard) till the Enter
key is pressed. The sequence of characters may be stored in a string
variable for further use.
On reading the Enter key, the program proceeds to the next statement.
Let us change our program to store the user input in name and city
variables.
#! /usr/bin/python3.11
name = input()
city = input()
print ("Hello My name is", name)
print ("I am from ", city)
When you run, you will find the cursor waiting for the user's input.
Enter values for name and city. Using the entered data, the output will
be displayed.
Ravi
Chennai
Hello My name is Ravi
I am from Chennai
Now, the variables are not assigned any specific value in the program.
Every time you run, different values can be input. So, your program has
become truly interactive.
Inside the input() function, you may give a prompt text, which will
appear before the cursor when you run the code.
#! /usr/bin/python3.11
name = input("Enter your name : ")
city = input("Enter your city : ")
print ("Hello My name is", name)
print ("I am from ", city)
When you run the program displays the prompt message, basically
helping the user what to enter.
Enter your name: Praveen Rao
Enter your city: Bengaluru
Hello My name is Praveen Rao
I am from Bengaluru
When you run, you will find the cursor waiting for the user's input.
Enter values for name and city. Using the entered data, the output will
be displayed.
Enter your name - Ravi
Enter city name - Chennai
Hello My name is Ravi
I am from Chennai
Why do you get a TypeError here? The reason is, Python always reads
the user input as a string. Hence, width="20" and height="30" are the
strings and obviously you cannot perform multiplication of two strings.
To overcome this problem, we shall use int(), another built-in function
from Python's standard library. It converts a string object to an integer.
To accept an integer input from the user, read the input in a string, and
type cast it to integer with int() function −
w = input("Enter width : ")
width = int(w)
h = input("Enter height : ")
height = int(h)
You can combine the input and type cast statements in one −
#! /usr/bin/python3.11
width = int(input("Enter width : "))
height = int(input("Enter height : "))
area = width*height
print ("Area of rectangle = ", area)
Now you can input any integer value to the two variables in the
program −
Enter width: 20
Enter height: 30
Area of rectangle = 600
The program ask user to enter amount and rate; and displays the result
as follows −
Enter Amount: 12500
Enter rate of interest: 6.5
Amount: 12500.0 Interest: 812.5
The print() Function
Python's print() function is a built-in function. It is the most frequently
used function that displays the value of a Python expression given in
parenthesis, on Python's console, or standard output (sys.stdout).
Open Compiler
print ("Hello World ")
The first call to print() displays a string literal and a string variable. The
second prints the value of two variables and their subtraction. The
pow() function computes the square root of a number and square
value of a variable.
Message Hello World
100 25.5 74.5
10.0 650.25
To make these two lines appear in the same line, define the end
parameter in the first print() function and set it to a whitespace string "
".
Open Compiler
city="Hyderabad"
state="Telangana"
country="India"
print("City:", city, end=" ")
print("State:", state)
Numbers
Python has built-in support to store and process numeric data (Python
Numbers). Most of the time you work with numbers in almost every
Python application. Obviously, any computer application deals with
numbers. This tutorial will discuss different types of Python Numbers
and their properties.
Python also has a built-in Boolean data type called bool. It can be
treated as a sub-type of int type, since its two possible values True
and False represent the integers 1 and 0 respectively.
Try out the following code snippet. It takes a Hexadecimal string, and
returns the integer.
Open Compiler
num_string = "A1"
number = int(num_string, 16)
print ("Hexadecimal:", num_string, "Integer:",number)
However, if the string contains any symbol apart from the Hexadecimal
symbol chart an error will be generated.
Open Compiler
num_string = "A1X001"
print (int(num_string, 16))
Python's standard library has a hex() function, with which you can
obtain a hexadecimal equivalent of an integer.
Open Compiler
a=hex(161)
print (a, type(a))
One more such entity is Nan (stands for Not a Number). It represents
any value that is undefined or not representable.
>>> a=float('Nan')
>>> a
Nan
Note that the real part as well as the coefficient of the imaginary part
have to be floats, and they may be expressed in standard decimal point
notation or scientific notation.
Python's complex() function helps in forming an object of complex
type. The function receives arguments for real and imaginary parts,
and returns the complex number.
There are two versions of complex() function, with two arguments and
with one argument. Use of complex() with two arguments is
straightforward. It uses the first argument as the real part and the
second as the coefficient of the imaginary part.
Open Compiler
a=complex(5.3,6)
b=complex(1.01E-2, 2.2E3)
print ("a:", a, "type:", type(a))
print ("b:", b, "type:", type(b))
Surprised by the above example? Put "x" as 1+2j and "y" as 2-3j. Try to
perform manual computation of "x+yj" and you'll come to know.
complex(1+2j, 2-3j)
=(1+2j)+(2-3j)*j
=1+2j +2j+3
=4+4j
If you use only one numeric argument for complex() function, it treats it
as the value of the real part; and the imaginary part is set to 0.
Open Compiler
a=complex(5.3)
print ("a:", a, "type:", type(a))
The complex() function can also parse a string into a complex number if
its only argument is a string having complex number representation.
In the following snippet, the user is asked to input a complex number. It
is used as an argument. Since Python reads the input as a string, the
function extracts the complex object from it.
Open Compiler
a= "5.5+2.3j"
b=complex(a)
print ("Complex number:", b)
Python's built-in complex class has two attributes real and imag −
they return the real and coefficient of the imaginary part from the
object.
Open Compiler
a=5+6j
print ("Real part:", a.real, "Coefficient of Imaginary part:", a.image)
1 math.ceil(x)
The ceiling of x: the smallest integer not less than x
2 math.comb(n,k)
This function is used to find the number of ways to choose "x"
items from "y" items without repetition and without order.
3 math.copysign(x, y)
This function returns a float with the magnitude (absolute
value) of x but the sign of y.
4 math.cmp(x, y)
This function is used to compare the values of to objects. This
function is deprecated in Python3.
5 math.fabs(x)
This function is used to calculate the absolute value of a given
integer.
6 math.factorial(n)
This function is used to find the factorial of a given integer.
7 math.floor(x)
This function calculates the floor value of a given integer.
8 math.fmod(x, y)
The fmod() function in the maths module returns the same
result as the "%" operator. However fmod() gives a more
accurate result of modulo division than modulo operator.
9 math.frexp(x)
This function is used to calculate the mantissa and exponent
of a given number.
10 math.fsum(iterable)
This function returns the floating point sum of all numeric
items in an iterable i.e. list, tuple, array.
11 math.gcd(*integers)
This function is used to calculate the greatest common divisor
of all the given integers.
12 math.isclose()
This function is used to determine whether two given numeric
values are close to each other.
13 math.isfinite(x)
This function is used to determine whether the given number
is a finite number.
14 math.isinf(x)
This function is used to determine whether the given value is
infinity (+ve or, -ve).
15 math.isnan(x)
This function is used to determine whether the given number
is "NaN".
16 math.sqrt(n)
This function calculates the integer square-root of the given
non negative integer.
17 math.lcm(*integers)
This function is used to calculate the least common factor of
the given integer arguments.
18 math.ldexp(x, i)
This function returns the product of the first number with the
exponent of the second number. So, ldexp(x,y) returns x*2**y.
This is the inverse of the frexp() function.
19 math.modf(x)
This returns the fractional and integer parts of x in a two-item
tuple.
20 math.nextafter(x, y, steps)
This function returns the next floating-point value after x
towards y.
21 math.perm(n, k)
This function is used to calculate the permutation. It returns
the number of ways to choose x items from y items without
repetition and with order.
22 math.prod(iterable, *, start)
This function is used to calculate the product of all numeric
items in the iterable (list, tuple) given as argument.
23 math.remainder(x,y)
This function returns the remainder of x with respect to y. This
is the difference x − n*y, where n is the integer closest to the
quotient x / y.
24 math.trunc(x)
This function returns an integral part of the number, removing
the fractional part. trunc() is equivalent to floor() for positive x,
and equivalent to ceil() for negative x.
25 math.ulp(x)
This function returns the value of the least significant bit of the
float x. trunc() is equivalent to floor() for positive x, and
equivalent to ceil() for negative x.
1 math.cbrt(x)
This function is used to calculate the cube root of a number.
2 math.exp(x)
This function calculate the exponential of x: ex
3 math.exp2(x)
This function returns 2 raised to power x. It is equivalent to
2**x.
4 math.expm1(x)
This function returns e raised to the power x, minus 1. Here e
is the base of natural logarithms.
5 math.log(x)
This function calculates the natural logarithm of x, for x> 0.
6 math.log1p(x)
This function returns the natural logarithm of 1+x (base e).
The result is calculated in a way which is accurate for x near
zero.
7 math.log2(x)
This function returns the base-2 logarithm of x. This is usually
more accurate than log(x, 2).
8 math.log10(x)
The base-10 logarithm of x for x> 0.
9 math.pow(x, y)
The value of x**y.
10 math.sqrt(x)
The square root of x for x > 0
Trigonometric Functions
Python includes following functions that perform trigonometric
calculations in the maths module −
1 math.acos(x)
This function returns the arc cosine of x, in radians.
2 math.asin(x)
This function returns the arc sine of x, in radians.
3 math.atan(x)
This function returns the arc tangent of x, in radians.
4 math.atan2(y, x)
This function returns atan(y / x), in radians.
5 math.cos(x)
This function returns the cosine of x radians.
6 math.sin(x)
This function returns the sine of x radians.
7 math.tan(x)
This function returns the tangent of x radians.
8 math.hypot(x, y)
This function returns the Euclidean norm, sqrt(x*x +
y*y).
1 math.degrees(x)
This function converts the given angle from radians to
degrees.
2 math.radians(x)
This function converts the given angle from degrees to
radians.
Mathematical Constants
The Python maths module defines the following mathematical
constants −
1 math.pi
This represents the mathematical constant pi, which equals
"3.141592..." to available precision.
2 math.e
This represents the mathematical constant e, which is equal to
"2.718281..." to available precision.
3 math.tau
This represents the mathematical constant Tau (denoted by τ
). It is equivalent to the ratio of circumference to radius, and is
equal to 2Π.
4 math.inf
This represents positive infinity. For negative infinity use
"−math.inf".
5 math.nan
This constant is a floating-point "not a number" (NaN) value.
Its value is equivalent to the output of float('nan').
Hyperbolic Functions
Hyperbolic functions are analogs of trigonometric functions that are
based on hyperbolas instead of circles. Following are the hyperbolic
functions of the Python maths module −
1 math.acosh(x)
This function is used to calculate the inverse hyperbolic cosine
of the given value.
2 math.asinh(x)
This function is used to calculate the inverse hyperbolic sine of
a given number.
3 math.atanh(x)
This function is used to calculate the inverse hyperbolic
tangent of a number.
4 math.cosh(x)
This function is used to calculate the hyperbolic cosine of the
given value.
5 math.sinh(x)
This function is used to calculate the hyperbolic sine of a given
number.
6 math.tanh(x)
This function is used to calculate the hyperbolic tangent of a
number.
Special Functions
Following are the special functions provided by the Python maths
module −
1 math.erf(x)
This function returns the value of the Gauss error function for
the given parameter.
2 math.erfc(x)
This function is the complement for the error function. Value of
erf(x) is equivalent to 1-erf(x).
3 math.gamma(x)
This is used to calculate the factorial of the complex numbers.
It is defined for all the complex numbers except the non-
positive integers.
4 math.lgamma(x)
This function is used to calculate the natural logarithm of the
absolute value of the Gamma function at x.
1 random.choice(seq)
A random item from a list, tuple, or string.
3 random.random()
A random float r, such that 0 is less than or equal to r and r is
less than 1
4 random.seed([x])
This function sets the integer starting value used in generating
random numbers. Call this function before calling any other
random module function. Returns None.
5 random.shuffle(seq)
This function is used to randomise the items of the given
sequence.
6 random.uniform(a, b)
This function returns a random floating point value r, such that
a is less than or equal to r and r is less than b.
Booleans
Python Booleans (bool)
In Python, bool is a subtype of int type. A bool object has two possible
values, and it is initialised with Python keywords, True and False.
Example
>>> a=True
>>> b=False
>>> type(a), type(b)
(<class 'bool'>, <class 'bool'>)
Example
Open Compiler
a=int(True)
print ("bool to int:", a)
a=float(False)
print ("bool to float:", a)
a=complex(True)
print ("bool to complex:", a)
Example
Open Compiler
# Check true
a = True
print(bool(a))
# Check false
a = False
print(bool(a))
# Check 0
a = 0.0
print(bool(a))
# Check 1
a = 1.0
print(bool(a))
# Check Equality
a=5
b = 10
print(bool( a==b))
# Check None
a = None
print(bool(a))
# Check an empty sequence
a = ()
print(bool(a))
# Check an empty mapping
a = {}
print(bool(a))
# Check a non empty string
a = 'Tutorialspoint'
print(bool(a))
Print Page
Control Flow
Python program control flow is regulated by various types of conditional
statements, loops, and function calls. By default, the instructions in a
computer program are executed in a sequential manner, from top to
bottom, or from start to end. However, such sequentially executing
programs can perform only simplistic tasks. We would like the program
to have a decision-making ability, so that it performs different steps
depending on different conditions.
Most programming languages including Python provide functionality to
control the flow of execution of instructions. Normally, there are two
types of control flow statements in any programming language and
Python also supports them.
The if Statements
Python provides if..elif..else control statements as a part of decision
making. It consists of three different blocks, which are if block, elif
(short of else if) block and else block.
Example
Following is a simple example which makes use of if..elif..else. You can
try to run this program using different marks and verify the result.
Open Compiler
marks = 80
result = ""
if marks < 30:
result = "Failed"
elif marks > 75:
result = "Passed with distinction"
else:
result = "Passed"
print(result)
Example
Following is a simple example which makes use of a match statement.
Open Compiler
def checkVowel(n):
match n:
case 'a': return "Vowel alphabet"
case 'e': return "Vowel alphabet"
case 'i': return "Vowel alphabet"
case 'o': return "Vowel alphabet"
case 'u': return "Vowel alphabet"
case _: return "Simple alphabet"
print (checkVowel('a'))
print (checkVowel('m'))
print (checkVowel('o'))
Example
Following is an example which makes use of While Loop to print first 5
numbers in Python:
Open Compiler
i=1
while i < 6:
print(i)
i += 1
Jump Statements
The jump statements are used to jump on a specific statement by
breaking the current flow of the program. In Python, there are two jump
statements: break and continue.
Example
The following example demonstrates the use of break statement −
Open Compiler
x=0
while x < 10:
print("x:", x)
if x == 5:
print("Breaking...")
break
x += 1
print("End")
Example
The following example demonstrates the use of continue statement −
Open Compiler
for letter in "Python":
# continue when letter is 'h'
if letter == "h":
continue
print("Current Letter :", letter)
Decision Making
Python's decision making functionality is in its keywords −
if..elif...else. The if keyword requires a boolean expression, followed
by colon (:) symbol. The colon (:) symbol starts an indented block. The
statements with the same level of indentation are executed if the
boolean expression in if statement is True. If the expression is not
True (False), the interpreter bypasses the indented block and proceeds
to execute statements at earlier indentation level.
Decision structures evaluate multiple expressions which produce TRUE
or FALSE as outcome. You need to determine which action to take and
which statements to execute if the outcome is TRUE or FALSE
otherwise.
Following is the general form of a typical decision making structure
found in most of the programming languages −
Python programming language assumes any non-zero and non-null
values as TRUE, and if it is either zero or null, then it is assumed as
FALSE value.
1 if statements
An if statement consists of a boolean expression followed by
one or more statements.
2 if...else statements
An if statement can be followed by an optional else
statement, which executes when the boolean expression is
FALSE.
3 nested if statements
You can use one if or else if statement inside another if or
else if statement(s).
Example
Here is an example of a one-line if clause −
Open Compiler
var = 100
if ( var == 100 ) : print ("Value of expression is 100")
print ("Good bye!")
if...else statement
In this decision making statement, if the if condition is true, then the
statements within this block are executed, otherwise, the else block is
executed.
The program will choose which block of code to execute based on
whether the condition in the if statement is true or false.
Example
The following example shows the use of if...else statement.
Open Compiler
var = 100
if ( var == 100 ):
print ("Value of var is equal to 100")
else:
print("Value of var is not equal to 100")
Nested if statements
A nested if is another decision making statement in which one if
statement resides inside another. It allows us to check multiple
conditions sequentially.
Example
In this example, we will see the use of nested-if statements.
Open Compiler
var = 100
if ( var == 100 ):
print("The number is equal to 100")
if var % 2 == 0:
print("The number is even")
else:
print("The given number is odd")
elif var == 0:
print("The given number is zero")
else:
print("The given number is negative")
if Statement
Python If Statement
The if statement in Python evaluates whether a condition is true or
false. It contains a logical expression that compares data, and a
decision is made based on the result of the comparison.
Change the variable amount to 800, and run the code again. This time,
no discount is applicable. And, you will get the following output −
amount = 800
Example
Suppose there are different slabs of discount on a purchase −
1. 20% on amount exceeding 10000,
2. 10% for amount between 5-10000,
3. 5% if it is between 1 to 5000.
4. no discount if amount<1000
We can write a Python code for the above logic with if-else
statements −
Open Compiler
amount = 2500
print('Amount = ',amount)
if amount > 10000:
discount = amount * 20 / 100
else:
if amount > 5000:
discount = amount * 10 / 100
else:
if amount > 1000:
discount = amount * 5 / 100
else:
discount = 0
print('Payable amount = ',amount - discount)
Set amount to test all possible conditions: 800, 2500, 7500 and
15000. The outputs will vary accordingly −
Amount: 800
Payable amount = 800
Amount: 2500
Payable amount = 2375.0
Amount: 7500
Payable amount = 6750.0
Amount: 15000
Payable amount = 12000.0
While the code will work perfectly fine, if you look at the increasing
level of indentation at each if and else statement, it will become
difficult to manage if there are still more conditions.
When you run the above code, it will display the following result −
num = 36
Divisible by 3 and 2
....execution ends....
Syntax
The syntax of the nested if construct with else condition will be like
this −
if expression1:
statement(s)
if expression2:
statement(s)
else
statement(s)
else:
if expression3:
statement(s)
else:
statement(s)
Example
Now let's take a Python code to understand how it works −
Open Compiler
num=8
print ("num = ",num)
if num%2==0:
if num%3==0:
print ("Divisible by 3 and 2")
else:
print ("divisible by 2 not divisible by 3")
else:
if num%3==0:
print ("divisible by 3 not divisible by 2")
else:
print ("not Divisible by 2 not divisible by 3")
Match-Case Statement
Python match-case Statement
A Python match-case statement takes an expression and compares its
value to successive patterns given as one or more case blocks. Only
the first pattern that matches gets executed. It is also possible to
extract components (sequence elements or object attributes) from the
value into variables.
With the release of Python 3.10, a pattern matching technique called
match-case has been introduced, which is similar to the switch-case
construct available in C/C++/Java etc. Its basic use is to compare a
variable against one or more values. It is more similar to pattern
matching in languages like Rust or Haskell than a switch statement in C
or C++.
Syntax
The following is the syntax of match-case statement in Python -
match variable_name:
case 'pattern 1' : statement 1
case 'pattern 2' : statement 2
...
case 'pattern n' : statement n
Example
The following code has a function named weekday(). It receives an
integer argument, matches it with all possible weekday number values,
and returns the corresponding name of day.
Open Compiler
def weekday(n):
match n:
case 0: return "Monday"
case 1: return "Tuesday"
case 2: return "Wednesday"
case 3: return "Thursday"
case 4: return "Friday"
case 5: return "Saturday"
case 6: return "Sunday"
case _: return "Invalid day number"
print (weekday(3))
print (weekday(6))
print (weekday(7))
The last case statement in the function has "_" as the value to
compare. It serves as the wildcard case, and will be executed if all
other cases are not true.
Example
The code below shows how to combine cases in a match statement. It
defines a function named access() and has one string argument,
representing the name of the user. For admin or manager users, the
system grants full access; for guests, the access is limited; and for the
rest, there's no access.
Open Compiler
def access(user):
match user:
case "admin" | "manager": return "Full access"
case "Guest": return "Limited access"
case _: return "No access"
print (access("manager"))
print (access("Guest"))
print (access("Ravi"))
Example
In this code, we use list as argument in match case statement.
Open Compiler
def greeting(details):
match details:
case [time, name]:
return Good {time} {name}!'
case [time, *names]:
msg=''
for name in names:
msg+=Good {time} {name}!\n'
return msg
print (greeting(["Morning", "Ravi"]))
print (greeting(["Afternoon","Guest"]))
print (greeting(["Evening", "Kajal", "Praveen", "Lata"]))
Example
In the following example, the function argument is a list of amount and
duration, and the interest is to be calculated for amounts less than or
more than 10000. The condition is included in the case clause.
Open Compiler
def intr(details):
match details:
case [amt, duration] if amt<10000:
return amt*10*duration/100
case [amt, duration] if amt>=10000:
return amt*15*duration/100
print ("Interest = ", intr([5000,5]))
print ("Interest = ", intr([15000,3]))
On executing, this code will produce the following output −
Interest = 2500.0
Interest = 6750.0
Loops
Python Loops
Python loops allow us to execute a statement or group of statements
multiple times.
In general, statements are executed sequentially: The first statement in
a function is executed first, followed by the second, and so on. There
may be a situation when you need to execute a block of code several
times.
Programming languages provide various control structures that allow
for more complicated execution paths.
Flowchart of a Loop
The following diagram illustrates a loop statement −
Types of Loops in Python
Python programming language provides following types of loops to
handle looping requirements −
1 while loop
Repeats a statement or group of statements while a given
condition is TRUE. It tests the condition before executing the
loop body.
2 for loop
Executes a sequence of statements multiple times and
abbreviates the code that manages the loop variable.
3 nested loops
You can use one or more loops inside any other while, for or
do..while loop.
1 break statement
Terminates the loop statement and transfers execution to the
statement immediately following the loop.
2 continue statement
Causes the loop to skip the remainder of its body and
immediately retest its condition prior to reiterating.
3 pass statement
The pass statement in Python is used when a statement is
required syntactically but you do not want any command or
code to execute.
For Loops
The for loop in Python provides the ability to loop over the items of
any sequence, such as a list, tuple or a string. It performs the same
action on each item of the sequence. This loop starts with the for
keyword, followed by a variable that represents the current item in the
sequence. The in keyword links the variable to the sequence you want
to iterate over. A colon (:) is used at the end of the loop header, and
the indented block of code beneath it is executed once for each item in
the sequence.
Example
The following example compares each character and displays if it is not
a vowel ('a', 'e', 'i', 'o', 'u').
Open Compiler
zen = '''
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
'''
for char in zen:
if char not in 'aeiou':
print (char, end='')
Example
In the following example, the for loop traverses a tuple containing
integers and returns the total of all numbers.
Open Compiler
numbers = (34,54,67,21,78,97,45,44,80,19)
total = 0
for num in numbers:
total += num
print ("Total =", total)
When you execute this code, it will show the following result −
34
54
78
44
80
Syntax
The range() function has the following syntax −
range(start, stop, step)
Where,
1. Start − Starting value of the range. Optional. Default is 0
2. Stop − The range goes upto stop-1
3. Step − Integers in the range increment by the step value.
Option, default is 1.
Example
In this example, we will see the use of range with for loop.
Open Compiler
for num in range(5):
print (num, end=' ')
print()
for num in range(10, 20):
print (num, end=' ')
print()
for num in range(1, 10, 2):
print (num, end=' ')
When you run the above code, it will produce the following output −
01234
10 11 12 13 14 15 16 17 18 19
13579
Example
Running a simple for loop over the dictionary object traverses the keys
used in it.
Open Compiler
numbers = {10:"Ten", 20:"Twenty", 30:"Thirty",40:"Forty"}
for x in numbers:
print (x)
Once we are able to get the key, its associated value can be easily
accessed either by using square brackets operator or with the get()
method.
Example
The following example illustrates the above mentioned approach.
Open Compiler
numbers = {10:"Ten", 20:"Twenty", 30:"Thirty",40:"Forty"}
for x in numbers:
print (x,":",numbers[x])
The items(), keys() and values() methods of dict class return the view
objects dict_items, dict_keys and dict_values respectively. These
objects are iterators, and hence we can run a for loop over them.
Example
The dict_items object is a list of key-value tuples over which a for loop
can be run as follows −
Open Compiler
numbers = {10:"Ten", 20:"Twenty", 30:"Thirty",40:"Forty"}
for x in numbers.items():
print (x)
Example
The following example illustrates the combination of an else statement
with a for statement that searches for prime numbers from 10 to 20.
Open Compiler
#For loop to iterate between 10 to 20
for num in range(10, 20):
#For loop to iterate on the factors
for i in range(2,num):
#If statement to determine the first factor
if num%i == 0:
#To calculate the second factor
j=num/i
print ("%d equals %d * %d" % (num,i,j))
#To move to the next number
break
else:
print (num, "is a prime number")
break
Example
In the following program, we use the for-else loop without a break
statement.
Open Compiler
for i in ['T','P']:
print(i)
else:
# Loop else statement
# there is no break statement in for loop, hence else part gets
executed directly
print("ForLoop-else statement successfully executed")
On executing, the above program will generate the following output −
T
P
ForLoop-else statement successfully executed
For-Else Construct with break statement
In case of forceful termination (by using break statement) of
the loop, the else statement is overlooked by the interpreter
and hence its execution is skipped.
Example
The following program shows how else conditions work in case of a
break statement.
Open Compiler
for i in ['T','P']:
print(i)
break
else:
# Loop else statement
# terminated after 1st iteration due to break statement in for loop
print("Loop-else statement successfully executed")
Example
The following program shows how other conditions work in case of
break statements and conditional statements.
Open Compiler
# creating a function to check whether the list item is a positive
# or a negative number
def positive_or_negative():
# traversing in a list
for i in [5,6,7]:
# checking whether the list element is greater than 0
if i>=0:
# printing positive number if it is greater than or equal to 0
print ("Positive number")
else:
# Else printing Negative number and breaking the loop
print ("Negative number")
break
# Else statement of the for loop
else:
# Statement inside the else block
print ("Loop-else Executed")
# Calling the above-created function
positive_or_negative()
While Loops
Example 1
The following example illustrates the working of a while loop. Here, the
iteration runs till the value of count will become 5.
Open Compiler
count=0
while count<5:
count+=1
print ("Iteration no. {}".format(count))
print ("End of while loop")
Example 2
Here is another example of using the while loop . For each iteration,
the program asks for user input and keeps repeating till the user inputs
a non-numeric string. The isnumeric() function returns true if input is an
integer, false otherwise.
var = '0'
while var.isnumeric() == True:
var = "test"
if var.isnumeric() == True:
print ("Your input", var)
print ("End of while loop")
Example
Let's take an example to understand how the infinite loop works in
Python −
var = 1
while var == 1 : # This constructs an infinite loop
num = int(input("Enter a number :"))
print ("You entered: ", num)
print ("Good bye!")
Example
The following example illustrates the combination of an else statement
with a while statement. Till the count is less than 5, the iteration count
is printed. As it becomes 5, the print statement in the else block is
executed, before the control is passed to the next statement in the
main program.
Open Compiler
count=0
while count<5:
count+=1
print ("Iteration no. {}".format(count))
else:
print ("While loop over. Now in else block")
print ("End of while loop")
On running the above code, it will print the following output −
Iteration no. 1
Iteration no. 2
Iteration no. 3
Iteration no. 4
Iteration no. 5
While loop over. Now in else block
End of while loop
Example
The following example shows how to use a one-line while clause.
Open Compiler
flag = 0
while (flag): print ("Given flag is really true!")
print ("Good bye!")
When you run this code, it will display the following output −
Good bye!
Change the flag value to "1" and try the above program. If you do so, it
goes into an infinite loop and you need to press CTRL+C keys to exit.
break Statement
Python break Statement
A Python break statement is used to terminate the current loop and
resumes execution at the next statement, just like the traditional break
statement in C.
The most common use for a Python break statement is when some
external condition is triggered requiring a sudden exit from a loop. The
break statement can be used in both Python while and for loops.
If you are using nested loops in Python, the break statement stops the
execution of the innermost loop and starts executing the next line of
code after the block.
Example
In this example, we will see the working of the break statement in the
for loop.
Open Compiler
for letter in 'Python':
if letter == 'h':
break
print ("Current Letter :", letter)
print ("Good bye!")
Example
The code below shows how to use break statements with a while loop.
Open Compiler
var = 10
while var > 0:
print ('Current variable value :', var)
var = var -1
if var == 5:
break
print ("Good bye!")
Example
The following program demonstrates the use of break in a for loop
iterating over a list. Here, the specified number will be searched in the
list. If it is found, then the loop terminates with the "found" message.
Open Compiler
no = 33
numbers = [11,33,55,39,55,75,37,21,23,41,13]
for num in numbers:
if num == no:
print ('number found in list')
break
else:
print ('number not found in list')
Example
Let's see an example to understand how the continue statement
works in a for loop.
Open Compiler
for letter in 'Python':
if letter == 'h':
continue
print ('Current Letter :', letter)
print ("Good bye!")
Assign different values (say 75) to num in the above program and test
the result for its prime factors.
Prime factors for: 75
3
5
5
pass Statement
Example
If you want to code an infinite loop that does nothing each time
through, do it as shown below −
while True: pass
# Type Ctrl-C to stop
Because the body of the loop is just an empty statement, Python gets
stuck in this loop.
Example
For example if we create a function which does not do anything
especially for code to be filled in later, then we can make use of ...
def func1():
# Alternative to pass
...
# Works on same line too
def func2(): ...
# Does nothing if called
func1()
func2()
Print Page
Nested Loops
In Python, when you write one or more loops within a loop statement
that is known as a nested loop. The main loop is considered as outer
loop and loop(s) inside the outer loop are known as inner loops.
The Python programming language allows the use of one loop inside
another loop. A loop is a code block that executes specific instructions
repeatedly. There are two types of loops, namely for and while, using
which we can create nested loops.
You can put any type of loop inside of any other type of loop. For
example, a for loop can be inside a while loop or vice versa.
Functions
A Python function is a block of organised, reusable code that is used to
perform a single, related action. Functions provide better modularity for
your application and a high degree of code reusing.
A top-to-down approach towards building the processing logic involves
defining blocks of independent reusable functions. A Python function
may be invoked from any other function by passing required data
(called parameters or arguments). The called function returns its
result back to the calling environment.
Types of Python Functions
Python provides the following types of functions −
1 Built-in functions
Python's standard library includes a number of built-in
functions. Some of Python's built-in functions are print(), int(),
len(), sum(), etc. These functions are always available, as they
are loaded into the computer's memory as soon as you start
the Python interpreter.
3 User-defined functions
In addition to the built-in functions and functions in the built-in
modules, you can also create your own functions. These
functions are called user-defined functions.
Example
In the following example, we are checking the id() of a variable.
Open Compiler
def testfunction(arg):
print ("ID inside the function:", id(arg))
var = "Hello"
print ("ID before passing:", id(var))
testfunction(var)
If the above code is executed, the id() before passing and inside the
function will be displayed.
ID before passing: 1996838294128
ID inside the function: 1996838294128
The behaviour also depends on whether the passed object is mutable
or immutable. Python numeric objects are immutable. When a numeric
object is passed, and then the function changes the value of the formal
argument, it actually creates a new object in the memory, leaving the
original variable unchanged.
Example
The following example shows how an immutable object behaves when
it is passed to a function.
Open Compiler
def testfunction(arg):
print ("ID inside the function:", id(arg))
arg = arg + 1
print ("new object after increment", arg, id(arg))
var=10
print ("ID before passing:", id(var))
testfunction(var)
print ("value after function call", var)
Example
Here we pass a list, append a new item, and see the contents of the
original list object, which we will find has changed.
Open Compiler
def testfunction(arg):
print ("Inside function:",arg)
print ("ID inside the function:", id(arg))
arg=arg.append(100)
var=[10, 20, 30, 40]
print ("ID before passing:", id(var))
testfunction(var)
print ("list after function call", var)
Example
Let's modify the greetings function and name an argument. A string
passed to the function as an actual argument becomes a name variable
inside the function.
Open Compiler
def greetings(name):
"This is docstring of greetings function"
print ("Hello {}".format(name))
return
greetings("Samay")
greetings("Pratima")
greetings("Steven")
Example
In the code below, we call the function printme() without any
parameters which will give error.
Open Compiler
# Function definition is here
def printme( str ):
"This prints a passed string into this function"
print (str)
return;
# Now you can call printme function
printme()
Keyword Arguments
Keyword arguments are related to the function calls. When you use
keyword arguments in a function call, the caller identifies the
arguments by the parameter name. This allows you to skip arguments
or place them out of order because the Python interpreter is able to use
the keywords provided to match the values with parameters.
Example 1
The following example shows how to use keyword arguments in Python.
Open Compiler
# Function definition is here
def printme( str ):
"This prints a passed string into this function"
print (str)
return;
# Now you can call printme function
printme( str = "My string")
Example 2
The following example gives a more clear picture. Note that the order
of parameters does not matter.
Open Compiler
# Function definition is here
def printinfo( name, age ):
"This prints a passed info into this function"
print ("Name: ", name)
print ("Age ", age)
return;
# Now you can call printinfo function
printinfo( age=50, name="miki" )
Default Arguments
A default argument is an argument that assumes a default value if a
value is not provided in the function call for that argument.
Example
The following example gives an idea on default arguments, it prints
default age if it is not passed −
Open Compiler
# Function definition is here
def printinfo( name, age = 35 ):
"This prints a passed info into this function"
print ("Name: ", name)
print ("Age ", age)
return;
# Now you can call printinfo function
printinfo( age=50, name="miki" )
printinfo( name="miki" )
Example
In the following example, we have defined two positional-only
arguments namely "x" and "y". This method should be called with
positional arguments in the order in which the arguments are declared,
otherwise, we will get an error.
Open Compiler
def posFun(x, y, /, z):
print(x + y + z)
print("Evaluating positional-only arguments: ")
posFun(33, 22, z=11)
Keyword-only arguments
Those arguments that must be specified by their name while calling the
function are known as Keyword-only arguments . They are defined
by placing an asterisk ("*") in the function's parameter list before any
keyword-only parameters. This type of argument can only be passed to
a function as a keyword argument, not a positional argument.
Example
In the code below, we have defined a function with three keyword-only
arguments. To call this method, we need to pass keyword arguments,
otherwise, we will encounter an error.
Open Compiler
def posFun(*, num1, num2, num3):
print(num1 * num2 * num3)
print("Evaluating keyword-only arguments: ")
posFun(num1=6, num2=8, num3=5)
An asterisk (*) is placed before the variable name that holds the values
of all non-keyword variable arguments. This tuple remains empty if no
additional arguments are specified during the function call.
Example
Following is a simple example of Python variable-length arguments.
Open Compiler
# Function definition is here
def printinfo( arg1, *vartuple ):
"This prints a variable passed arguments"
print ("Output is: ")
print (arg1)
for var in var tuple:
print (var)
return;
# Now you can call printinfo function
printinfo( 10 )
printinfo( 70, 60, 50 )
Example
Let us define the add() function. It adds the two values passed to it and
returns the addition. The returned value is stored in a variable called
result.
Open Compiler
def add(x,y):
z=x+y
return z
a=10
b=20
result = add(a,b)
print ("a = {} b = {} a+b = {}".format(a, b, result))
Syntax
The syntax of lambda functions contains only a single statement,
which is as follows −
lambda [arg1 [,arg2,.....argn]]:expression
Example
Following is the example to show how lambda form of function works −
Open Compiler
# Function definition is here
sum = lambda arg1, arg2: arg1 + arg2;
# Now you can call sum as a function
print ("Value of total : ", sum( 10, 20 ))
print ("Value of total : ", sum( 20, 20 ))
Scope of Variables
All variables in a program may not be accessible at all locations in that
program. This depends on where you have declared a variable.
The scope of a variable determines the portion of the program where
you can access a particular identifier. There are two basic scopes of
variables in Python −
Global variables
Local variables
Example
Following is a simple example of local and global scope −
Open Compiler
total = 0; # This is a global variable.
# Function definition is here
def sum( arg1, arg2 ):
# Add both the parameters and return them."
total = arg1 + arg2; # Here the total is a local variable.
print ("Inside the function local total : ", total)
return total;
# Now you can call sum function
sum( 10, 20 );
print ("Outside the function global total : ", total)
Default Arguments
Example
The code below explains how to use mutable objects as default
arguments in Python.
Open Compiler
def fcn(nums, numeric list = []):
numeric list.append(nums + 1)
print(numeric list)
# function calls
fcn(66)
fcn(68)
fcn(70)
Example
Let us try to understand with the help of following function definition −
Open Compiler
def division(num, den):
quotient = num/den
print ("num:{} den:{} quotient:{}".format(num, den, quotient))
division(10,5)
division(5,10)
Since the values are assigned as per the position, the output is as
follows −
num:10 den:5 quotient:2.0
num:5 den:10 quotient:0.5
Example
Instead of passing the values with positional arguments, let us call the
function with keyword arguments −
Open Compiler
def division(num, den):
quotient = num/den
print ("num:{} den:{} quotient:{}".format(num, den, quotient))
division(num=10, den=5)
division(den=5, num=10)
Keyword-Only Arguments
Keyword-Only Arguments
You can use the variables in the formal argument list as keywords to
pass value. Use of keyword arguments is optional. But, you can force
the function to accept arguments by keyword only. You should put an
asterisk (*) before the keyword-only arguments list.
Let us say we have a function with three arguments, out of which we
want second and third arguments to be keyword-only. For that, put *
after the first argument.
It will print −
Hello-World
Example
In the following user defined function "intr()" the "rate" argument is
keyword-only. To call this function, the value for rate must be passed
by keyword.
Open Compiler
def intr(amt,*, rate):
val = amt*rate/100
return val
interest = intr(1000, rate=10)
print(interest)
100.0
However, if you try to use the default positional way of calling the
above function, you will encounter an error.
Example
The code below shows it is not possible to use positional arguments
when keyword-only arguments are required.
Open Compiler
def intr(amt, *, rate):
val = amt * rate / 100
return val
interest = intr(1000, 10)
print(interest)
Positional Arguments
Positional Arguments
The list of variables declared in the parentheses at the time of defining
a function are the formal arguments . And, these arguments are also
known as positional arguments . A function may be defined with any
number of formal arguments.
While calling a function −
1. All the arguments are required.
2. The number of actual arguments must be equal to the number
of formal arguments.
3. They Pick up values in the order of definition.
4. The type of arguments must match.
5. Names of formal and actual arguments need not be the same.
Positional Arguments Examples
Let's discuss some examples of Positional arguments −
Example 1
The following example shows the use of positional argument.
Open Compiler
def add(x,y):
z = x+y
print ("x={} y={} x+y={}".format(x,y,z))
a = 10
b = 20
add(a, b)
Here, the add() function has two formal arguments, both are numeric.
When integers 10 and 20 passed to it. The variable "a" takes 10 and
"b" takes 20, in the order of declaration. The add() function displays
the addition.
Example 2
Python also raises errors when the number of arguments don't match. If
you give only one argument and check the result you can see an error.
Open Compiler
def add(x,y):
z=x+y
print (z)
a=10;
add(a)
Example 3
Similarly, if you pass more than the number of formal arguments an
error will be generated stating the same −
Open Compiler
def add(x,y):
z=x+y
print ("x={} y={} x+y={}".format(x,y,z))
add(10, 20, 30)
Example 4
Data type of corresponding actual and formal arguments must match.
Change a to a string value and see the result.
Open Compiler
def add(x,y):
z=x+y
print (z)
a="Hello"
b=20
add(a,b)
Positional-Only Arguments
Example
In this example, we are using the prompt keyword, which will lead to
error.
Open Compiler
name = input(prompt="Enter your name ")
On executing, this code will show the following error message −<>
name = input (prompt="Enter your name ")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: input() takes no keyword arguments
Positional-Only Arguments Examples
Let's understand positional-only arguments with the help of some
examples −
Example 1
In this example, we make both the arguments of intr() function as
positional-only by putting "/" at the end.
Open Compiler
def intr(amt, rate, /):
val = amt * rate / 100
return val
print(intr(316200, 4))
When you run the code, it will show the following result −
12648.0
Example 2
If we try to use the arguments as keywords, Python raises errors as
shown in the below example.
Open Compiler
def intr(amt, rate, /):
val = amt * rate / 100
return val
print(intr(amt=1000, rate=10))
Example 3
A function may be defined in such a way that it has some keyword-only
and some positional-only arguments. Here, x is a required positional-
only argument, y is a regular positional argument, and z is a
keyword-only argument.
Open Compiler
def myfunction(x, /, y, *, z):
print (x, y, z)
myfunction(10, y=20, z=30)
myfunction(10, 20, z=30)
The args variable prefixed with "*" stores all the values passed to it.
Here, args becomes a tuple. We can run a loop over its items to add the
numbers.
It will produce the following output −
100
6
Example
The following example has an avg() function. Assume that a student
can take any number of tests. First test is mandatory. He can take as
many tests as he likes to improve his score. The function calculates the
average of marks in the first test and his maximum score in the rest of
tests.
The function has two arguments, first is the required argument and
second to hold any number of values.
Open Compiler
#avg of first test and best of following tests
def avg(first, *rest):
second=max(rest)
return (first+second)/2
result=avg(40,30,50,25)
print (result)
Following call to avg() function passes the first value to the required
argument first, and the remaining values to a tuple named rest. We
then find the maximum and use it to calculate the average.
It will produce the following output −
45.0
Example
The following code is an example of a function with arbitrary keyword
arguments. The addr() function has an argument **kwargs which is
able to accept any number of address elements like name, city, phno,
pin, etc. Inside the function kwargs dictionary of kw:value pairs is
traversed using items() method.
Open Compiler
def addr(**kwargs):
for k,v in kwargs.items():
print ("{}:{}".format(k,v))
print ("pass two keyword args")
addr(Name="John", City="Mumbai")
print ("pass four keyword args")
# pass four keyword args
addr(Name="Raam", City="Mumbai", ph_no="9123134567",
PIN="400001")
Example
Imagine a case where science and maths are mandatory subjects, in
addition to which students may choose any number of elective
subjects.
The following code defines a percent() function where marks in
science and marks are stored in required arguments, and the marks in
variable number of elective subjects in **optional argument.
Open Compiler
def percent(maths, sci, **optional):
print ("maths:", maths)
print ("sci:", sci)
s=maths+sci
for k,v in optional.items():
print ("{}:{}".format(k,v))
s=s+v
return s/(len(optional)+2)
result=percent(maths=80, sci=75, Eng=70, Hist=65, Geo=72)
print ("percentage:", result)
Local Variables
A local variable is defined within a specific function or block of code. It
can only be accessed by the function or block where it was defined,
and it has a limited scope. In other words, the scope of local variables
is limited to the function they are defined in and attempting to access
them outside of this function will result in an error. Always remember,
multiple local variables can exist with the same name.
Example
The following example shows the scope of local variables.
Open Compiler
def myfunction():
a = 10
b = 20
print("variable a:", a)
print("variable b:", b)
return a+b
print (myfunction())
In the above code, we have accessed the local variables through its
function. Hence, the code will produce the following output −
variable a: 10
variable b: 20
30
Global Variables
A global variable can be accessed from any part of the program, and it
is defined outside any function or block of code. It is not specific to any
block or function.
Example
The following example shows the scope of global variables. We can
access them inside as well as outside of the function scope.
Open Compiler
#global variables
name = 'TutorialsPoint'
marks = 50
def myfunction():
# accessing inside the function
print("name:", name)
print("marks:", marks)
# function call
myfunction()
Nonlocal Variables
The Python variables that are not defined in either local or global scope
are called nonlocal variables. They are used in nested functions.
Example
The following example demonstrates how nonlocal variables work.
Open Compiler
def yourfunction():
a=5
b=6
# nested function
def myfunction():
# nonlocal function
nonlocal a
nonlocal b
a = 10
b = 20
print("variable a:", a)
print("variable b:", b)
return a+b
print (myfunction())
yourfunction()
These namespaces are nested one inside the other. Following diagram
shows the relationship between namespaces.
The life of a certain variable is restricted to the namespace in which it
is defined. As a result, it is not possible to access a variable present in
the inner namespace from any outer namespace.
It can be seen that the built-in module which contains definitions of all
built-in functions and built-in exceptions is loaded.
Example
Save the following code that contains few variables and a function with
few more variables inside it.
Open Compiler
name = 'TutorialsPoint'
marks = 50
result = True
def myfunction():
a = 10
b = 20
return a+b
print (globals())
The global namespace now contains variables in the program and their
values and the function object in it (and not the variables in the
function).
Example
Modify the above script to print a dictionary of global and local
namespaces from within the function.
Open Compiler
name = 'TutorialsPoint'
marks = 50
result = True
def myfunction():
a = 10
b = 20
c = a+b
print ("globals():", globals())
print ("locals():", locals())
return c
myfunction()
Since both globals() and locals functions return a dictionary, you can
access the value of a variable from the respective namespace with the
dictionary get() method or index operator.
print (globals()['name']) # displays TutorialsPoint
print (locals().get('a')) # displays 10
Example
In the following example, we define a local and a global variable.
Open Compiler
marks = 50 # this is a global variable
def myfunction():
marks = 70 # this is a local variable
print (marks)
myfunction()
print (marks) # prints global value
It will produce the following output −
70
50
Example
If you try to manipulate value of a global variable from inside a
function, Python raises UnboundLocalError as shown in example
below −
Open Compiler
# this is a global variable
marks = 50
def myfunction():
marks = marks + 20
print (marks)
myfunction()
# prints global value
print (marks)
Example
To modify a global variable, you can either update it with a dictionary
syntax, or use the global keyword to refer to it before modifying.
Open Compiler
var1 = 50 # this is a global variable
var2 = 60 # this is a global variable
def myfunction():
"Change values of global variables"
globals()['var1'] = globals()['var1']+10
global var2
var2 = var2 + 20
myfunction()
print ("var1:",var1, "var2:",var2) #shows global variables with changed
values
Example
Lastly, if you try to access a local variable in global scope, Python
raises NameError as the variable in local scope can't be accessed
outside it.
Open Compiler
var1 = 50 # this is a global variable
var2 = 60 # this is a global variable
def myfunction(x, y):
total = x+y
print ("Total is a local variable: ", total)
myfunction(var1, var2)
print (total) # This gives NameError
Function Annotations
Function Annotations
The function annotation feature of Python enables you to add
additional explanatory metadata about the arguments declared in a
function definition, and also the return data type. They are not
considered by the Python interpreter while executing the function. They
are mainly for the Python IDEs for providing detailed documentation to
the programmer.
Although you can use the docstring feature of Python for
documentation of a function, it may be obsolete if certain changes in
the function's prototype are made. Hence, the annotation feature was
introduced in Python as a result of PEP 3107.
Annotations are any valid Python expressions added to the arguments
or return data type. Simplest example of annotation is to prescribe the
data type of the arguments. Annotation is mentioned as an expression
after putting a colon in front of the argument.
Example
Remember that Python is a dynamically typed language, and doesn't
enforce any type checking at runtime. Hence annotating the arguments
with data types doesn't have any effect while calling the function. Even
if non-integer arguments are given, Python doesn't detect any error.
Open Compiler
def myfunction(a: int, b: int):
c = a+b
return c
print (myfunction(10,20))
print (myfunction("Hello ", "Python"))
Example
In this example, we are providing annotation for return type.
Open Compiler
def myfunction(a: int, b: int) -> int:
c = a+b
return c
print(myfunction(56,88))
print(myfunction.__annotations__)
Example
In the below example, we are using expression as a function
annotation.
Open Compiler
def total(x : 'marks in Physics', y: 'marks in chemistry'):
return x+y
print(total(86, 88))
print(total.__annotations__)
Example 1
The following example demonstrates how to provide annotation for
default arguments of a function.
def myfunction(a: "physics", b:"Maths" = 20) -> int:
c = a+b
return c
print (myfunction(10))
Example 2
The __annotations__ attribute itself is a dictionary in which arguments
are keys and annotations their values.
Open Compiler
def myfunction(a: "physics", b:"Maths" = 20) -> int:
c = a+b
return c
print (myfunction.__annotations__)
Example 3
You may have arbitrary positional and/or arbitrary keyword arguments
for a function. Annotations can be given for them also.
Open Compiler
def myfunction(*args: "arbitrary args", **kwargs: "arbitrary keyword
args") -> int:
pass
print (myfunction.__annotations__)
Example 4
In case you need to provide more than one annotation expression to a
function argument, give it in the form of a dictionary object in front of
the argument itself.
Open Compiler
def division(num: dict(type=float, msg='numerator'), den:
dict(type=float, msg='denominator')) -> float:
return num/den
print (division.__annotations__)
Modules
Python Modules
The concept of modules in Python further enhances the modularity.
You can define more than one related function together and load
required functions. A module is a file containing definitions of functions,
classes, variables, constants or any other Python object. Contents of
this file can be made available to any other program. Python has the
import keyword for this purpose.
A function is a block of organised, reusable code that is used to perform
a single, related action. Functions provide better modularity for your
application and a high degree of code reusing.
1 os
This module provides a unified interface to a number of
operating system functions.
2 string
This module contains a number of functions for string
processing
3 re
This module provides a set of powerful regular expression
facilities. Regular expression (RegEx), allows powerful string
search and matching for a pattern in a string
4 maths
This module implements a number of mathematical operations
for floating point numbers. These functions are generally thin
wrappers around the platform C library functions.
5 cmath
This module contains a number of mathematical operations for
complex numbers.
6 datetime
This module provides functions to deal with dates and the time
within a day. It wraps the C runtime library.
7 gc
This module provides an interface to the built-in garbage
collector.
8 asyncio
This module defines functionality required for asynchronous
processing
9 Collections
This module provides advanced Container data types.
10 functools
This module has Higher-order functions and operations on
callable objects. Useful in functional programming
11 operator
Functions corresponding to the standard operators.
12 pickle
Convert Python objects to streams of bytes and back.
13 socket
Low-level networking interface.
14 sqlite3
A DB-API 2.0 implementation using SQLite 3.x.
15 statistics
Mathematical statistics functions
16 typing
Support for type hints
17 venv
Creation of virtual environments.
18 json
Encode and decode the JSON format.
19 wsgiref
WSGI Utilities and Reference Implementation.
20 unittest
Unit testing framework for Python.
21 random
Generate pseudo-random numbers
22 sys
Provides functions that act strongly with the interpreter.
23 requests
It simplifies HTTP requests by offering a user-friendly interface
for sending and handling responses.
To call any function, use the module object's reference. For example,
mymodule.sum().
import mymodule
print ("sum:",mymodule.sum(10,20))
print ("average:",mymodule.average(10,20))
print ("power:",mymodule.power(10, 2))
Note that function need not be called by prefixing the name of its
module to it.
This provides an easy way to import all the items from a module into
the current namespace; however, this statement should be used
sparingly.
Locating Modules
When you import a module, the Python interpreter searches for the
module in the following sequences −
1. The current directory.
2. If the module isn't found, Python then searches each directory
in the shell variable PYTHONPATH.
3. If all else fails, Python checks the default path. On UNIX, this
default path is normally /usr/local/lib/python/.
The module search path is stored in the system module sys as the
sys.path variable. The sys.path variable contains the current directory,
PYTHONPATH, and the installation-dependent default.
Example
For example, we define a variable Money in the global namespace.
Within the function Money, we assign Money a value, therefore Python
assumes Money as a local variable. However, we assessed the value of
the local variable Money before setting it, so an UnboundLocalError is
the result. Uncommenting the global statement fixes the problem.
Open Compiler
Money = 2000
def AddMoney():
# Uncomment the following line to fix the code:
# global Money
Money = Money + 1
print (Money)
AddMoney()
print (Money)
Module Attributes
In Python, a module is an object of module class, and hence it is
characterised by attributes.
Following are the module attributes −
1. __file__ returns the physical name of the module.
2. __package__ returns the package to which the module
belongs.
3. __doc__ returns the docstring at the top of the module if any
4. __dict__ returns the entire scope of the module
5. __name__ returns the name of the module
Example
Assuming that the following code is saved as mymodule.py
"The docstring of mymodule"
def sum(x,y):
return x+y
def average(x,y):
return (x+y)/2
def power(x,y):
return x**y
The __name__Attribute
The __name__ attribute of a Python module has great significance. Let
us explore it in more detail.
In an interactive shell, __name__ attribute returns '__main__'
>>> __name__
'__main__'
If you import any module in the interpreter session, it returns the name
of the module as the __name__ attribute of that module.
>>> import maths
>>> maths.__name__
'maths'
From inside a Python script, the __name__ attribute returns '__main__'
#example.py
print ("__name__ attribute within a script:", __name__)
You can see that sum() function is called within the same script in
which it is defined.
sum: 30
Now if you run example.py program, you will find that the sum:30
output appears only once.
sum: 30
We can import the module and call its function from Python prompt as
−
>>> import test
>>> test.SayHello("Deepak")
Hi Deepak! How are you?
Even if you edit the test.py file and save it, the function loaded in the
memory won't update. You need to reload it, using the reload() function
in the imp module.
>>> import imp
>>> imp.reload(test)
>>> test.SayHello("Deepak", "Python")
Hi Deepak! How are you?
Welcome to Python Tutorial by TutorialsPoint
Packages in Python
A package is a hierarchical file directory structure that defines a single
Python application environment that consists of modules, subpackages,
sub-subpackages, and so on.
Consider a file Pots.py available in the Phone directory. This file has
following line of source code −
def Pots():
print "I'm Pots Phone"
Similar way, we have another two files having different functions with
the same name as above −
Phone/Isdn.py file having function Isdn()
Phone/G3.py file having function G3()
After you add these lines to __init__.py, you have all of these classes
available when you import the Phone package.
# Now import your Phone Package.
import Phone
Phone.Pots()
Phone.Isdn()
Phone.G3()
Built-in Functions
Built-in Functions in Python?
Built-in functions are those functions that are pre-defined in the
Python interpreter and you don't need to import any module to use
them. These functions help to perform a wide variety of operations on
strings, iterators, and numbers. For instance, the built-in functions like
sum(), min(), and max() are used to simplify mathematical operations.
In the above example, we are using two built-in functions print() and
len().
Strings
In Python, a string is an immutable sequence of Unicode characters.
Each character has a unique numeric value as per the UNICODE
standard. But, the sequence as a whole, doesn't have any numeric
value even if all the characters are digits. To differentiate the string
from numbers and other identifiers, the sequence of characters is
included within single, double or triple quotes in its literal
representation. Hence, 1234 is a number (integer) but '1234' is a
string.
Example
>>> 'Welcome To TutorialsPoint'
'Welcome To TutorialsPoint'
>>> "Welcome To TutorialsPoint"
'Welcome To TutorialsPoint'
>>> '''Welcome To TutorialsPoint'''
'Welcome To TutorialsPoint'
>>> """Welcome To TutorialsPoint"""
'Welcome To TutorialsPoint'
Updating Strings
You can "update" an existing string by (re)assigning a variable to
another string. The new value can be related to its previous value or to
a completely different string altogether. For example −
Open Compiler
var1 = 'Hello World!'
print ("Updated String :- ", var1[:6] + 'Python')
Escape Characters
Following table is a list of escape or non-printable characters that can
be represented with backslash notation.
An escape character gets interpreted; in single quoted as well as
double quoted strings.
\b 0x08 Backspace
\cx Control-x
\C-x Control-x
\e 0x1b Escape
\M-\C-x Meta-Control-x
\n 0x0a Newline
\s 0x20 Space
\t 0x09 Tab
\x Character x
+ a + b will
Concatenation - Adds values on either side
give
of the operator
HelloPython
[:] Range Slice - Gives the characters from the a[1:4] will
given range give ell
% See at next
Format - Performs String formatting
section
Here is the list of complete set of symbols which can be used along
with % −
1 %c
character
2 %s
string conversion via str() prior to
formatting
3 %i
signed decimal integer
4 %d
signed decimal integer
5 %u
unsigned decimal integer
6 %o
octal integer
7 %x
hexadecimal integer (lowercase letters)
8 %X
hexadecimal integer (UPPERcase letters)
9 %e
exponential notation (with lowercase 'e')
10 %E
exponential notation (with UPPERcase 'E')
11 %f
floating point real number
12 %g
the shorter of %f and %e
13 %G
the shorter of %f and %E
1 *
argument specifies width or precision
2 -
left justification
3 +
display the sign
4 <sp>
leave a blank space before a positive number
5 #
add the octal leading zero ( '0' ) or hexadecimal leading '0x' or
'0X', depending on whether 'x' or 'X' were used.
6 0
pad from left with zeros (instead of spaces)
7 %
'%%' leaves you with a single literal '%'
8 (var)
mapping variable (dictionary arguments)
9 m.n.
m is the minimum total width and n is the number of digits to
display after the decimal point (if appl.)
Visit our Python - String Formatting tutorial to learn about various ways
to format strings.
Example
Open Compiler
var = 'Welcome to "Python Tutorial" from TutorialsPoint'
print ("var:", var)
var = "Welcome to 'Python Tutorial' from TutorialsPoint"
print ("var:", var)
Triple Quotes
To form a string with triple quotes, you may use triple single quotes, or
triple double quotes − both versions are similar.
Example
Open Compiler
var = '''Welcome to TutorialsPoint'''
print ("var:", var)
var = """Welcome to TutorialsPoint"""
print ("var:", var)
Example
Open Compiler
var = "Welcome To TutorialsPoint"
print (type(var))
It will produce the following output −
<class 'str'>
1 capitalise()
Capitalises the first letter of the string.
2 casefold()
Converts all uppercase letters in string to lowercase. Similar to
lower(), but works on UNICODE characters alos.
3 centre(width, fillchar)
Returns a space-padded string with the original string centred
to a total of width columns.
5 decode(encoding='UTF-8',errors='strict')
Decodes the string using the codec registered for encoding.
encoding defaults to the default string encoding.
6 encode(encoding='UTF-8',errors='strict')
Returns an encoded string version of string; on error, default is
to raise a ValueError unless errors are given with 'ignore' or
'replace'.
8 expandtabs(tab size=8)
Expands tabs in string to multiple spaces; defaults to 8 spaces
per tab if tab size is not provided.
10 format(*args, **kwargs)
This method is used to format the current string value.
11 format_map(mapping)
This method is also used to format the current string; the only
difference is it uses a mapping object.
13 isalnum()
Returns true if the string has at least 1 character and all
characters are alphanumeric and false otherwise.
14 isalpha()
Returns true if the string has at least 1 character and all
characters are alphabetic and false otherwise.
15 isascii()
Returns True is all the characters in the string are from the
ASCII character set.
16 isdecimal()
Returns true if a unicode string contains only decimal
characters and false otherwise.
17 isdigit()
Returns true if the string contains only digits and false
otherwise.
18 isidentifier()
Checks whether the string is a valid Python identifier.
19 islower()
Returns true if the string has at least 1 cased character and all
cased characters are in lowercase and false otherwise.
20 isnumeric()
Returns true if a unicode string contains only numeric
characters and false otherwise.
21 isprintable()
Checks whether all the characters in the string are printable.
22 isspace()
Returns true if the string contains only whitespace characters
and false otherwise.
23 istitle()
Returns true if the string is properly "titlecased" and false
otherwise.
24 isupper()
Returns true if the string has at least one cased character and
all cased characters are in uppercase and false otherwise.
25 join(seq)
Merges (concatenates) the string representations of elements
in sequence seq into a string, with separator string.
26 ljust(width[, fillchar])
Returns a space-padded string with the original string left-
justified to a total of width columns.
27 lower()
Converts all uppercase letters in string to lowercase.
28 lstrip()
Removes all leading white space in string.
29 maketrans()
Returns a translation table to be used in the translation
function.
30 partition()
Splits the string in three string tuples at the first occurrence of
separator.
31 remove prefix()
Returns a string after removing the prefix string.
32 remove suffix()
Returns a string after removing the suffix string.
34 rfind(str, beg=0,end=len(string))
Same as find(), but search backwards in string.
36 rjust(width,[, fillchar])
Returns a space-padded string with the original string right-
justified to a total of width columns.
37 rpartition()
Splits the string in three string tuples at the last occurrence of
the separator.
38 rsplit()
Splits the string from the end and returns a list of substrings.
39 rstrip()
Removes all trailing whitespace of string.
40 split(str="", num=string.count(str))
Splits string according to delimiter str (space if not provided)
and returns list of substrings; split into at most num substrings
if given.
41 splitlines( num=string.count('\n'))
Splits string at all (or num) NEWLINEs and returns a list of each
line with NEWLINEs removed.
42 startswith(str, beg=0,end=len(string))
Determines if string or a substring of string (if starting index
beg and ending index end are given) starts with substring str;
returns true if so and false otherwise.
43 strip([chars])
Performs both lstrip() and rstrip() on string.
44 swapcase()
Inverts case for all letters in string.
45 title()
Returns a "titlecased" version of string, that is, all words begin
with uppercase and the rest are lowercase.
46 translate(table, deletechars="")
Translates string according to translation table str(256 chars),
removing those in the del string.
47 upper()
Converts lowercase letters in string to uppercase.
48 zfill (width)
Returns original string left padded with zeros to a total of
width characters; intended for numbers, zfill() retains any sign
given (less one zero).
1 len(list)
Returns the length of the string.
2 max(list)
Returns the max alphabetical character from the string
str.
3 min(list)
Returns the min alphabetical character from the string
str.
Python Slicing Strings
Python String slicing is a way of creating a sub-string from a given
string. In this process, we extract a portion or piece of a string. Usually,
we use the slice operator "[ : ]" to perform slicing on a Python String.
Before proceeding with string slicing let's understand string indexing.
In Python, a string is an ordered sequence of Unicode characters. Each
character in the string has a unique index in the sequence. The index
starts with 0. First character in the string has its positional index 0. The
index keeps incrementing towards the end of the string.
If a string variable is declared as var="HELLO PYTHON", index of each
character in the string is as follows −
Example
In the below example, we access the characters of a string through an
index.
Open Compiler
var = "HELLO PYTHON"
print(var[0])
print(var[7])
print(var[11])
print(var[12])
On running the code, it will produce the following output −
H
Y
N
ERROR!
Traceback (most recent call last):
File "<main.py>", line 5, in <module>
IndexError: string index out of range
Example
Let us use negative indexing to fetch N, Y, and H characters.
Open Compiler
var = "HELLO PYTHON"
print(var[-1])
print(var[-5])
print(var[-12])
Example
In the following example, character Y is at index 7 in HELLO PYTHON.
Try to replace Y with y and see what happens.
Open Compiler
var="HELLO PYTHON"
var[7]="y"
print (var)
The ":" operator needs two integer operands (both of which may be
omitted, as we shall see in subsequent examples). The first operand x
is the index of the first character of the desired slice. The second
operand y is the index of the character next to the last in the desired
string. So var(x:y] separates characters from nth position to (y-1)th
position from the original string.
Example
Open Compiler
var="HELLO PYTHON"
print ("var:",var)
print ("var[3:8]:", var[3:8])
Example
The below example shows how to slice a string using negative indexes.
Open Compiler
var="HELLO PYTHON"
print ("var:",var)
print ("var[3:8]:", var[3:8])
print ("var[-9:-4]:", var[-9:-4])
Example
In this example, we are performing slice operations using default
values.
Open Compiler
var="HELLO PYTHON"
print ("var:",var)
print ("var[0:5]:", var[0:5])
print ("var[:5]:", var[:5])
Example
Similarly, y operand is also optional. By default, it is "-1", which means
the string will be sliced from the nth position up to the end of the
string.
Open Compiler
var="HELLO PYTHON"
print ("var:",var)
print ("var[6:12]:", var[6:12])
print ("var[6:]:", var[6:])
Example
Naturally, if both the operands are not used, the slice will be equal to
the original string. That's because "x" is 0, and "y" is the last index+1
(or -1) by default.
Open Compiler
var="HELLO PYTHON"
print ("var:",var)
print ("var[0:12]:", var[0:12])
print ("var[:]:", var[:])
Example
The left operand must be smaller than the operand on right, for getting
a substring of the original string. Python doesn't raise any error, if the
left operand is greater, but returns a null string.
Open Compiler
var="HELLO PYTHON"
print ("var:",var)
print ("var[-1:7]:", var[-1:7])
print ("var[7:0]:", var[7:0])
Example
Open Compiler
var="HELLO PYTHON"
print ("var:",var)
print ("var[:6][:2]:", var[:6][:2])
var1=var[:6]
print ("slice:", var1)
print ("var1[:2]:", var1[:2])
It will produce the following output −
var: HELLO PYTHON
var[:6][:2]: HE
slice: HELLO
var1[:2]: HE
Modify Strings
String modification refers to the process of changing the characters
of a string. If we talk about modifying a string in Python, what we are
talking about is creating a new string that is a variation of the original
one.
In Python, a string (object of str class) is of immutable type. Here,
immutable refers to an object that cannot be modified in place once it's
created in memory. Unlike a list, we cannot overwrite any character in
the sequence, nor can we insert or append characters to it directly. If
we need to modify a string, we will use certain string methods that
return a new string object. However, the original string remains
unchanged.
We can use any of the following tricks as a workaround to modify a
string.
Example
The below example practically illustrates how to convert a string into a
list.
Open Compiler
s1="WORD"
print ("original string:", s1)
l1=list(s1)
l1.insert(3,"L")
print (l1)
s1=''.join(l1)
print ("Modified string:", s1)
Example
In the below example, we are using an array module to modify the
specified string.
Open Compiler
import array as ar
# initialising a string
s1="WORD"
print ("original string:", s1)
# converting it to an array
sar=ar.array('u', s1)
# inserting an element
sar.insert(3,"L")
# getting back the modified string
s1=sar.tounicode()
print ("Modified string:", s1)
Example
Let us use the above discussed principle in the following program to
modify a string.
Open Compiler
import io
s1="WORD"
print ("original string:", s1)
sio=io.StringIO(s1)
sio.seek(3)
sio.write("LD")
s1=sio.getvalue()
print ("Modified string:", s1)
String Concatenation
Concatenate Strings in Python
String concatenation in Python is the operation of joining two or
more strings together. The result of this operation will be a new string
that contains the original strings. The diagram below shows a general
string concatenation operation −
Example
The following example shows string concatenation operation in Python
using + operator.
Open Compiler
str1="Hello"
str2="World"
print ("String 1:",str1)
print ("String 2:",str2)
str3=str1+str2
print("String 3:",str3)
Example
In the below example, we are inserting space between two strings
while concatenation.
Open Compiler
str1="Hello"
str2="World"
blank=" "
print ("String 1:",str1)
print ("String 2:",str2)
str3=str1+blank+str2
print("String 3:",str3)
Example
In the below example, we are concatenating strings using the + and *
operator together.
str1="Hello"
str2="World"
print ("String 1:",str1)
print ("String 2:",str2)
str3=str1+str2*3
print("String 3:",str3)
str4=(str1+str2)*3
print ("String 4:", str4)
In the second case, the strings str1 and str2 are inside parentheses,
hence their concatenation takes place first. Its result is then replicated
three times.
String 4: HelloWorldHelloWorldHelloWorld
Apart from + and *, no other arithmetic operators can be used with
string operands.
String Formatting
String formatting in Python is the process of building a string
representation dynamically by inserting the value of numeric
expressions in an already existing string. Python's string concatenation
operator doesn't accept a non-string operand. Hence, Python offers
following string formatting techniques −
1. Using % operator
2. Using format() method of str class
3. Using f-string
4. Using String Template class
Using % operator
The "%" (modulo) operator is often referred to as the string formatting
operator. It takes a format string along with a set of variables and
combines them to create a string that contains values of the variables
formatted in the specified way.
Example
To insert a string into a format string using the "%" operator, we use
"%s" as shown in the below example −
Open Compiler
name = "Tutorialspoint"
print("Welcome to %s!" % name)
Example
In the below example, we are using the format() method to insert
values into a string dynamically.
Open Compiler
str = "Welcome to {}"
print(str.format("Tutorialspoint"))
Using f-string
The f-strings, also known as formatted string literals, are used to
embed expressions inside string literals. The "f" in f-strings stands for
formatted and prefixing it with strings creates an f-string. The curly
braces "{}" within the string will then act as placeholders that are filled
with variables, expressions, or function calls.
Example
The following example illustrates the working of f-strings with
expressions.
Open Compiler
item1_price = 2500
item2_price = 300
total = f'Total: {item1_price + item2_price}'
print(total)
Escape Characters
Escape Character
An escape character is a character followed by a backslash (\). It tells
the Interpreter that this escape character (sequence) has a special
meaning. For instance, \n is an escape sequence that represents a
newline. When Python encounters this sequence in a string, it
understands that it needs to start a new line.
Unless an 'r' or 'R' prefix is present, escape sequences in string and
bytes literals are interpreted according to rules similar to those used by
Standard C. In Python, a string becomes a raw string if it is prefixed
with "r" or "R" before the quotation symbols. Hence 'Hello' is a normal
string whereas r'Hello' is a raw string.
Example
In the below example, we are practically demonstrating raw and normal
strings.
Open Compiler
# normal string
normal = "Hello"
print (normal)
# raw string
raw = r"Hello"
print (raw)
Example
In the following example, when a normal string is printed the escape
character '\n' is processed to introduce a newline. However, because of
the raw string operator 'r' the effect of escape character is not
translated as per its meaning.
Open Compiler
normal = "Hello\nWorld"
print (normal)
raw = r"Hello\World"
print (raw)
1 \<newline>
Backslash and newline ignored
2 \\
Backslash (\)
3 \'
Single quote (')
4 \"
Double quote (")
5 \a
ASCII Bell (BEL)
6 \b
ASCII Backspace (BS)
7 \f
ASCII Formfeed (FF)
8 \n
ASCII Line Feed (LF)
9 \r
ASCII Carriage Return (CR)
10 \t
ASCII Horizontal Tab (TAB)
11 \v
ASCII Vertical Tab (VT)
12 \ooo
Character with octal value ooo
13 \xhh
Character with hex value hh
Escape Characters Example
The following code shows the usage of escape sequences listed in the
above table −
Open Compiler
# ignore \
s = 'This string will not include \
backslashes or newline characters.'
print (s)
# escape backslash
s=s = 'The \\character is called backslash'
print (s)
# escape single quote
s='Hello \'Python\''
print (s)
# escape double quote
s="Hello \"Python\""
print (s)
# escape \b to generate ASCII backspace
s='Hel\blo'
print (s)
# ASCII Bell character
s='Hello\a'
print (s)
# newline
s='Hello\nPython'
print (s)
# Horizontal tab
s='Hello\tPython'
print (s)
# form feed
s= "hello\world"
print (s)
# Octal notation
s="\101"
print(s)
# Hexadecimal notation
s="\x41"
print (s)
String Methods
1 capitalise()
Capitalises first letter of string
2 casefold()
Converts all uppercase letters in string to lowercase. Similar to
lower(), but works on UNICODE characters alos
3 lower()
Converts all uppercase letters in string to lowercase.
4 swapcase()
Inverts case for all letters in string.
5 title()
Returns a "titlecased" version of string, that is, all words begin
with uppercase and the rest are lowercase.
6 upper()
Converts lowercase letters in string to uppercase.
Alignment Methods
Following methods in the str class control the alignment of characters
within the string object.
1 centre(width, fillchar)
Returns a string padded with fillchar with the original string
centred to a total of width columns.
2 ljust(width[, fillchar])
Returns a space-padded string with the original string left-
justified to a total of width columns.
3 rjust(width,[, fillchar])
Returns a space-padded string with the original string right-
justified to a total of width columns.
4 expandtabs(tab size = 8)
Expands tabs in string to multiple spaces; defaults to 8 spaces
per tab if tab size is not provided.
5 zfill (width)
Returns original string left padded with zeros to a total of
width characters; intended for numbers, zfill() retains any sign
given (less one zero).
1 lstrip()
Removes all leading whitespace in string.
2 rstrip()
Removes all trailing whitespace of string.
3 strip()
Performs both lstrip() and rstrip() on string
4 rsplit()
Splits the string from the end and returns a list of substrings
5 split()
Splits string according to delimiter (space if not provided) and
returns list of substrings.
6 splitlines()
Splits string at NEWLINEs and returns a list of each line with
NEWLINEs removed.
7 partition()
Splits the string in three string tuple at the first occurrence of
separator
8 rpartition()
Splits the string in three string tuple at the last occurrence of
separator
9 join()
Concatenates the string representations of elements in
sequence into a string, with separator string.
10 remove prefix()
Returns a string after removing the prefix string
11 remove suffix()
Returns a string after removing the suffix string
1 isalnum()
Returns true if the string has at least 1 character and all
characters are alphanumeric and false otherwise.
2 isalpha()
Returns true if the string has at least 1 character and all
characters are alphabetic and false otherwise.
3 isdigit()
Returns true if the string contains only digits and false
otherwise.
4 islower()
Returns true if the string has at least 1 cased character and all
cased characters are in lowercase and false otherwise.
5 isnumeric()
Returns true if a unicode string contains only numeric
characters and false otherwise.
6 isspace()
Returns true if the string contains only whitespace characters
and false otherwise.
7 istitle()
Returns true if the string is properly "titlecased" and false
otherwise.
8 isupper()
Returns true if the string has at least one cased character and
all cased characters are in uppercase and false otherwise.
9 isascii()
Returns True is all the characters in the string are from the
ASCII character set
10 isdecimal()
Checks if all the characters are decimal characters
11 isidentifier()
Checks whether the string is a valid Python identifier
12 isprintable()
Checks whether all the characters in the string are printable
Translation Methods
Following are the Translation methods of the string −
1 maketrans()
Returns a translation table to be used in the translation
function.
2 translate(table, deletechars="")
Translates string according to translation table str(256 chars),
removing those in the del string.
String Exercises
Example 1
Python program to find number of vowels in a given string.
Open Compiler
mystr = "All animals are equal. Some are more equal"
vowels = "aeiou"
count=0
for x in mystr:
if x.lower() in vowels: count+=1
print ("Number of Vowels:", count)
Example 2
Python program to convert a string with binary digits to integer.
Open Compiler
mystr = '10101'
def strtoint(mystr):
for x in mystr:
if x not in '01': return "Error. String with non-binary characters"
num = int(mystr, 2)
return num
print ("binary:{} integer: {}".format(mystr,strtoint(mystr)))
Example 3
Python program to drop all digits from a string.
Open Compiler
digits = [str(x) for x in range(10)]
mystr = 'He12llo, Py00th55on!'
chars = []
for x in mystr:
if x not in digits:
chars.append(x)
newstr = ''.join(chars)
print (newstr)
Exercise Programs
1. Python program to sort the characters in a string
2. Python program to remove duplicate characters from a string
3. Python program to list unique characters with their count in a
string
4. Python program to find number of words in a string
5. Python program to remove all non-alphabetic characters from
a string
Lists
Python Lists
List is one of the built-in data types in Python. A Python list is a
sequence of comma separated items, enclosed in square brackets [ ].
The items in a Python list need not be of the same data type.
Following are some examples of Python lists −
list1 = ["Rohan", "Physics", 21, 69.75]
list2 = [1, 2, 3, 4, 5]
list3 = ["a", "b", "c", "d"]
list4 = [25.50, True, -55, 1+2j]
Updating Lists
You can update single or multiple elements of lists by giving the slice
on the left-hand side of the assignment operator, and you can add to
elements in a list with the append() method. For example −
Open Compiler
list = ['physics', 'chemistry', 1997, 2000];
print ("Value available at index 2 : ")
print (list[2])
list[2] = 2001;
print ("New value available at index 2 : ")
print (list[2])
1 list.append(obj)
Appends object obj to list.
2 list.clear()
Clears the contents of the list.
3 list.copy()
Returns a copy of the list object.
4 list.count(obj)
Returns count of how many times obj occurs in
list
5 list.extend(seq)
Appends the contents of seq to list
6 list.index(obj)
Returns the lowest index in list that obj appears
7 list.insert(index, obj)
Inserts object obj into list at offset index
8 list.pop(obj=list[-1])
Removes and returns last object or obj from list
9 list.remove(obj)
Removes object obj from list
10 list.reverse()
Reverses objects of list in place
11 list.sort([func])
Sorts objects of list, use compare func if given
1 cmp(list1, list2)
Compares elements of both lists.
2 len(list)
Gives the total length of the list.
3 max(list)
Returns an item from the list with max
value.
4 min(list)
Returns an item from the list with min
value.
5 list(seq)
Converts a tuple into a list.
Example
Following is the basic example to access list items −
Open Compiler
list1 = ["Rohan", "Physics", 21, 69.75]
list2 = [1, 2, 3, 4, 5]
print ("Item at 0th index in list1: ", list1[0])
print ("Item at index 2 in list2: ", list2[2])
Example
In the following example, we are accessing list items with negative
indexing −
Open Compiler
list1 = ["a", "b", "c", "d"]
list2 = [25.50, True, -55, 1+2j]
print ("Item at 0th index in list1: ", list1[-1])
print ("Item at index 2 in list2: ", list2[-3])
Where,
1. start is the starting index (inclusive).
2. stop is the ending index (exclusive).
Example
In the following example, we are retrieving sublist from index 1 to last
in "list1" and index 0 to 1 in "list2", and retrieving all elements in "list3"
−
Open Compiler
list1 = ["a", "b", "c", "d"]
list2 = [25.50, True, -55, 1+2j]
list3 = ["Rohan", "Physics", 21, 69.75]
print ("Items from index 1 to last in list1: ", list1[1:])
print ("Items from index 0 to 1 in list2: ", list2[:2])
print ("Items from index 0 to index last in list3", list3[:])
Example
In this example, we are fetching sublist from index "1 to 2" in "list1"
and index "0 to 1" in "list2" using slice operator −
Open Compiler
list1 = ["a", "b", "c", "d"]
list2 = [25.50, True, -55, 1+2j]
print ("Items from index 1 to 2 in list1: ", list1[1:3])
print ("Items from index 0 to 1 in list2: ", list2[0:2])
Syntax
list1[i] = newvalue
Example
In the following code, we change the value at index 2 of the given list.
Open Compiler
list3 = [1, 2, 3, 4, 5]
print ("Original list ", list3)
list3[2] = 10
print ("List after changing value at index 2: ", list3)
Example
In the following code, items at index 1 and 2 are replaced by items in
another sublist.
Open Compiler
list1 = ["a", "b", "c", "d"]
print ("Original list: ", list1)
list2 = ['Y', 'Z']
list1[1:3] = list2
print ("List after changing with sublist: ", list1)
Example
Open Compiler
list1 = ["a", "b", "c", "d"]
print ("Original list: ", list1)
list2 = ['X','Y', 'Z']
list1[1:3] = list2
print ("List after changing with sublist: ", list1)
Example
If the sublist with which a slice of the original list is to be replaced has
lesser items, the items with match will be replaced and the rest of the
items in the original list will be removed.
In the following code, we try to replace "b" and "c" with "Z" (one less
item than items to be replaced). It results in Z replacing b and c
removed.
Open Compiler
list1 = ["a", "b", "c", "d"]
print ("Original list: ", list1)
list2 = ['Z']
list1[1:3] = list2
print ("List after changing with sublist: ", list1)
Example
In the following example, we are adding an element "e" to the end of
the list "list1" using the append() method −
Open Compiler
list1 = ["a", "b", "c", "d"]
print ("Original list: ", list1)
list1.append('e')
print ("List after appending: ", list1)
Output
Following is the output of the above code −
Original list: ['a', 'b', 'c', 'd']
List after appending: ['a', 'b', 'c', 'd', 'e']
Adding List Items Using insert() Method
The insert() method in Python is used to add an element at a specified
index (position) within a list, shifting existing elements to
accommodate the new one.
We can add list items using the insert() method by specifying the index
position where we want to insert the new item and the item itself within
the parentheses, like my_list.insert(index, new_item).
Example
In this example, we have an original list containing various items. We
use the insert() method to add new elements to the list at specific
positions −
Open Compiler
list1 = ["Rohan", "Physics", 21, 69.75]
list1.insert(2, 'Chemistry')
print ("List after appending: ", list1)
list1.insert(-1, 'Pass')
print ("List after appending: ", list1)
We can see that "Pass" is not inserted at the updated index "-1", but at
the previous index "-1". This behaviour is because when appending or
inserting items into a list, Python does not dynamically update negative
index positions.
Example
In the below example, we are using the extend() method to add the
elements from "another_list" to the end of "list1" −
Open Compiler
# Original list
list1 = [1, 2, 3]
# Another list to extend with
another_list = [4, 5, 6]
list1.extend(another_list)
print("Extended list:", list1)
Output
Output of the above code is as follows −
Extended list: [1, 2, 3, 4, 5, 6]
Example
In the following example, we are deleting the element "Physics" from
the list "list1" using the remove() method −
Open Compiler
list1 = ["Rohan", "Physics", 21, 69.75]
print ("Original list: ", list1)
list1.remove("Physics")
print ("List after removing: ", list1)
Example
The following example shows how you can use the pop() method to
remove list items −
Open Compiler
list2 = [25.50, True, -55, 1+2j]
print ("Original list: ", list2)
list2.pop(2)
print ("List after popping: ", list2)
Example
In this example, we are using the clear() method to remove all
elements from the list "my_list" −
Open Compiler
my_list = [1, 2, 3, 4, 5]
# Clearing the list
my_list.clear()
print("Cleared list:", my_list)
Example
In here, we are deleting a series of consecutive items from a list with
the slicing operator −
Open Compiler
list2 = [25.50, True, -55, 1+2j]
print ("List before deleting: ", list2)
del list2[0:2]
print ("List after deleting: ", list2)
Loop Lists
Loop Through List Items
Looping through list items in Python refers to iterating over each
element within a list. We do so to perform the desired operations on
each item. These operations include list modification, conditional
operations, string manipulation, data analysis, etc.
Python provides various methods for looping through list items, with
the most common being the for loop. We can also use the while loop
to iterate through list items, although it requires additional handling of
the loop control variable explicitly i.e. an index.
Syntax
Following is the basic syntax to loop through items in a list using a for
loop in Python −
for item in list:
# Code block to execute
Example
In the following example, we are using a for loop to iterate through
each element in the list "lst" and retrieving each element followed by a
space on the same line −
Open Compiler
lst = [25, 12, 10, -21, 10, 100]
for num in lst:
print (num, end = ' ')
Output
Following is the output of the above code −
25 12 10 -21 10 100
Syntax
Following is the basic syntax for looping through items in a list using a
while loop in Python −
while condition:
# Code block to execute
Example
In the below example, we iterate through each item in the list "my_list"
using a while loop. We use an index variable "index" to access each
item sequentially, incrementing it after each iteration to move to the
next item −
Open Compiler
my_list = [1, 2, 3, 4, 5]
index = 0
while index < len(my_list):
print(my_list[index])
index += 1
Output
Output of the above code is as follows −
1
2
3
4
5
Loop Through List Items with Index
An index is a numeric value representing the position of an element
within a sequence, such as a list, starting from 0 for the first element.
We can loop through list items using index by iterating over a range of
indices corresponding to the length of the list and accessing each
element using the index within the loop.
Example
This example initialises a list "lst" with integers and creates a range of
indices corresponding to the length of the list. Then, it iterates over
each index in the range and prints the value at that index in the list
"lst" −
Open Compiler
lst = [25, 12, 10, -21, 10, 100]
indices = range(len(lst))
for i in indices:
print ("lst[{}]: ".format(i), lst[i])
Output
We get the output as shown below −
lst[0]: 25
lst[1]: 12
lst[2]: 10
lst[3]: -21
lst[4]: 10
lst[5]: 100
Example
In this example, we use list comprehension to iterate through each
number in a list of numbers, square each one, and store the squared
result in the new list "squared_numbers" −
Open Compiler
numbers = [1, 2, 3, 4, 5]
squared_numbers = [num ** 2 for num in numbers]
print (squared_numbers)
Output
We get the output as shown below −
[1, 4, 9, 16, 25]
This provides both the index and item of each element in the iterable
during iteration
Example
In the following example, we are using the enumerate() function to
iterate through a list "fruits" and retrieve each fruit along with its
corresponding index −
Open Compiler
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
print(index, fruit)
Output
We get the output as shown below −
0 apple
1 banana
2 cherry
List Comprehension
List Comprehension in Python
A list comprehension is a concise way to create lists. It is similar to
set builder notation in mathematics. It is used to define a list based on
an existing iterable object, such as a list, tuple, or string, and apply an
expression to each element in the iterable.
Where,
1. expression is the operation or transformation to apply to
each item in the iterable.
2. item is the variable representing each element in the iterable.
3. iterable is the sequence of elements to iterate over.
4. condition (optional) is an expression that filters elements
based on a specified condition.
Example
In the following example, we are using list comprehension with a
lambda function to double each element in a given list "original_list".
We iterate over each element in the "original_list" and apply the
lambda function to double it −
Open Compiler
original_list = [1, 2, 3, 4, 5]
doubled_list = [(lambda x: x * 2)(x) for x in original_list]
print(doubled_list)
Example
In this example, all combinations of items from two lists in the form of a
tuple are added in a third list object −
Open Compiler
list1=[1,2,3]
list2=[4,5,6]
CombUst=[(x,y) for x in list1 for y in list2]
print (CombUst)
Example
The following example uses conditionals within a list comprehension to
generate a list of even numbers from 1 to 20 −
Open Compiler
list1=[x for x in range(1,21) if x%2==0]
print (list1)
Example
The following example uses list comprehension to build a list of squares
of numbers between 1 to 10 −
Open Compiler
squares = [x*x for x in range(1,11)]
print (squares)
Sort Lists
Sorting Lists in Python
Sorting a list in Python is a way to arrange the elements of the list in
either ascending or descending order based on a defined criterion, such
as numerical or lexicographical order.
This can be achieved using the built-in sorted() function or by calling
the sort() method on the list itself, both of which modify the original list
or return a new sorted list depending on the method used.
Syntax
The syntax for using the sort() method is as follows −
list_name.sort(key=None, reverse=False)
Where,
1. list_name is the name of the list to be sorted.
2. key (optional) is a function that defines the sorting criterion.
If provided, it is applied to each element of the list for sorting.
Default is None.
3. reverse (optional) is a boolean value. If True, the list will be
sorted in descending order. If False (default), the list will be
sorted in ascending order.
Syntax
The syntax for using the sorted() method is as follows −
sorted(iterable, key=None, reverse=False)
Where,
1. iterable is the iterable (e.g., list, tuple, string) whose
elements are to be sorted.
2. key (optional) is a function that defines the sorting criterion.
If provided, it is applied to each element of the iterable for
sorting. Default is None.
3. reverse (optional) is a boolean value. If True, the iterable
will be sorted in descending order. If False (default), the
iterable will be sorted in ascending order.
Example
In the following example, we are using the sorted() function to sort a
list of numbers and retrieve a new sorted list −
Open Compiler
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
# Sorting in descending order
sorted_numbers_desc = sorted(numbers, reverse=True)
print(sorted_numbers_desc)
Following is the output of the above code −
[9, 6, 5, 5, 5, 4, 3, 3, 2, 1, 1]
Copy Lists
Copying a List in Python
Copying a list in Python refers to creating a new list that contains the
same elements as the original list. There are different methods for
copying a list, including, using slice notation, the list() function, and
using the copy() method.
Each method behaves differently in terms of whether it creates a
shallow copy or a deep copy. Let us discuss all of these deeply in this
tutorial.
As you can see, even though we only modified the first element of the
first sublist in the shallow copied list, the same change is reflected in
the original list as well.
This is because a shallow copy only creates new references to the
original objects, rather than creating copies of the objects themselves
−
Original List: [[100, 2, 3], [4, 5, 6], [7, 8, 9]]
Shallow Copied List: [[100, 2, 3], [4, 5, 6], [7, 8, 9]]
As you can see, when we modify the first element of the first sublist in
the deep copied list, it does not affect the original list.
This is because a deep copy creates a new object and recursively
copies all the nested objects, ensuring that the copied object is fully
independent from the original one −
Original List: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Deep Copied List: [[100, 2, 3], [4, 5, 6], [7, 8, 9]]
Where, start is the index where the slice starts, end is the index where
the slice ends (exclusive), and step is the step size between elements.
We can copy a list using slice notation by specifying the entire range of
indices of the original list. This effectively creates a new list with the
same elements as the original list.
Any modifications made to the copied list will not affect the original list,
and vice versa, because they are separate objects in memory.
Example
In this example, we are creating a slice of the "original_list", effectively
copying all its elements into a new list "copied_list" −
Open Compiler
# Original list
original_list = [1, 2, 3, 4, 5]
# Copying the list using slice notation
copied_list = original_list[1:4]
# Modifying the copied list
copied_list[0] = 100
# Printing both lists
print("Original List:", original_list)
print("Copied List:", copied_list)
Example
In the example below, we are creating a new list object "copied_list"
containing the same elements as "original_list" using the list() function
−
Open Compiler
# Original list
original_list = [1, 2, 3, 4, 5]
# Copying the list using the list() constructor
copied_list = list(original_list)
# Printing both lists
print("Original List:", original_list)
print("Copied List:", copied_list)
Example
In the following example, we are using the copy() function to creates a
new list object "copied_list" containing the same elements as
"original_list" −
Open Compiler
import copy
original_list = [1, 2, 3, 4, 5]
# Copying the list using the copy() function
copied_list = copy.copy(original_list)
print("Copied List:", copied_list)
Join Lists
Join Lists in Python
Joining lists in Python refers to combining the elements of multiple lists
into a single list. This can be achieved using various methods, such as
concatenation, list comprehension, or using built-in functions like
extend() or + operator.
Joining lists does not modify the original lists but creates a new list
containing the combined elements.
Example
In the following example, we are concatenating the elements of two
lists "L1" and "L2", creating a new list "joined_list" containing all the
elements from both lists −
Open Compiler
# Two lists to be joined
L1 = [10,20,30,40]
L2 = ['one', 'two', 'three', 'four']
# Joining the lists
joined_list = L1 + L2
# Printing the joined list
print("Joined List:", joined_list)
This creates a new list where expression is evaluated for each item in
the iterable.
We can join a list using list comprehension by iterating over multiple
lists and appending their elements to a new list.
Example
In this example, we are joining two lists, L1 and L2, into a single list
using list comprehension. The resulting list, joined_list, contains all
elements from both L1 and L2 −
Open Compiler
# Two lists to be joined
L1 = [36, 24, 3]
L2 = [84, 5, 81]
# Joining the lists using list comprehension
joined_list = [item for sublist in [L1, L2] for item in sublist]
# Printing the joined list
print("Joined List:", joined_list)
Example
In the example below, we are appending elements from "list2" to "list1"
using the append() function. We achieve this by iterating over "list2"
and adding each element to "list1" −
Open Compiler
# List to which elements will be appended
list1 = ['Fruit', 'Number', 'Animal']
# List from which elements will be appended
list2 = ['Apple', 5, 'Dog']
# Joining the lists using the append() function
for element in list2:
list1.append(element)
# Printing the joined list
print("Joined List:", list1)
We get the output as shown below −
Joined List: ['Fruit', 'Number', 'Animal', 'Apple', 5, 'Dog']
Example
In the following example, we are extending "list1" by appending the
elements of "list2" using the extend() function −
Open Compiler
# List to be extended
list1 = [10, 15, 20]
# List to be added
list2 = [25, 30, 35]
# Joining the lists using the extend() function
list1.extend(list2)
# Printing the extended list
print("Extended List:", list1)
List Methods
List is one of the fundamental data structures in Python, It provides a
flexible way to store and manage a collection of items. It has several
built-in methods that allow you to add, update, and delete items
efficiently.
Lists in Python can contain items of different data types, including
other lists, making them highly flexible to different scenarios. The list
object includes several built-in methods that allow you to add, update,
and delete items efficiently, as well as to perform various operations on
the list's elements.
1 list.append(obj)
Appends object obj to list.
2 list.extend(seq)
Appends the contents of seq to list
3 list.insert(index, obj)
Inserts object obj into list at offset
index
1 list.clear()
Clears all the contents of the list.
2 list.pop(obj=list[-1])
Removes and returns the last object or the object at the
specified index from the list.
3 list.remove(obj)
Removes the first occurrence of object obj from the list.
1 list.index(obj)
Returns the lowest index in list that obj appears
2 list.count(obj)
Returns count of how many times obj occurs in the
list.
1 list.copy()
Returns a copy of the list object.
2 list.sort([func])
Sorts the objects in the list in place, using a comparison
function if provided.
3 list.reverse()
Reverses the order of objects in the list in place.
List Exercises
Python List Exercise 1
Python program to find unique numbers in a given list.
Open Compiler
L1 = [1, 9, 1, 6, 3, 4, 5, 1, 1, 2, 5, 6, 7, 8, 9, 2]
L2 = []
for x in L1:
if x not in L2:
L2.append(x)
print (L2)
Updating Tuples
Tuples are immutable which means you cannot update or change the
values of tuple elements. You are able to take portions of existing
tuples to create new tuples as the following example demonstrates −
Open Compiler
tup1 = (12, 34.56);
tup2 = ('abc', 'xyz');
# Following action is not valid for tuples
# tup1[0] = 100;
# So let's create a new tuple as follows
tup3 = tup1 + tup2;
print (tup3);
No Enclosing Delimiters
Any set of multiple objects, comma-separated, written without
identifying symbols, i.e., brackets for lists, parentheses for tuples, etc.,
default to tuples, as indicated in these short examples −
Open Compiler
print ('abc', -4.24e93, 18+6.6j, 'xyz');
x, y = 1, 2;
print ("Value of x , y : ", x,y);
1 cmp(tuple1, tuple2)
Compares elements of both tuples.
2 len(tuple)
Gives the total length of the tuple.
3 max(tuple)
Returns an item from the tuple with max
value.
4 min(tuple)
Returns an item from the tuple with min
value.
5 tuple(seq)
Converts a list into tuple.
Example
Following is the basic example to access tuple items with slicing index
−
Open Compiler
tuple1 = ("Rohan", "Physics", 21, 69.75)
tuple2 = (1, 2, 3, 4, 5)
print ("Item at 0th index in tuple1: ", tuple1[0])
print ("Item at index 2 in tuple2: ", tuple2[2])
Example
In the following example, we are accessing tuple items with negative
indexing −
Open Compiler
tup1 = ("a", "b", "c", "d")
tup2 = (25.50, True, -55, 1+2j)
print ("Item at 0th index in tup1: ", tup1[-1])
print ("Item at index 2 in tup2: ", tup2[-3])
Example
In the example below, we are accessing a range of tuple items by using
negative indexing −
Open Compiler
tup1 = ("a", "b", "c", "d")
tup2 = (1, 2, 3, 4, 5)
print ("Items from index 1 to last in tup1: ", tup1[1:])
print ("Items from index 2 to last in tup2", tup2[2:-1])
Where,
start is the starting index (inclusive).
stop is the ending index (exclusive).
Example
In the following example, we are retrieving subtuple from index 1 to
last in "tuple1" and index 0 to 1 in "tuple2", and retrieving all elements
in "tuple3" −
Open Compiler
tuple1 = ("a", "b", "c", "d")
tuple2 = (25.50, True, -55, 1+2j)
tuple3 = (1, 2, 3, 4, 5)
tuple4 = ("Rohan", "Physics", 21, 69.75)
print ("Items from index 1 to last in tuple1: ", tuple1[1:])
print ("Items from index 0 to 1 in tuple2: ", tuple2[:2])
print ("Items from index 0 to index last in tuple3", tuple3[:])
Following is the output of the above code −
Items from index 1 to last in tuple1: ('b', 'c', 'd')
Items from index 0 to 1 in tuple2: (25.5, True)
Items from index 0 to index last in tuple3 ('Rohan', 'Physics', 21, 69.75)
Where,
start is the starting index (inclusive).
stop is the ending index (exclusive) of the sub tuple.
Example
In this example, we are fetching subtuple from index "1 to 2" in
"tuple1" and index "0 to 1" in "tuple2" using slice operator −
Open Compiler
tuple1 = ("a", "b", "c", "d")
tuple2 = (25.50, True, -55, 1+2j)
print ("Items from index 1 to 2 in tuple1: ", tuple1[1:3])
print ("Items from index 0 to 1 in tuple2: ", tuple2[0:2])
Update Tuples
Updating Tuples in Python
In Python, tuple is an immutable sequence, meaning once a tuple is
created, its elements cannot be changed, added, or removed.
To update a tuple in Python, you can combine various operations to
create a new tuple. For instance, you can concatenate tuples, slice
them, or use tuple unpacking to achieve the desired result. This often
involves converting the tuple to a list, making the necessary
modifications, and then converting it back to a tuple.
Example
In the following example, we create a new tuple by concatenating "T1"
with "T2" using the "+" operator −
Open Compiler
# Original tuple
T1 = (10, 20, 30, 40)
# Tuple to be concatenated
T2 = ('one', 'two', 'three', 'four')
# Updating the tuple using the concatenation operator
T1 = T1 + T2
print(T1)
Where,
start is the index at which the slice begins (inclusive).
stop is the index at which the slice ends (exclusive).
step is the interval between elements in the slice (optional).
Example
In this example, we are updating a tuple by slicing it into two parts and
inserting new elements between the slices −
Open Compiler
# Original tuple
T1 = (37, 14, 95, 40)
# Elements to be added
new_elements = ('green', 'blue', 'red', 'pink')
# Extracting slices of the original tuple
# Elements before index 2
part1 = T1[:2]
# Elements from index 2 onward
part2 = T1[2:]
# Create a new tuple
updated_tuple = part1 + new_elements + part2
# Printing the updated tuple
print("Original Tuple:", T1)
print("Updated Tuple:", updated_tuple)
Example
In the example below, we are updating a tuple by first converting it to a
list and using list comprehension to add 100 to each element. We then
convert the list back to a tuple to get the updated tuple −
Open Compiler
# Original tuple
T1 = (10, 20, 30, 40)
# Converting the tuple to a list
list_T1 = list(T1)
# Using list comprehension
updated_list = [item + 100 for item in list_T1]
# Converting the updated list back to a tuple
updated_tuple = tuple(updated_list)
# Printing the updated tuple
print("Original Tuple:", T1)
print("Updated Tuple:", updated_tuple)
Example
In the following example, we first convert the original tuple "T1" to a
list "list_T1". We then use a loop to iterate over the new elements and
append each one to the list using the append() function. Finally, we
convert the updated list back to a tuple to get the updated tuple −
Open Compiler
# Original tuple
T1 = (10, 20, 30, 40)
# Convert tuple to list
list_T1 = list(T1)
# Elements to be added
new_elements = [50, 60, 70]
# Updating the list using append()
for element in new_elements:
list_T1.append(element)
# Converting list back to tuple
updated_tuple = tuple(list_T1)
# Printing the updated tuple
print("Original Tuple:", T1)
print("Updated Tuple:", updated_tuple)
Example
Open Compiler
tup1 = (10,20,30)
x, y = tup1
x, y, p, q = tup1
Example 1
Open Compiler
tup1 = (10,20,30)
x, *y = tup1
print ("x: ", "y: ", y)
The first value in tuple is assigned to "x", and the rest of items to "y"
which becomes a list.
Example 2
In this example, the tuple contains 6 values and variables to be
unpacked are 3. We prefix "*" to the second variable.
Open Compiler
tup1 = (10,20,30, 40, 50, 60)
x, *y, z = tup1
print ("x: ",x, "y: ", y, "z: ", z)
Here, values are unpacked in "x" and "z" first, and then the rest of
values are assigned to "y" as a list.
Example 3
What if we add "*" to the first variable?
Open Compiler
tup1 = (10,20,30, 40, 50, 60)
*x, y, z = tup1
print ("x: ",x, "y: ", y, "z: ", z)
Loop Tuples
Loop Through Tuple Items
Looping through tuple items in Python refers to iterating over each
element in a tuple sequentially.
In Python we can loop through the items of a tuple in various ways,
with the most common being the for loop. We can also use the while
loop to iterate through tuple items, although it requires additional
handling of the loop control variable explicitly i.e. an index.
Syntax
Following is the basic syntax to loop through items in a tuple using a for
loop in Python −
for item in tuple:
# Code block to execute
Example
In the following example, we are using a for loop to iterate through
each element in the tuple "tup" and retrieving each element followed
by a space on the same line −
Open Compiler
tup = (25, 12, 10, -21, 10, 100)
for num in tup:
print (num, end = ' ')
Output
Following is the output of the above code −
25 12 10 -21 10 100
Syntax
Following is the basic syntax for looping through items in a tuple using
a while loop in Python −
while condition:
# Code block to execute
Example
In the below example, we iterate through each item in the tuple
"my_tup" using a while loop. We use an index variable "index" to
access each item sequentially, incrementing it after each iteration to
move to the next item −
Open Compiler
my_tup = (1, 2, 3, 4, 5)
index = 0
while index < len(my_tup):
print(my_tup[index])
index += 1
Output
Output of the above code is as follows −
1
2
3
4
5
Example
This example initialises a tuple "tup" with integers and creates a range
of indices corresponding to the length of the tuple. Then, it iterates
over each index in the range and prints the value at that index in the
tuple "tup" −
Open Compiler
tup = (25, 12, 10, -21, 10, 100)
indices = range(len(tup))
for i in indices:
print ("tup[{}]: ".format(i), tup[i])
Output
We get the output as shown below −
tup[0]: 25
tup[1]: 12
tup[2]: 10
tup[3]: -21
tup[4]: 10
tup[5]: 100
Join Tuples
Joining Tuples in Python
Joining tuples in Python refers to combining the elements of multiple
tuples into a single tuple. This can be achieved using various methods,
such as concatenation, list comprehension, or using built-in functions
like extend() or sum().
Joining tuples does not modify the original tuples but creates a new
tuple containing the combined elements.
Example
In the following example, we are concatenating the elements of two
tuples "T1" and "T2", creating a new tuple "joined_tuple" containing all
the elements from both tuples −
Open Compiler
# Two tuples to be joined
T1 = (10,20,30,40)
T2 = ('one', 'two', 'three', 'four')
# Joining the tuples
joined_tuple = T1 + T2
# Printing the joined tuple
print("Joined Tuple:", joined_tuple)
This creates a new list where expression is evaluated for each item in
the iterable.
We can join a tuple using list comprehension by iterating over multiple
tuples and appending their elements to a new tuple.
Example
In this example, we are joining two tuples, T1 and T2, into a single tuple
using list comprehension. The resulting tuple, joined_tuple, contains all
elements from both T1 and T2 −
Open Compiler
# Two tuples to be joined
T1 = (36, 24, 3)
T2 = (84, 5, 81)
# Joining the tuples using list comprehension
joined_tuple = [item for sub tuple in [T1, T2] for item in sub tuple]
# Printing the joined tuple
print("Joined Tuple:", joined_tuple)
Example
In the following example, we are extending the first tuple "T1" by
converting it into a list "L1", then adding elements from the second
tuple "T2" by first converting it into a list "L2", and finally converting
the merged list back into a tuple, effectively joining the two tuples −
Open Compiler
T1 = (10,20,30,40)
T2 = ('one', 'two', 'three', 'four')
L1 = list(T1)
L2 = list(T2)
L1.extend(L2)
T1 = tuple(L1)
print ("Joined Tuple:", T1)
Example
In this example, the elements of the first tuple are first appended to an
empty tuple. Then elements from the second tuple are appended,
resulting in a new tuple that is a concatenation of the two −
Open Compiler
T1 = (10,20,30,40)
T2 = ('one', 'two', 'three', 'four')
T3 = sum((T1, T2), ())
print ("Joined Tuple:", T3)
Example
In the following example, we are iterating over each element in tuple
T2, and for each element, we are appending it to tuple T1, effectively
joining the two tuples −
Open Compiler
T1 = (10,20,30,40)
T2 = ('one', 'two', 'three', 'four')
for t in T2:
T1+=(t,)
print (T1)
Tuple Methods
Below are the built-in methods for tuples. Let's explore each method's
basic functionality −
1 tuple.count(obj)
Returns count of how many times obj occurs in
tuple
2 tuple.index(obj)
Returns the lowest index in tuple that obj appears
Syntax
tuple.index(obj)
Return value
The index() method returns an integer, representing the index of the
first occurrence of "obj".
Example
Take a look at the following example −
Open Compiler
tup1 = (25, 12, 10, -21, 10, 100)
print ("Tup1:", tup1)
x = tup1.index(10)
print ("First index of 10:", x)
Syntax
tuple.count(obj)
Return Value
Number of occurrences of the object. The count() method returns an
integer.
Example
Open Compiler
tup1 = (10, 20, 45, 10, 30, 10, 55)
print ("Tup1:", tup1)
c = tup1.count(10)
print ("count of 10:", c)
Example
Even if the items in the tuple contain expressions, they will be
evaluated to obtain the count.
Open Compiler
tup1 = (10, 20/80, 0.25, 10/40, 30, 10, 55)
print ("Tup1:", tup1)
c = tup1.count(0.25)
print ("count of 10:", c)
Sets
Sets in Python
In Python, a set is an unordered collection of unique elements. Unlike
lists or tuples, sets do not allow duplicate values i.e. each element in a
set must be unique. Sets are mutable, meaning you can add or remove
items after a set has been created.
Sets are defined using curly braces {} or the built-in set() function.
They are particularly useful for membership testing, removing
duplicates from a sequence, and performing common mathematical set
operations like union, intersection, and difference.
A set refers to a collection of distinct objects. It is used to group objects
together and to study their properties and relationships. The objects in
a set are called elements or members of the set.
Set Operations
In Python, sets support various set operations, which are used to
manipulate and compare sets. These operations include union,
intersection, difference, symmetric difference, and subset testing. Sets
are particularly useful when dealing with collections of unique elements
and performing operations based on set theory.
1. Union − It combine elements from both sets using the union()
function or the | operator.
2. Intersection − It is used to get common elements using the
intersection() function or the & operator.
3. Difference − It is used to get elements that are in one set
but not the other using the difference() function or the -
operator.
4. Symmetric Difference − It is used to get elements that are
in either of the sets but not in both using the
symmetric_difference() method or the ^ operator.
Syntax
The syntax for set comprehensions is similar to list comprehensions,
but instead of square brackets [ ], you use curly braces { } to denote a
set −
set_variable = {expression for item in iterable if condition}
Example
In the following example, we are creating a set containing the squares
of numbers from 1 to 5 using a set comprehension −
Open Compiler
squared_set = {x**2 for x in range(1, 6)}
print(squared_set)
Example
Open Compiler
nested_set = {(x, y) for x in range(1, 3) for y in range(1, 3)}
print(nested_set)
Frozen Sets
In Python, a frozen set is an immutable collection of unique elements,
similar to a regular set but with the distinction that it cannot be
modified after creation. Once created, the elements within a frozen set
cannot be added, removed, or modified, making it a suitable choice
when you need an immutable set.
You can create a frozen set in Python using the frozenset() function by
passing an iterable (such as a list, tuple, or another set) containing the
elements you want to include in the frozen set.
Example
In the following example, we are creating a frozen set of integers and
then adding an element to it −
Open Compiler
my_frozen_set = frozenset([1, 2, 3])
print(my_frozen_set)
my_frozen_set.add(4)
Example
In the following example, the for loop iterates over the set "langs", and
in each iteration, the variable "lang" is assigned the value of the
current element −
Open Compiler
# Defining a set
langs = {"C", "C++", "Java", "Python"}
# Accessing set items using a for loop
for lang in langs:
print (lang)
Example
In this example, we are using list comprehension to access set items by
iterating over each element of "my_set" −
Open Compiler
my_set = {1, 2, 3, 4, 5}
# Accessing set items using list comprehension
accessed_items = [item for item in my_set]
print(accessed_items)
Example
Following is the basic example demonstrating how to access subsets
from a set −
Open Compiler
import itertools
# Defining a set
original_set = {1, 2, 3, 4}
# Checking if {1, 2} is a subset of the original set
is_subset = {1, 2}.issubset(original_set)
print("{1, 2} is a subset of the original set:", is_subset)
# Generating all subsets with two elements
subsets_with_two_elements = [set(subset) for subset in
itertools.combinations(original_set, 2)]
print("Subsets with two elements:", subsets_with_two_elements)
Example
In the below example, the "in" operator verifies whether the item "Java"
exists in the set "langs", and the "not in" operator checks whether the
item "SQL" does not exist in the set −
Open Compiler
# Defining a set
langs = {"C", "C++", "Java", "Python"}
# Checking if an item exists in the set
if "Java" in langs:
print("Java is present in the set.")
else:
print("Java is not present in the set.")
# Checking if an item does not exist in the set
if "SQL" not in langs:
print("SQL is not present in the set.")
else:
print("SQL is present in the set.")
Syntax
Following is the syntax to add an element to a set −
set.add(obj)
Example
In the following example, we are initialising an empty set called
"language" and adding elements to it using the add() method −
Open Compiler
# Defining an empty set
language = set()
# Adding elements to the set using add() method
language.add("C")
language.add("C++")
language.add("Java")
language.add("Python")
# Printing the updated set
print("Updated Set:", language)
Example
In this example, a set is constructed from a string, and another string is
used as argument for update() method −
Open Compiler
set1 = set("Hello")
set1.update("World")
print (set1)
Example
The following example combine sets using the union() method and the |
operator to create new sets containing unique elements from the
original sets −
Open Compiler
# Defining three sets
lang1 = {"C", "C++", "Java", "Python"}
lang2 = {"PHP", "C#", "Perl"}
lang3 = {"SQL", "C#"}
# Performing union operation
combined_set1 = lang1.union(lang2)
combined_set2 = lang2 | lang3
# Print the combined set
print ("Combined Set1:", combined_set1)
print("Combined Set2:", combined_set2)
Example
If a sequence object is given as argument to union() method, Python
automatically converts it to a set first and then performs union −
Open Compiler
lang1 = {"C", "C++", "Java", "Python"}
lang2 = ["PHP", "C#", "Perl"]
lang3 = lang1.union(lang2)
print (lang3)
Example
In the following example, we are defining a list of integers and then
using set comprehension to generate a set containing the squares of
those integers −
Open Compiler
# Defining a list containing integers
numbers = [1, 2, 3, 4, 5]
# Creating a set containing squares of numbers using set
comprehension
squares_set = {num ** 2 for num in numbers}
# Printing the set containing squares of numbers
print("Squares Set:", squares_set)
Example
In the following example, we are deleting the element "Physics" from
the set "my_set" using the remove() method −
Open Compiler
my_set = {"Rohan", "Physics", 21, 69.75}
print ("Original set: ", my_set)
my_set.remove("Physics")
print ("Set after removing: ", my_set)
Example
If the element to delete is not found in the set, the remove() method
will raise a KeyError exception −
Open Compiler
my_set = {"Rohan", "Physics", 21, 69.75}
print ("Original set: ", my_set)
my_set.remove("PHP")
print ("Set after removing: ", my_set)
Example
In this example, we are using the discard() method to delete an
element from a set regardless of whether it is present or not −
Open Compiler
my_set = {"Rohan", "Physics", 21, 69.75}
print ("Original set: ", my_set)
# removing an existing element
my_set.discard("Physics")
print ("Set after removing Physics: ", my_set)
# removing non-existing element
my_set.discard("PHP")
print ("Set after removing non-existent element PHP: ", my_set)
Example
In the example below, we are defining a set with elements "1" through
"5" and removing an arbitrary element from it using the pop() method
−
Open Compiler
# Defining a set
my_set = {1, 2, 3, 4, 5}
# removing and returning an arbitrary element from the set
removed_element = my_set.pop()
# Printing the removed element and the updated set
print("Removed Element:", removed_element)
print("Updated Set:", my_set)
Example
In the following example, we are defining a set with elements "1"
through "5" and then using the clear() method to remove all elements
from the set −
Open Compiler
# Defining a set with multiple elements
my_set = {1, 2, 3, 4, 5}
# Removing all elements from the set
my_set.clear()
# Printing the updated set
print("Updated Set:", my_set)
Example
In this example, we are defining two sets "s1" and "s2", and then using
the difference_update() method to remove elements from "s1" that are
also in "s2" −
Open Compiler
s1 = {1,2,3,4,5}
s2 = {4,5,6,7,8}
print ("s1 before running difference_update: ", s1)
s1.difference_update(s2)
print ("s1 after running difference_update: ", s1)
Example
In the following example, we are defining two sets "set1" and "set2".
We are then using the symmetric difference operator (^) to create a
new set "result_set" containing elements that are in either "set1" or
"set2" but not in both −
Open Compiler
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
# Removing items that exist in either set
result_set = set1 ^ set2
print("Resulting Set:", result_set)
Example
In this example, we are defining two sets "set1" and "set2". We are
then using the intersection_update() method to modify "set1" so that it
only contains elements that are also in "set2" −
Open Compiler
set1 = {1, 2, 3, 4}
set2 = {3, 4, 5, 6}
# Keeping only common items in set1
set1.intersection_update(set2)
print("Set 1 after keeping only common items:", set1)
Return value
The intersection() method returns a set object, retaining only those
items common in itself and obj.
Example
In the following example, we are defining two sets "s1" and "s2", then
using the intersection() method to create a new set "s3" containing
elements that are common to both "s1" and "s2" −
Open Compiler
s1 = {1,2,3,4,5}
s2 = {4,5,6,7,8}
print ("s1: ", s1, "s2: ", s2)
s3 = s1.intersection(s2)
print ("s3 = s1 & s2: ", s3)
Example
In the example below, we are defining two sets "s1" and "s2", then
using the symmetric_difference_update() method to modify "s1" so that
it contains elements that are in either "s1" or "s2", but not in both −
Open Compiler
s1 = {1,2,3,4,5}
s2 = {4,5,6,7,8}
print ("s1: ", s1, "s2: ", s2)
s1.symmetric_difference_update(s2)
print ("s1 after running symmetric difference ", s1)
Example
In the following example, we are defining two sets "s1" and "s2". We
are then using the symmetric_difference() method to create a new set
"s3" containing elements that are in either "s1" or "s2", but not in both
−
Open Compiler
s1 = {1,2,3,4,5}
s2 = {4,5,6,7,8}
print ("s1: ", s1, "s2: ", s2)
s3 = s1.symmetric_difference(s2)
print ("s1 = s1^s2 ", s3)
Loop Sets
Loop Through Set Items
Looping through set items in Python refers to iterating over each
element in a set. We can later perform required operations on each
item. These operations include list printing elements, conditional
operations, filtering elements etc.
Unlike lists and tuples, sets are unordered collections, so the elements
will be accessed in an arbitrary order. You can use a for loop to iterate
through the items in a set.
Syntax
Following is the basic syntax to loop through items in a set using a for
loop in Python −
for item in set:
# Code block to execute
Example
In the following example, we are using a for loop to iterate through
each element in the set "my_set" and retrieving each element −
Open Compiler
# Defining a set with multiple elements
my_set = {25, 12, 10, -21, 10, 100}
# Loop through each item in the set
for item in my_set:
# Performing operations on each element
print("Item:", item)
Output
Following is the output of the above code −
Item: 100
Item: 25
Item: 10
Item: -21
Item: 12
Example
In the below example, we are iterating through a set using an iterator
and a while loop. The "try" block retrieves and prints each item, while
the "except StopIteration" block breaks the loop when there are no
more items to fetch −
Open Compiler
# Defining a set with multiple elements
my_set = {1, 2, 3, 4, 5}
# Converting the set to an iterator
set_iterator = iter(my_set)
# Looping through each item in the set using a while loop
while True:
try:
# Getting the next item from the iterator
item = next(set_iterator)
# Performing operations on each element
print("Item:", item)
except StopIteration:
# If StopIteration is raised, break from the loop
break
Output
Output of the above code is as follows −
Item: 1
Item: 2
Item: 3
Item: 4
Item: 5
Where,
1. expression − It is an expression to evaluate for each item in
the iterable.
2. item − It is a variable representing each element in the
iterable.
3. iterable − It is a collection to iterate over (e.g., list, tuple,
set).
4. condition − It is an optional condition to filter elements
included in the resulting set.
Example
In this example, we are using a set comprehension to generate a set
containing squares of even numbers from the original list "numbers" −
Open Compiler
# Original list
numbers = [1, 2, 3, 4, 5]
# Set comprehension to create a set of squares of even numbers
squares_of_evens = {x**2 for x in numbers if x % 2 == 0}
# Print the resulting set
print(squares_of_evens)
Output
We get the output as shown below −
{16, 4}
Example
In the following example, we are first converting a set into a list. Then,
we iterate through the list using a for loop with enumerate() function,
retrieving each item along with its index −
Open Compiler
# Converting the set into a list
my_set = {1, 2, 3, 4, 5}
set_list = list(my_set)
# Iterating through the list
for index, item in enumerate(set_list):
print("Index:", index, "Item:", item)
Output
The output produced is as shown below −
Index: 0 Item: 1
Index: 1 Item: 2
Index: 2 Item: 3
Index: 3 Item: 4
Index: 4 Item: 5
Example
In this example, we loop through a sequence of numbers and add each
number to the set using the add() method. The loop iterates over
existing elements, while add() method adds new elements to the set −
Open Compiler
# Creating an empty set
my_set = set()
# Looping through a sequence and adding elements to the set
for i in range(5):
my_set.add(i)
print(my_set)
Join Sets
In Python, a set is an ordered collection of items. The items may be of
different types. However, an item in the set must be an immutable
object. It means, we can only include numbers, string and tuples in a
set and not lists. Python's set class has different provisions to join set
objects.
Example
In the following example, we are performing a union operation on sets
"s1" and "s2" using the "|" operator, creating a new set "s3" containing
elements from both sets without duplicates −
Open Compiler
s1={1,2,3,4,5}
s2={4,5,6,7,8}
s3 = s1|s2
print (s3)
Example
In the example below, we are updating set "s1" with the elements of
set "s2" using the update() method, modifying "s1" to contain elements
from both sets without duplicates −
Open Compiler
s1={1,2,3,4,5}
s2={4,5,6,7,8}
s1.update(s2)
print (s1)
Example
In the following example, we are creating a new set "s3" by unpacking
the elements of sets "s1" and "s2" using the * operator within a set
literal −
Open Compiler
s1={1,2,3,4,5}
s2={4,5,6,7,8}
s3 = {*s1, *s2}
print (s3)
Example
In this example, we are creating a new set "joined_set" using a set
comprehension. By iterating over a list containing "set1" and "set2",
and then iterating over each element "x" within each set "s", we merge
all elements from both sets into "joined_set" −
Open Compiler
set1 = {1, 2, 3}
set2 = {3, 4, 5}
joined_set = {x for s in [set1, set2] for x in s}
print(joined_set)
Output of the above code is as shown below −
{1, 2, 3, 4, 5}
Example
In the example below, we first initialise an empty set. Then, we iterate
over each element in "set1" and "set2" separately, adding each
element into a new set named "joined_set" using the add() method −
Open Compiler
set1 = {1, 2, 3}
set2 = {3, 4, 5}
# Initialising an empty set to hold the merged elements
joined_set = set()
# Iterating over set1 and adding its elements to the joined set
for element in set1:
joined_set.add(element)
# Iterating over set2 and adding its elements to the joined set
for element in set2:
joined_set.add(element)
print(joined_set)
Copy Sets
Python Copy Sets
Copying sets in Python refers to creating a new set that contains the
same elements as an existing set. Unlike simple variable assignment,
which creates a reference to the original set, copying ensures that
changes made to the copied set do not affect the original set, and vice
versa.
There are different methods for copying a set in Python, including using
the copy() method, the set() function or set comprehension.
Syntax
Following is the syntax of the copy() method −
set.copy()
Return Value
The copy() method returns a new set which is a shallow copy of the
existing set.
Example
In the following example, we are creating a copy of the set "lang1" and
storing it in "lang2", then retrieving both sets and their memory
addresses using id().
After adding an element to "lang1", we retrieve both sets and their
memory addresses again to show that "lan1" and "lan2" are
independent copies −
Open Compiler
lang1 = {"C", "C++", "Java", "Python"}
print ("lang1: ", lang1, "id(lang1): ", id(lang1))
lang = lang 1.copy()
print ("lang2: ", lang2, "id(lang2): ", id(lang2))
lang1.add("PHP")
print ("After updating lang1")
print ("lang1: ", lang1, "id(lang1): ", id(lang1))
print ("lang2: ", lang2, "id(lang2): ", id(lang2))
Output
This will produce the following output −
lang1: {'Python', 'Java', 'C', 'C++'} id(lang1): 2451578196864
lang2: {'Python', 'Java', 'C', 'C++'} id(lang2): 2451578197312
After updating lang1
lang1: {'Python', 'C', 'C++', 'PHP', 'Java'} id(lang1): 2451578196864
lang2: {'Python', 'Java', 'C', 'C++'} id(lang2): 2451578197312
Example
In this example, we are creating a copy of "original_set" using the set()
function and storing it in "copied_set" −
Open Compiler
# Original set
original_set = {1, 2, 3, 4}
# Copying the set using the set() function
copied_set = set(original_set)
print("copied set:", copied_set)
# Demonstrating that the sets are independent
copied_set.add(5)
print("copied set:",copied_set)
print("original set:",original_set)
Output
Following is the output of the above code −
copied set: {1, 2, 3, 4}
copied set: {1, 2, 3, 4, 5}
original set: {1, 2, 3, 4}
Example
In the example below, we create an original set named "original_set",
then copy it using set comprehension into "copied_set" −
Open Compiler
# Original set
original_set = {1, 2, 3, 4, 5}
# Copying the set using set comprehension
copied_set = {x for x in original_set}
print("Copied set:", copied_set)
Output
Output of the above code is as shown below −
Copied set: {1, 2, 3, 4, 5}
Set Operators
Set Operators in Python
The set operators in Python are special symbols and functions that
allow you to perform various operations on sets, such as union,
intersection, difference, and symmetric difference. These operators
provide a way to combine, compare, and modify sets.
Python implements them with following set operators −
In Python, you can perform the union operation using the union()
function or the | operator. This operation combines the elements of two
sets while eliminating duplicates, resulting in a new set containing all
unique elements from both sets −
Example
The following example uses the "|" operator and union() function, and
returns the union of two sets −
Open Compiler
set1 = {1, 2, 3}
set2 = {3, 4, 5}
set3 = {6, 8, 9}
set4 = {9, 45, 73}
union_set1 = set1.union(set2)
union_set2 = set3 | set4
print ('The union of set1 and set2 is', union_set1)
print ('The union of set3 and set4 is', union_set2)
Example
Following example uses & operator and intersection() function, and
returns intersection of two sets −
Open Compiler
set1 = {1, 2, 3}
set2 = {3, 4, 5}
set3 = {6, 8, 9}
set4 = {9, 8, 73}
intersection_set1 = set1.intersection(set2)
intersection_set2 = set3 & set4
print ('The intersection of set1 and set2 is', intersection_set1)
print ('The intersection of set3 and set4 is', intersection_set2)
Example
The following example uses the "-" operator and the difference()
function, and returns difference of two sets −
Open Compiler
set1 = {1, 2, 3}
set2 = {3, 4, 5}
set3 = {6, 8, 9}
set4 = {9, 8, 73}
difference_set1 = set1.difference(set2)
difference_set2 = set3 - set4
print ('The difference between set1 and set2 is', difference_set1)
print ('The difference between set3 and set4 is', difference_set2)
Example
The following example uses the "^" operator and the
symmetric_difference() function, and returns symbolic difference of two
sets −
Open Compiler
set1 = {1, 2, 3}
set2 = {3, 4, 5}
set3 = {6, 8, 9}
set4 = {9, 8, 73}
symmetric_difference_set1 = set1.symmetric_difference(set2)
symmetric_difference_set2 = set3 ^ set4
print ('The symmetric difference of set1 and set2 is',
symmetric_difference_set1)
print ('The symmetric difference of set3 and set4 is',
symmetric_difference_set2)
Example
The following example uses the "<=" operator and the issubset()
function, and returns subset testing of two sets −
Open Compiler
set1 = {1, 2}
set2 = {1, 2, 3, 4}
set3 = {64, 47, 245, 48}
set4 = {64, 47, 3}
is_subset1 = set1.issubset(set2)
is_subset2 = set3 <= set4
print ('set1 is a subset of set2:', is_subset1)
print ('set3 is a subset of set4:', is_subset2)
Set Methods
Sets in Python are unordered collections of unique elements, often used
for membership testing and eliminating duplicates. Set objects support
various mathematical operations like union, intersection, difference,
and symmetric difference. The set class includes several built-in
methods that allow you to add, update, and delete elements efficiently,
as well as to perform various set operations such as union, intersection,
difference, and symmetric difference on elements.
1 set.add()
Add an element to a set.
2 set.clear()
Remove all elements from a set.
3 set.copy()
Return a shallow copy of a set.
4 set.discard()
Remove an element from a set if it is a member.
5 set.pop()
Remove and return an arbitrary set element.
6 set.remove()
Remove an element from a set; it must be a
member.
Set Operations
These methods perform set operations such as union, intersection,
difference, and symmetric difference −
Sr. Methods with Description
No.
1 set.update()
Update a set with the union of itself and others.
2 set.difference_update()
Remove all elements of another set from this set.
3 set.intersection()
Returns the intersection of two sets as a new set.
4 set.intersection_update()
Updates a set with the intersection of itself and another.
5 set.isdisjoint()
Returns True if two sets have a null intersection.
6 set.issubset()
Returns True if another set contains this set.
7 set.issuperset()
Returns True if this set contains another set.
8 set.symmetric_difference()
Returns the symmetric difference of two sets as a new set.
9 set.symmetric_difference_update()
Update a set with the symmetric difference of itself and
another.
10 set.union()
Returns the union of sets as a new set.
11 set.difference()
Returns the difference of two or more sets as a new set.
Set Exercises
Python Set Exercise 1
Python program to find common elements in two lists with the help of
set operations −
Open Compiler
l1=[1,2,3,4,5]
l2=[4,5,6,7,8]
s1=set(l1)
s2=set(l2)
commons = s1&s2 # or s1.intersection(s2)
commonlist = list(commons)
print (commonlist)
Dictionaries
Dictionaries in Python
In Python, a dictionary is a built-in data type that stores data in key-
value pairs. It is an unordered, mutable, and indexed collection. Each
key in a dictionary is unique and maps to a value. Dictionaries are often
used to store data that is related, such as information associated with a
specific entity or object, where you can quickly retrieve a value based
on its key.
Python's dictionary is an example of a mapping type. A mapping object
'maps' the value of one object to another. To establish mapping
between a key and a value, the colon (:) symbol is put between the
two.
Each key-value pair is separated by a comma and enclosed within curly
braces {}. The key and value within each pair are separated by a colon
(:), forming the structure key:value.
Given below are some examples of Python dictionary objects −
capitals = {"Maharashtra":"Mumbai", "Gujarat":"Gandhinagar",
"Telangana":"Hyderabad", "Karnataka":"Bengaluru"}
numbers = {10:"Ten", 20:"Twenty", 30:"Thirty",40:"Forty"}
marks = {"Savita":67, "Imtiaz":88, "Laxman":91, "David":49}
Example 1
Only a number, string or tuple can be used as a key. All of them are
immutable. You can use an object of any type as the value. Hence
following definitions of dictionary are also valid −
Open Compiler
d1 = {"Fruit":["Mango","Banana"], "Flower":["Rose", "Lotus"]}
d2 = {('India, USA'):'Countries', ('New Delhi', 'New York'):'Capitals'}
print (d1)
print (d2)
Example 2
Python doesn't accept mutable objects such as lists as keys, and raises
TypeError.
Open Compiler
d1 = {["Mango","Banana"]:"Fruit", "Flower":["Rose", "Lotus"]}
print (d1)
Example 3
You can assign a value to more than one key in a dictionary, but a key
cannot appear more than once in a dictionary.
Open Compiler
d1 = {"Banana":"Fruit", "Rose":"Flower", "Lotus":"Flower",
"Mango":"Fruit"}
d2 = {"Fruit":"Banana","Flower":"Rose", "Fruit":"Mango",
"Flower":"Lotus"}
print (d1)
print (d2)
Creating a Dictionary
You can create a dictionary in Python by placing a comma-separated
sequence of key-value pairs within curly braces {}, with a colon :
separating each key and its associated value. Alternatively, you can
use the dict() function.
Example
The following example demonstrates how to create a dictionary called
"student_info" using both curly braces and the dict() function −
Open Compiler
# Creating a dictionary using curly braces
sports_player = {
"Name": "Sachin Tendulkar",
"Age": 48,
"Sport": "Cricket"
}
print ("Dictionary using curly braces:", sports_player)
# Creating a dictionary using the dict() function
student_info = dict(name="Alice", age=21, major="Computer
Science")
print("Dictionary using dict():",student_info)
1 dict.clear()
Removes all elements of dictionary dict
2 dict.copy()
Returns a shallow copy of dictionary dict
3 dict.fromkeys()
Create a new dictionary with keys from seq and values set to
value.
4 dict.get(key, default=None)
For key key, returns value or default if key not in dictionary
5 dict.has_key(key)
Returns true if key in dictionary dict, false otherwise
6 dict.items()
Returns a list of dicts (key, value) tuple pairs
7 dict.keys()
Returns list of dictionary dict's keys
8 dict.setdefault(key, default=None)
Similar to get(), but will set dict[key]=default if key is not
already in dict
9 dict.update(dict2)
Adds dictionary dict2's key-values pairs to dict
10 dict.values()
Returns list of dictionary dict's values
1 cmp(dict1, dict2)
Compares elements of both dict.
2 len(dict)
Gives the total length of the dictionary. This would be equal to
the number of items in the dictionary.
3 str(dict)
Produces a printable string representation of a dictionary
4 type(variable)
Returns the type of the passed variable. If the passed variable
is a dictionary, then it would return a dictionary type.
Example 1
In the following example, we are defining a dictionary named "capitals"
where each key represents a state and its corresponding value
represents the capital city.
Then, we access and retrieve the capital cities of Gujarat and Karnataka
using their respective keys 'Gujarat' and 'Karnataka' from the dictionary
−
Open Compiler
capitals = {"Maharashtra":"Mumbai", "Gujarat":"Gandhinagar",
"Telangana":"Hyderabad", "Karnataka":"Bengaluru"}
print ("Capital of Gujarat is : ", capitals['Gujarat'])
print ("Capital of Karnataka is : ", capitals['Karnataka'])
Example 2
Python raises a KeyError if the key given inside the square brackets is
not present in the dictionary object −
Open Compiler
capitals = {"Maharashtra":"Mumbai", "Gujarat":"Gandhinagar",
"Telangana":"Hyderabad", "Karnataka":"Bengaluru"}
print ("Capital of Haryana is : ", capitals['Haryana'])
Syntax
Following is the syntax of the get() method in Python −
Val = dict.get("key")
Example 1
In the example below, we are defining a dictionary named "capitals"
where each key-value pair maps a state to its capital city. Then, we use
the get() method to retrieve the capital cities of "Gujarat" and
"Karnataka" −
Open Compiler
capitals = {"Maharashtra":"Mumbai", "Gujarat":"Gandhinagar",
"Telangana":"Hyderabad", "Karnataka":"Bengaluru"}
print ("Capital of Gujarat is: ", capitals.get('Gujarat'))
print ("Capital of Karnataka is: ", capitals.get('Karnataka'))
Example 2
Unlike the "[]" operator, the get() method doesn't raise error if the key
is not found; it return None −
Open Compiler
capitals = {"Maharashtra":"Mumbai", "Gujarat":"Gandhinagar",
"Telangana":"Hyderabad", "Karnataka":"Bengaluru"}
print ("Capital of Haryana is : ", capitals.get('Haryana'))
Example 3
The get() method accepts an optional string argument. If it is given,
and if the key is not found, this string becomes the return value −
Open Compiler
capitals = {"Maharashtra":"Mumbai", "Gujarat":"Gandhinagar",
"Telangana":"Hyderabad", "Karnataka":"Bengaluru"}
print ("Capital of Haryana is : ", capitals.get('Haryana', 'Not found'))
Example
In this example, we are retrieving all the keys from the dictionary
"student_info" using the keys() method −
Open Compiler
# Creating a dictionary with keys and values
student_info = {
"name": "Alice",
"age": 21,
"major": "Computer Science"
}
# Accessing all keys using the keys() method
all_keys = student_info.keys()
print("Keys:", all_keys)
Example 1
In this example, we are directly accessing associated with the key
"name" and "age" using the square brackets −
Open Compiler
# Creating a dictionary with student information
student_info = {
"name": "Alice",
"age": 21,
"major": "Computer Science"
}
# Accessing dictionary values using square brackets
name = student_info["name"]
age = student_info["age"]
print("Name:", name)
print("Age:", age)
Output of the above code is as follows −
Name: Alice
Age: 21
Example 2
In here, we use the get() method to retrieve the value associated with
the key "major" and provide a default value of "2023" for the key
"graduation_year" −
Open Compiler
# Creating a dictionary with student information
student_info = {
"name": "Alice",
"age": 21,
"major": "Computer Science"
}
# Accessing dictionary values using the get() method
major = student_info.get("major")
# Default value provided if key is not found
grad_year = student_info.get("graduation_year", "2023")
print("Major:", major)
print("Graduation Year:", grad_year)
Example 3
Now, we are retrieving all the values from the dictionary "student_info"
using the values() method −
Open Compiler
# Creating a dictionary with keys and values
student_info = {
"name": "Alice",
"age": 21,
"major": "Computer Science"
}
# Accessing all values using the values() method
all_values = student_info.values()
print("Values:", all_values)
Example
In the following example, we are using the items() function to retrieve
all the key-value pairs from the dictionary "student_info" −
Open Compiler
# Creating a dictionary with student information
student_info = {
"name": "Alice",
"age": 21,
"major": "Computer Science"
}
# Using the items() method to get key-value pairs
all_items = student_info.items()
print("Items:", all_items)
# Iterating through the key-value pairs
print("Iterating through key-value pairs:")
for key, value in all_items:
print(f"{key}: {value}")
Example
In the following example, we are defining a dictionary named "person"
with keys 'name', 'age', and 'city' and their corresponding values. Then,
we modify the value associated with the key 'age' to 26 −
Open Compiler
# Initial dictionary
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}
# Modifying the value associated with the key 'age'
person['age'] = 26
print(person)
Example
In the example below, we are using the update() method to modify the
values associated with the keys 'age' and 'city' in the 'persons'
dictionary −
Open Compiler
# Initial dictionary
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}
# Updating multiple values
person.update({'age': 26, 'city': 'Los Angeles'})
print(person)
Example
In this example, we conditionally modify the value associated with the
key 'age' to '26' if the current value is '25' in the 'persons' dictionary −
Open Compiler
# Initial dictionary
person = {'name': 'Alice', 'age': 25, 'city': 'New York'}
# Conditionally modifying the value associated with 'age'
if person['age'] == 25:
person['age'] = 26
print(person)
Example
In this example, we are creating a dictionary named "marks" with keys
representing names and their corresponding integer values. Then, we
add a new key-value pair 'Kavita': 58 to the dictionary using square
bracket notation −
Open Compiler
marks = {"Savita":67, "Imtiaz":88, "Laxman":91, "David":49}
print ("Initial dictionary: ", marks)
marks['Kavya'] = 58
print ("Dictionary after new addition: ", marks)
Example
In the following example, we use the update() method to add multiple
new key-value pairs 'Kavya': 58 and 'Mohan': 98 to the dictionary
'marks' −
Open Compiler
marks = {"Savita":67, "Imtiaz":88}
print ("Initial dictionary: ", marks)
marks.update({'Kavya': 58, 'Mohan': 98})
print ("Dictionary after new addition: ", marks)
Example
In the example below, we are initialising two dictionaries named
"marks" and "marks1", both containing names and their corresponding
integer values. Then, we create a new dictionary "newmarks" by
merging "marks" and "marks1" using dictionary unpacking −
Open Compiler
marks = {"Savita":67, "Imtiaz":88, "Laxman":91, "David":49}
print ("marks dictionary before update: \n", marks)
marks1 = {"Sharad": 51, "Mushtaq": 61, "Laxman": 89}
newmarks = {**marks, **marks1}
print ("marks dictionary after update: \n", newmarks)
Example
In this example, we are using the | operator to combine the dictionaries
"marks" and "marks1" with "marks1" values taking precedence in case
of duplicate keys −
Open Compiler
marks = {"Savita":67, "Imtiaz":88, "Laxman":91, "David":49}
print ("marks dictionary before update: \n", marks)
marks1 = {"Sharad": 51, "Mushtaq": 61, "Laxman": 89}
newmark's = marks | marks1
print ("marks dictionary after update: \n", newmarks)
Example
In the following example, we use the |= operator to update "marks"
with the key-value pairs from "marks1", with values from "marks1"
taking precedence in case of duplicate keys −
Open Compiler
marks = {"Savita":67, "Imtiaz":88, "Laxman":91, "David":49}
print ("marks dictionary before update: \n", marks)
marks1 = {"Sharad": 51, "Mushtaq": 61, "Laxman": 89}
marks |= marks1
print ("marks dictionary after update: \n", marks)
Example
In this example, we use the setdefault() to add the key-value pair
"major": "Computer Science" to the "student" dictionary −
Open Compiler
# Initial dictionary
student = {"name": "Alice", "age": 21}
# Adding a new key-value pair
major = student.setdefault("major", "Computer Science")
print(student)
Since the key "major" does not exist, it is added with the specified
default value as shown in the output below −
{'name': 'Alice', 'age': 21, 'major': 'Computer Science'}
Example
In this example, we are initialising instances of defaultdict with different
default factories: int to initialise missing keys with 0, list to initialise
missing keys with an empty list, and a custom function default_value to
initialise missing keys with the return value of the function −
Open Compiler
from collections import defaultdict
# Using int as the default factory to initialise missing keys with 0
d = defaultdict(int)
# Incrementing the value for key 'a'
d["a"] += 1
print(d)
# Using list as the default factory to initialise missing keys with an
empty list
d = defaultdict(list)
# Appending to the list for key 'b'
d["b"].append(1)
print(d)
# Using a custom function as the default factory
def default_value():
return "N/A"
d = defaultdict(default_value)
print(d["c"])
Example 1
In the following example, we are creating a dictionary named numbers
with integer keys and their corresponding string values. Then, delete
the item with the key '20' using the del keyword −
Open Compiler
numbers = {10:"Ten", 20:"Twenty", 30:"Thirty",40:"Forty"}
print ("numbers dictionary before delete operation: \n", numbers)
del numbers[20]
print ("numbers dictionary before delete operation: \n", numbers)
Example 2
The del keyword, when used with a dictionary object, removes the
dictionary from memory −
Open Compiler
numbers = {10:"Ten", 20:"Twenty", 30:"Thirty",40:"Forty"}
print ("numbers dictionary before delete operation: \n", numbers)
del numbers
print ("numbers dictionary before delete operation: \n", numbers)
Following is the output obtained −
numbers dictionary before delete operation:
{10: 'Ten', 20: 'Twenty', 30: 'Thirty', 40: 'Forty'}
Traceback (most recent call last):
File "C:\Users\mlath\examples\main.py", line 5, in <module>
print ("numbers dictionary before delete operation: \n", numbers)
^^^^^^^
NameError: name 'numbers' is not defined
Example
In this example, we are using the pop() method to remove the item
with the key '20' (storing its value in val) from the 'numbers' dictionary.
We then retrieve the updated dictionary and the popped value −
Open Compiler
numbers = {10:"Ten", 20:"Twenty", 30:"Thirty",40:"Forty"}
print ("numbers dictionary before pop operation: \n", numbers)
val = numbers.pop(20)
print ("nubvers dictionary after pop operation: \n", numbers)
print ("Value popped: ", val)
Example
In the example below, we use the popitem() method to remove an
arbitrary item from the dictionary 'numbers' (storing both its key-value
pair in val), and retrieve the updated dictionary along with the popped
key-value pair −
Open Compiler
numbers = {10:"Ten", 20:"Twenty", 30:"Thirty",40:"Forty"}
print ("numbers dictionary before pop operation: \n", numbers)
val = numbers.popitem()
print ("numbers dictionary after pop operation: \n", numbers)
print ("Value popped: ", val)
Example
In this example, we remove items 'age' and 'major' from the
'student_info' dictionary based on a predefined list of keys to remove −
Open Compiler
# Creating a dictionary
student_info = {
"name": "Alice",
"age": 21,
"major": "Computer Science"
}
# Removing items based on conditions
keys_to_remove = ["age", "major"]
for key in keys_to_remove:
student_info.pop(key, None)
print(student_info)
The items(), keys(), and values() methods of dict class return view
objects. These views are refreshed dynamically whenever any change
occurs in the contents of their source dictionary object.
Syntax
Following is the syntax of the items() method −
Obj = dict.items()
Return value
The items() method returns a dict_items object which is a dynamic
view of (key,value) tuples.
Example
In the following example, we first obtain the dict_items object with the
items() method and check how it is dynamically updated when the
dictionary object is updated.
Open Compiler
numbers = {10:"Ten", 20:"Twenty", 30:"Thirty",40:"Forty"}
obj = numbers.items()
print ('type of obj: ', type(obj))
print (obj)
print ("update numbers dictionary")
numbers.update({50:"Fifty"})
print ("View automatically updated")
print (obj)
Syntax
Following is the syntax of the keys() method −
Obj = dict.keys()
Return value
The keys() method returns a dict_keys object which is a view of keys in
the dictionary.
Example
In this example, we are creating a dictionary named "numbers" with
integer keys and their corresponding string values. Then, we obtain a
view object "obj" of the keys using the keys() method, and retrieve its
type and content −
Open Compiler
numbers = {10:"Ten", 20:"Twenty", 30:"Thirty",40:"Forty"}
obj = numbers.keys()
print ('type of obj: ', type(obj))
print (obj)
print ("update numbers dictionary")
numbers.update({50:"Fifty"})
print ("View automatically updated")
print (obj)
Syntax
Following is the syntax of the values() method −
Obj = dict.values()
Return value
The values() method returns a dict_values view of all the values present
in the dictionary.
Example
In the example below, we obtain a view object "obj" of the values using
the values() method from the "numbers" dictionary −
Open Compiler
numbers = {10:"Ten", 20:"Twenty", 30:"Thirty",40:"Forty"}
obj = numbers.values()
print ('type of obj: ', type(obj))
print (obj)
print ("update numbers dictionary")
numbers.update({50:"Fifty"})
print ("View automatically updated")
print (obj)
Loop Dictionaries
Example
In this example, the items() method is called on the "student"
dictionary, returning a view object containing the key-value pairs. The
for loop iterates over each pair, assigning the key to the variable "key"
and the corresponding value to the variable "value" −
Open Compiler
student = {"name": "Alice", "age": 21, "major": "Computer Science"}
# Looping through key-value pairs
for key, value in student.items():
print(key, value)
Example
In the example below, the keys() method is called on the "student"
dictionary, returning a view object containing the keys. The for loop
iterates over each key in the view object, allowing you to perform
operations based on the keys of the dictionary during each iteration −
Open Compiler
student = {"name": "Alice", "age": 21, "major": "Computer Science"}
# Looping through keys
for key in student.keys():
print(key)
Example
In the following example, the values() method is called on the "student"
dictionary, returning a view object containing the values −
Open Compiler
student = {"name": "Alice", "age": 21, "major": "Computer Science"}
# Looping through values
for value in student.values():
print(value)
Shallow Copy
When you perform a shallow copy, a new dictionary object is created,
but it contains references to the same objects that the original
dictionary references.
This is useful when you want to duplicate the structure of a dictionary
without duplicating the nested objects it contains.
This can be done using the copy() method or the dict() function as
shown below −
Deep Copy
A deep copy creates a new dictionary and recursively copies all objects
found in the original dictionary. This means that not only the dictionary
itself but also all objects it contains (including nested dictionaries, lists,
etc.) are copied. As a result, changes made to the deep copy do not
affect the original dictionary and vice versa.
We can achieve this using the deepcopy() function in the copy module.
Example
We can see in the example below that the "age" value in the deep copy
is changed, the "skills" list in the deep copy is modified (an item is
appended) and the "education" dictionary in the deep copy is modified,
all without affecting the original −
Open Compiler
import copy
original_dict = {
"name": "Alice",
"age": 25,
"skills": ["Python", "Data Science"],
"education": {
"degree": "Bachelor's",
"field": "Computer Science"
}
}
# Creating a deep copy
deep_copy = copy.deepcopy(original_dict)
# Modifying the deep copy
deep_copy["age"] = 26
deep_copy["skills"].append("Machine Learning")
deep_copy["education"]["degree"] = "Master's"
# Retrieving both dictionaries
print("Original dictionary:", original_dict)
print("Deep copy:", deep_copy)
Syntax
Following is the basic syntax of the copy() method in Python −
new_dict = original_dict.copy()
Where, original_dict is the dictionary you want to copy.
Example
The following example demonstrates the creation of a shallow copy of a
dictionary using the copy() method −
Open Compiler
# Creating a dictionary
dict1 = {"name": "Krishna", "age": "27", "doy": 1992}
# Copying the dictionary
dict2 = dict1.copy()
# Printing both of the dictionaries
print("dict1 :", dict1)
print("dict2 :", dict2)
Output
We will get the output as shown below −
dict1 : {'name': 'Krishna', 'age': '27', 'doy': 1992}
dict2 : {'name': 'Krishna', 'age': '27', 'doy': 1992}
Nested Dictionaries
Nested Dictionaries
Nested dictionaries in Python refer to dictionaries that are stored as
values within another dictionary. In other words, a dictionary can
contain other dictionaries as its values, forming a hierarchical or nested
structure.
Nested dictionaries can be modified, updated, or extended in the same
way as regular dictionaries. You can add, remove, or update key-value
pairs at any level of the nested structure.
Example
In the following example, we are defining a nested dictionary
"students" where each key represents a student's name and its value is
another dictionary containing details about the student.
Then, we add a new key-value pair to Alice's nested dictionary and add
a new nested dictionary for a new student, Charlie −
Open Compiler
# Initial nested dictionary
students = {
"Alice": {"age": 21, "major": "Computer Science"},
"Bob": {"age": 20, "major": "Engineering"}
}
# Adding a new key-value pair to Alice's nested dictionary
students["Alice"]["GPA"] = 3.8
# Adding a new nested dictionary for a new student
students["Charlie"] = {"age": 22, "major": "Mathematics"}
print(students)
Example
In the following example, we delete the nested dictionary for "Bob"
from "students" dictionary using the del statement −
Open Compiler
# Define a nested dictionary
students = {
"Alice": {"age": 21, "major": "Computer Science"},
"Bob": {"age": 20, "major": "Engineering"},
"Charlie": {"age": 22, "major": "Mathematics"}
}
# Delete the dictionary for Bob
del students["Bob"]
# Print the updated nested dictionary
print(students)
Example
In this example, we are iterating through the "students" dictionary,
retrieving each student's name and their corresponding details by
iterating through the nested dictionaries −
Open Compiler
# Defining a nested dictionary
students = {
"Alice": {"age": 21, "major": "Computer Science"},
"Bob": {"age": 20, "major": "Engineering"},
"Charlie": {"age": 22, "major": "Mathematics"}
}
# Iterating through the Nested Dictionary:
for student, details in students.items():
print(f"Student: {student}")
for key, value in details.items():
print(f" {key}: {value}")
Dictionary Methods
A Python dictionary is an object of the built-in dict class, which defines
the following methods −
Dictionary Methods
Sr. Method and Description
No.
1 dict.clear()
Removes all elements of dictionary dict.
2 dict.copy()
Returns a shallow copy of dictionary dict.
3 dict.fromkeys()
Create a new dictionary with keys from seq and values set to
value.
4 dict.get(key, default=None)
For key key, returns value or default if key not in dictionary.
5 dict.has_key(key)
Returns true if a given key is available in the dictionary,
otherwise it returns a false.
6 dict.items()
Returns a list of dicts (key, value) tuple pairs.
7 dict.keys()
Returns a list of dictionary dict's keys.
8 dict.pop()
Removes the element with specified key from the collection
9 dict.popitem()
Removes the last inserted key-value pair
10 dict.setdefault(key, default=None)
Similar to get(), but will set dict[key]=default if key is not
already in dict.
11 dict.update(dict2)
Adds dictionary dict2's key-values pairs to dict.
12 dict.values()
Returns a list of dictionary dict's values.
Dictionary Exercises
Dictionary Exercise 1
Python program to create a new dictionary by extracting the keys from
a given dictionary.
Open Compiler
d1 = {"one":11, "two":22, "three":33, "four":44, "five":55}
keys = ['two', 'five']
d2={}
for k in keys:
d2[k]=d1[k]
print (d2)
Dictionary Exercise 2
Python program to convert a dictionary to a list of (k,v) tuples.
Open Compiler
d1 = {"one":11, "two":22, "three":33, "four":44, "five":55}
L1 = list(d1.items())
print (L1)
Dictionary Exercise 3
Python program to remove keys with same values in a dictionary.
Open Compiler
d1 = {"one":"eleven", "2":2, "three":3, "11":"eleven", "four":44,
"two":2}
vals = list(d1.values())#all values
uvals = [v for v in vals if vals.count(v)==1]#unique values
d2 = {}
for k,v in d1.items():
if v in uvals:
d = {k:v}
d2.update(d)
print ("dict with unique value:",d2)
Arrays
Arrays in Python
Unlike other programming languages like C++ or Java, Python does not
have built-in support for arrays. However, Python has several data
types like lists and tuples (especially lists) that are often used as arrays
but items stored in these types of sequences need not be of the same
type.
In addition, we can create and manipulate arrays using the array
module. Before proceeding further, let's understand arrays in general.
Array Representation
Arrays are represented as a collection of multiple containers where
each container stores one element. These containers are indexed from
'0' to 'n-1', where n is the size of that particular array.
Arrays can be declared in various ways in different languages. Below is
an illustration −
Where,
typecode − The typecode character used to specify the type
of elements in the array.
initializer − It is an optional value from which an array is
initialised. It must be a list, a bytes-like object, or iterable
elements of the appropriate type.
Example
The following example shows how to create an array in Python using
the array module.
Open Compiler
import array as arr
# creating an array with integer type
a = arr.array('i', [1, 2, 3])
print (type(a), a)
# creating an array with char type
a = arr.array('u', 'BAT')
print (type(a), a)
# creating an array with float type
a = arr.array('d', [1.1, 2.2, 3.3])
print (type(a), a)
'u' Unicode 2
character
Example
The below code shows how to access elements of an array.
Open Compiler
from array import *
array1 = array('i', [10,20,30,40,50])
print (array1[0])
print (array1[2])
Insertion Operation
In insertion operation, we insert one or more data elements into an
array. Based on the requirement, a new element can be added at the
beginning, end, or any given index of array.
Example
Here, we add a data element at the middle of the array using the
python in-built insert() method.
Open Compiler
from array import *
array1 = array('i', [10,20,30,40,50])
array1.insert(1,60)
for x in array1:
print(x)
Deletion Operation
Deletion refers to removing an existing element from the array and re-
organizing all elements of an array.
Here, we remove a data element at the middle of the array using the
python in-built remove() method.
Open Compiler
from array import *
array1 = array('i', [10,20,30,40,50])
array1.remove(40)
for x in array1:
print(x)
Search Operation
You can perform a search operation on an array to find an array
element based on its value or its index.
Example
Here, we search a data element using the python in-built index()
method −
Open Compiler
from array import *
array1 = array('i', [10,20,30,40,50])
print (array1.index(40))
When we compile and execute the above program, it will display the
index of the searched element. If the value is not present in the array,
it will return an error.
3
Update Operation
Update operation refers to updating an existing element from the array
at a given index. Here, we simply reassign a new value to the desired
index we want to update.
Example
In this example, we are updating the value of the array element at
index 2.
Open Compiler
from array import *
array1 = array('i', [10,20,30,40,50])
array1[2] = 80
for x in array1:
print(x)
Using indexing
The process of accessing elements of an array through the index is
known as Indexing . In this process, we simply need to pass the index
number inside the index operator []. The index of an array in Python
starts with 0 which means you can find its first element at index 0 and
the last at one less than the length of the given array.
Example
The following example shows how to access elements of an array using
indexing.
Open Compiler
import array as arr
# creating array
numericArray = arr.array('i', [111, 211, 311, 411, 511])
#indexing
print (numericArray[0])
print (numericArray[1])
print (numericArray[2])
When you run the above code, it will show the following output −
111
211
311
Using iteration
In this approach, a block of code is executed repeatedly using loops
such as for and while. It is used when you want to access array
elements one by one.
Example
In the below code, we use the for loop to access all the elements of the
specified array.
Open Compiler
import array as arr
# creating array
numericArray = arr.array('i', [111, 211, 311, 411, 511])
# iteration through for loop
for item in numericArray:
print(item)
Example
In the below example, we will see how to use the enumerate() function
to access array items.
Open Compiler
import array as arr
# creating array
numericArray = arr.array('i', [111, 211, 311, 411, 511])
# use of enumerate() function
for loc, val in enumerate(numericArray):
print(f"Index: {loc}, value: {val}")
Example
The following example demonstrates the slicing operation in Python.
Open Compiler
import array as arr
# creating array
numericArray = arr.array('i', [111, 211, 311, 411, 511])
# slicing operation
print (numericArray[2:])
print (numericArray[0:3])
On executing the above code, it will display the following result −
array('i', [311, 411, 511])
array('i', [111, 211, 311])
Syntax
Syntax of the append() method is as follows −
append(v)
Where,
v − new value is added at the end of the array. The new value
must be of the same type as the datatype argument used
while declaring the array object.
Example
Here, we are adding an element at the end of the specified array using
the append() method.
Open Compiler
import array as arr
a = arr.array('i', [1, 2, 3])
a.append(10)
print (a)
Syntax
Syntax of this method is shown below −
insert(i, v)
Where,
i − The index at which a new value is to be inserted.
v − The value to be inserted. Must be of the arraytype.
Example
The following example shows how to add array elements at specific
indexes with the help of insert() method.
Open Compiler
import array as arr
a = arr.array('i', [1, 2, 3])
a.insert(1,20)
print (a)
It will produce the following output −
array('i', [1, 20, 2, 3])
Syntax
This method has the following syntax −
extend(x)
Where,
x − This parameter specifies an array or iterable.
Example
In this example, we are adding items from another array to the
specified array.
Open Compiler
import array as arr
a = arr.array('i', [1, 2, 3, 4, 5])
b = arr.array('i', [6,7,8,9,10])
a.extend(b)
print (a)
Syntax
array.remove(v)
Example
The below example shows the usage of remove() method. Here, we are
removing an element from the specified array.
Open Compiler
import array as arr
# creating array
numericArray = arr.array('i', [111, 211, 311, 411, 511])
# before removing array
print ("Before removing:", numericArray)
# removing array
numericArray.remove(311)
# after removing array
print ("After removing:", numericArray)
Syntax
array.pop(i)
Example
In this example, we will see how to use the pop() method to remove
elements from an array.
Open Compiler
import array as arr
# creating array
numericArray = arr.array('i', [111, 211, 311, 411, 511])
# before removing array
print ("Before removing:", numericArray)
# removing array
numericArray.pop(3)
# after removing array
print ("After removing:", numericArray)
Loop Arrays
Loops are used to repeatedly execute a block of code. In Python, there
are two types of loops named for loop and while loop. Since the array
object behaves like a sequence, you can iterate through its elements
with the help of loops.
The reason for looping through arrays is to perform operations such as
accessing, modifying, searching, or aggregating elements of the array.
Example
The below example demonstrates how to iterate over an array using
the "for" loop −
Open Compiler
import array as arr
newArray = arr.array('i', [56, 42, 23, 85, 45])
for iterate in newArray:
print (iterate)
Example
The following example shows how you can loop through an array using
a while loop −
Open Compiler
import array as arr
# creating array
a = arr.array('i', [96, 26, 56, 76, 46])
# checking the length
l = len(a)
# loop variable
idx = 0
# while loop
while idx < l:
print (a[idx])
# incrementing the while loop
idx+=1
Example
The code below illustrates how to use a loop with an array index.
Open Compiler
import array as arr
a = arr.array('d', [56, 42, 23, 85, 45])
l = len(a)
for x in range(l):
print (a[x])
On running the above code, it will show the below output −
56.0
42.0
23.0
85.0
45.0
Copy Arrays
In Python, copying an array refers to the process of creating a new
array that contains all the elements of the original array. This operation
can be done using assignment operator (=) and deepcopy() method. In
this chapter, we discuss how to copy an array object to another.
But, before getting into the details let's briefly discuss arrays.
Python's built-in sequence types i.e. list, tuple, and string are indexed
collections of items. However, unlike arrays in C/C++, Java etc. they
are not homogenous, in the sense the elements in these types of
collection may be of different types. Python's array module helps you to
create objects similar to Java-like arrays.
Python arrays can be of string, integer or float type. The array class
constructor is used as follows −
import array
obj = array.array(typecode[, initializer])
Example
In the following example, we are using assignment operators to copy
arrays in Python.
Open Compiler
import array as arr
a = arr.array('i', [110, 220, 330, 440, 550])
b=a
print("Copied array:",b)
print (id(a), id(b))
Check the id() of both a and b. Same value of id confirms that a simple
assignment doesn't create a copy. Since "a" and "b" refer to the same
array object, any change in the array "a" will reflect in "b" too −
a[2] = 10
print (a,b)
Example
The following example demonstrates how to copy array in Python −
Open Compiler
import array as arr
import copy
a = arr.array('i', [110, 220, 330, 440, 550])
b = copy.deepcopy(a)
print("Copied array:",b)
This proves that a new object "b" is created which is an actual copy of
"a". If we change an element in "a", it is not reflected in "b".
a[2]=10
print (a,b)
Reverse Arrays
Example
The below example demonstrates how to use the slicing operation to
reverse an array in Python.
Open Compiler
import array as arr
# creating array
numericArray = arr.array('i', [88, 99, 77, 55, 66])
print("Original array:", numericArray)
revArray = numericArray[::-1]
print("Reversed array:",revArray)
When you run the code, it will produce the following output −
Original array: array('i', [88, 99, 77, 55, 66])
Reversed array: array('i', [66, 55, 77, 99, 88])
Example
Here, we will see the use of reverse() method in reversing an array in
Python.
Open Compiler
import array as arr
# creating an array
numericArray = arr.array('i', [10,5,15,4,6,20,9])
print("Array before reversing:", numericArray)
# converting the array into list
newArray = numericArray.tolist()
# reversing the list
newArray.reverse()
# creating a new array from reversed list
revArray = arr.array('i', newArray)
print ("Array after reversing:",revArray)
Example
In this example, we are using the reversed() method to reverse an
array in Python.
Open Compiler
import array as arr
# creating an array
numericArray = arr.array('i', [12, 10, 14, 16, 20, 18])
print("Array before reversing:", numericArray)
# reversing the array
newArray = list(reversed(numericArray))
# creating a new array from reversed list
revArray = arr.array('i', newArray)
print ("Array after reversing:",revArray)
Example
The following example shows how to reverse an array in Python using a
for loop.
Open Compiler
import array as arr
a = arr.array('i', [10,5,15,4,6,20,9])
b = arr.array('i')
for i in range(len(a)-1, -1, -1):
b.append(a[i])
print(a)
print(b)
Sort Arrays
Python's array module defines the array class. An object of array class
is similar to the array as present in Java or C/C++. Unlike the built-in
Python sequences, array is a homogenous collection of either strings,
or integers, or float objects.
The array class doesn't have any function/method to give a sorted
arrangement of its elements. However, we can achieve it with one of
the following approaches −
Using a sorting algorithm
Using the sort() method from List
Using the built-in sorted() function
Example
Run the following code using a Python code editor −
Open Compiler
import array as arr
a = arr.array('i', [10,5,15,4,6,20,9])
for i in range(0, len(a)):
for j in range(i+1, len(a)):
if(a[i] > a[j]):
temp = a[i];
a[i] = a[j];
a[j] = temp;
print (a)
Example
The following code shows how to get a sorted array using the sort()
method.
Open Compiler
import array as arr
# creating array
orgnlArray = arr.array('i', [10,5,15,4,6,20,9])
print("Original array:", orgnlArray)
# converting to list
sortedList = orgnlArray.tolist()
# sorting the list
sortedList.sort()
# creating array from sorted list
sortedArray = arr.array('i', sortedList)
print("Array after sorting:",sortedArray)
The function returns a new list containing all items from the iterable in
ascending order. Set the reverse parameter to True to get a descending
order of items.
The sorted() function can be used along with any iterable. Python
array is an iterable as it is an indexed collection. Hence, an array can
be used as a parameter to the sorted() function.
Example
In this example, we will see the use of the sorted() method in sorting an
array.
Open Compiler
import array as arr
a = arr.array('i', [4, 5, 6, 9, 10, 15, 20])
sorted(a)
print(a)
Join Arrays
The process of joining two arrays is termed as Merging or
concatenating. Python provides multiple ways to merge two arrays
such as append() and extend() methods. But, before merging two
arrays always ensure that both arrays are of the same data type
otherwise the program will throw an error.
In Python, array is a homogenous collection of Python's built in data
types such as strings, integer or float objects. However, array itself is
not a built-in type, instead we need to use Python's built-in array
module.
Using + operator
We can also use + operator to concatenate or merge two arrays. In
this approach, we first convert arrays to list objects, then concatenate
the lists using the + operator and convert back to get a merged array.
Array Methods
1 append(x)
Appends a new item with value x to the end of the array.
2 extend(iterable)
Appends items from iterable to the end of the array.
3 insert(i, x)
Inserts a new item with value x before position i.
4 pop([i])
Removes and returns the item with index i. If it is not
specified, remove and return the last item.
5 remove(x)
Removes the first occurrence of x from the array.
1 buffer_info()
Returns a tuple (address, length) giving the current memory
address and the length in elements of the buffer used to hold
the array’s contents.
2 count(x)
Returns the number of occurrences of x in the array.
1 reverse()
Reverses the order of the items in the array.
2 byteswap()
"Byteswaps" all items of the array, useful for reading data
from a file written on a machine with a different byte order.
Conversion Methods
These methods are used to convert arrays to and from bytes, files, lists,
and Unicode strings.
1 frombytes(buffer)
Appends items from the bytes-like object, interpreting its
content as an array of machine values.
2 tobytes()
Converts the array to a bytes representation.
3 fromfile(f, n)
Reads n items from the file object f and appends them to the
array.
4 tofile(f)
Writes all items to the file object f.
5 fromlist(list)
Appends items from the list to the array.
6 tolist()
Converts the array to a list with the same items.
7 fromunicode(s)
Extends the array with data from the given Unicode string. The
array must have type code 'u'.
8 tounicode()
Converts the array to a Unicode string. The array must have
type code 'u'.
Array Exercises
Example 1
Python program to find the largest number in an array −
Open Compiler
import array as arr
a = arr.array('i', [10,5,15,4,6,20,9])
print (a)
largest = a[0]
for i in range(1, len(a)):
if a[i]>largest:
largest=a[i]
print ("Largest number:", largest)
Example 2
Python program to store all even numbers from an array in another
array −
Open Compiler
import array as arr
a = arr.array('i', [10,5,15,4,6,20,9])
print (a)
b = arr.array('i')
for i in range(len(a)):
if a[i]%2 == 0:
b.append(a[i])
print ("Even numbers:", b)
Example 3
Python program to find the average of all numbers in a Python array −
Open Compiler
import array as arr
a = arr.array('i', [10,5,15,4,6,20,9])
print (a)
s=0
for i in range(len(a)):
s+=a[i]
avg = s/len(a)
print ("Average:", avg)
# Using sum() function
avg = sum(a)/len(a)
print ("Average:", avg)
Exercise Programs
Python program find difference between each number in the
array and the average of all numbers
Python program to convert a string in an array
Python program to split an array in two and store even
numbers in one array and odd numbers in the other.
Python program to perform insertion sort on an array.
Python program to store the Unicode value of each character
in the given array.
File Handling
File Handling in Python
File handling in Python involves interacting with files on your computer
to read data from them or write data to them. Python provides several
built-in functions and methods for creating, opening, reading, writing,
and closing files. This tutorial covers the basics of file handling in
Python with examples.
Where, filename is the name of the file to open and mode is the mode
in which the file is opened (e.g., 'r' for reading, 'w' for writing, 'a' for
appending).
2 rb
Opens a file for reading only in binary format. The file pointer
is placed at the beginning of the file. This is the default mode.
3 r+
Opens a file for both reading and writing. The file pointer
placed at the beginning of the file.
4 rb+
Opens a file for both reading and writing in binary format. The
file pointer placed at the beginning of the file.
5 w
Open a file for writing only. Overwrites the file if the file exists.
If the file does not exist, create a new file for writing.
6 b
Opens the file in binary mode
7 t
Opens the file in text mode (default)
8 +
open file for updating (reading and writing)
9 wb
Opens a file for writing only in binary format. Overwrites the
file if the file exists. If the file does not exist, create a new file
for writing.
10 w+
Opens a file for both writing and reading. Overwrites the
existing file if the file exists. If the file does not exist, create a
new file for reading and writing.
11 wb+
Opens a file for both writing and reading in binary format.
Overwrites the existing file if the file exists. If the file does not
exist, create a new file for reading and writing.
12 a
Open a file for appending. The file pointer is at the end of the
file if the file exists. That is, the file is in the append mode. If
the file does not exist, it creates a new file for writing.
13 ab
Opens a file for appending in binary format. The file pointer is
at the end of the file if the file exists. That is, the file is in the
append mode. If the file does not exist, it creates a new file for
writing.
14 a+
Opens a file for both appending and reading. The file pointer is
at the end of the file if the file exists. The file opens in the
append mode. If the file does not exist, it creates a new file for
reading and writing.
15 ab+
Opens a file for both appending and reading in binary format.
The file pointer is at the end of the file if the file exists. The file
opens in the append mode. If the file does not exist, it creates
a new file for reading and writing.
16 x
open for exclusive creation, failing if the file already exists
Once a file is opened and you have one file object, you can get various
information related to that file.
Example 1
In the following example, we are opening a file in different modes −
# Opening a file in read mode
file = open("example.txt", "r")
# Opening a file in write mode
file = open("example.txt", "w")
# Opening a file in append mode
file = open("example.txt", "a")
# Opening a file in binary read mode
file = open("example.txt", "rb")
Example 2
In here, we are opening a file named "foo.txt" in binary write mode
("wb"), printing its name, whether it's closed, and its opening mode,
and then closing the file −
Open Compiler
# Open a file
fo = open("foo.txt", "wb")
print ("Name of the file: ", fo.name)
print ("Closed or not: ", fo.closed)
print ("Opening mode: ", fo.mode)
fo.close()
Example
In this example, we open the file for writing, write data to the file, and
then close the file using the close() method −
Open Compiler
file = open("example.txt", "w")
file.write("This is an example.")
file.close()
print ("File closed successfully!!")
Example
In this example, the file is automatically closed at the end of the with
block, so there is no need to call close() method explicitly −
Open Compiler
with open("example.txt", "w") as file:
file.write("This is an example using the with statement.")
print ("File closed successfully!!")
Write to File
Writing to a file involves opening the file in a specific mode, writing
data to it, and then closing the file to ensure that all data is saved and
resources are released. Python provides a built-in function open() to
handle file operations and various methods for writing data.
Example
In the following example, we are opening the file "example.txt" in write
mode. We then use the write() method to write a string to the file −
Open Compiler
# Open a file in write mode
with open("example.txt", "w") as file:
file.write("Hello, World!\n")
file.write("This is a new line.\n")
print ("File opened successfully!!")
Example
In this example, we are creating a list of strings, lines, with each string
ending in a newline character. We then open a file "example.txt" in
write mode and use the writelines() method to write all the strings in
the list to the file in one operation −
Open Compiler
# List of lines to write to the file
lines = ["First line\n", "Second line\n", "Third line\n"]
# Open a file in write mode
with open("example.txt", "w") as file:
file.writelines(lines)
print ("File opened successfully!!")
Example
In the example below, we create a "foo.txt" file and write given content
in that file and finally close that file −
# Open a file
fo = open("foo.txt", "w")
fo.write( "Python is a great language.\nYeah its great!!\n")
# Close opened file
fo.close()
If you open this file with any text editor application such as Notepad, it
will have the following content −
Python is a great language.
Yeah it's great!!
Example
The following example demonstrates how to open a file in append
mode and add new text to it −
# Open a file in append mode
fo = open("foo.txt", "a")
text = "TutorialsPoint has a fabulous Python tutorial"
fo.write(text)
# Close opened file
fo.close()
If you open this file with any text editor application such as Notepad, it
will have the following content −
Python is a great language.
Yeah it's great!!
TutorialsPoint has a fabulous Python tutorial
Where,
offset − This is the position of the read/write pointer within
the file.
whence − This is optional and defaults to 0 which means
absolute file positioning, other values are 1 which means seek
relative to the current position and 2 means seek relative to
the file's end.
Example
The following program demonstrates how to open a file in read-write
mode ('w+'), write some data, seek a specific position, and then
overwrite part of the file's content −
# Open a file in read-write mode
fo = open("foo.txt", "w+")
# Write initial data to the file
fo.write("This is a rat race")
# Move the read/write pointer to the 10th byte
fo.seek(10, 0)
# Read 3 bytes from the current position
data = fo.read(3)
# Move the read/write pointer back to the 10th byte
fo.seek(10, 0)
# Overwrite the existing content with new text
fo.write('cat')
# Close the file
fo.close()
If we open the file in read mode (or seek to the starting position while
in 'w+' mode) and read the contents, it will show the following −
This is a cat race
Read Files
Reading from a file involves opening the file, reading its contents, and
then closing the file to free up system resources. Python provides
several methods to read from a file, each suited for different use cases.
Syntax
Following is the basic syntax of the read() method in Python −
file_object.read(size)
Where,
file_object is the file object returned by the open() function.
size is the number of bytes to read from the file. This
parameter is optional. If omitted or set to a negative value,
the method reads until the end of the file.
Example
In the following example, we are opening the file "example.txt" in read
mode. We then use the read() method to read the entire content of the
file −
# Open the file in read mode
file = open('example.txt', 'r')
# Read the entire content of the file
content = file.read()
# Print the content
print(content)
# Close the file
file.close()
Syntax
Following is the basic syntax of the readline() method in Python −
file_object.readline(size)
Where,
file_object is the file object returned by the open() function.
size is an optional parameter specifying the maximum
number of bytes to read from the line. If omitted or set to a
negative value, the method reads until the end of the line.
Example
In the example below, we are opening the file "example.txt" in read
mode. We then use the readline() method to read the first line of the
file −
# Open the file in read mode
file = open('example.txt', 'r')
# Read the first line of the file
line = file.readline()
# Print the line
print(line)
# Close the file
file.close()
Syntax
Following is the basic syntax of the readlines() method in Python −
file_object.readlines(hint)
Where,
file_object is the file object returned by the open() function.
hint is an optional parameter that specifies the number of
bytes to read. If specified, it reads lines up to the specified
bytes, not necessarily reading the entire file.
Example
In this example, we are opening the file "example.txt" in read mode.
We then use the readlines() method to read all the lines from the file
and return them as a list of strings −
# Open the file in read mode
file = open('example.txt', 'r')
# Read all lines from the file
lines = file.readlines()
# Print the lines
for line in lines:
print(line, end='')
# Close the file
file.close()
Example
Following is a simple example of using the with statement to open,
read, and print the contents of a file −
# Using the with statement to open a file
with open('example.txt', 'r') as file:
content = file.read()
print(content)
Example
To read a binary file, we need to open it in 'rb' mode. The returned
value of the read() method is then decoded before printing −
# Open the file in binary read mode
with open('test.bin', 'rb') as f:
data = f.read()
print(data.decode(encoding='utf-8'))
Syntax
Following is the syntax for seek() method −
fileObject.seek(offset[, whence])
Parameters
offset − This is the position of the read/write pointer within
the file.
whence − This is optional and defaults to 0 which means
absolute file positioning, other values are 1 which means seek
relative to the current position and 2 means seek relative to
the file's end.
Example
The following program opens a file in 'r+' mode (read-write mode),
seeks a certain position in the file, and reads data from that position −
# Open the file in read-write mode
with open("foo.txt", "r+") as fo:
# Move the read/write pointer to the 10th byte position
fo.seek(10, 0)
Example
In this example, we open the file in 'r+' mode and write data to the file.
The seek(0) method repositions the pointer to the beginning of the file
−
# Open the file in read-write mode
with open("foo.txt", "r+") as fo:
# Write data to the file
fo.write("This is a rat race")
# Rewind the pointer to the beginning of the file
fo.seek(0)
# Read data from the file
data = fo.read()
print(data)
Example
The following example demonstrates how to use the seek() method to
perform simultaneous read/write operations on a file. The file is opened
in w+ mode (read-write mode), some data is added, and then the file is
read and modified at a specific position −
Open Compiler
# Open a file in read-write mode
fo = open("foo.txt", "w+")
# Write initial data to the file
fo.write("This is a rat race")
# Seek to a specific position in the file
fo.seek(10, 0)
# Read a few bytes from the current position
data = fo.read(3)
print("Data read from position 10:", data)
# Seek back to the same position
fo.seek(10, 0)
# Overwrite the earlier contents with new text
fo.write("cat")
# Rewind to the beginning of the file
fo.seek(0, 0)
# Read the entire file content
data = fo.read()
print("Updated file content:", data)
# Close the file
fo.close()
Syntax
Following is the basic syntax of the rename() function in Python −
os.rename(current_file_name, new_file_name)
Parameters
Following are the parameters accepted by this function −
current_file_name − It is the current name of the file you
want to rename.
new_file_name − It is the new name you want to assign to
the file.
Example
Following is an example to rename an existing file "oldfile.txt" to
"newfile.txt" using the rename() function −
import os
# Current file name
current_name = "oldfile.txt"
# New file name
new_name = "newfile.txt"
# Rename the file
os.rename(current_name, new_name)
print(f"File '{current_name}' renamed to '{new_name}' successfully.")
Syntax
Following is the basic syntax of the remove() function in Python −
os.remove(file_name)
Parameters
This function accepts the name of the file as a parameter which needs
to be deleted.
Example
Following is an example to delete an existing file "file_to_delete.txt"
using the remove() function −
import os
# File to be deleted
file_to_delete = "file_to_delete.txt"
# Delete the file
os.remove(file_to_delete)
print(f"File '{file_to_delete}' deleted successfully.")
Directories
Directories in Python
In Python, directories, commonly known as folders in operating
systems, are locations on the filesystem used to store files and other
directories. They serve as a way to group and manage files
hierarchically.
Python provides several modules, primarily os and os.path, along with
shutil, that allows you to perform various operations on directories.
These operations include creating new directories, navigating through
existing directories, listing directory contents, changing the current
working directory, and removing directories.
Example
In this example, we check whether the given directory path exists using
the os.path.exists() function −
import os
directory_path = "D:\\Test\\MyFolder\\"
if os.path.exists(directory_path):
print(f"The directory '{directory_path}' exists.")
else:
print(f"The directory '{directory_path}' does not exist.")
Creating a Directory
You create a new directory in Python using the os.makedirs() function.
This function creates intermediate directories if they do not exist.
The os.makedirs() function accepts a "path" you want to create as an
argument. It optionally accepts a "mode" argument that specifies the
permissions o set for the newly created directories. It is an integer,
represented in octal format (e.g., 0o755). If not specified, the default
permissions are used based on your system's umask.
Example
In the following example, we are creating a new directory using the
os.makedirs() function −
Open Compiler
import os
new_directory = "new_dir.txt"
try:
os.makedirs(new_directory)
print(f"Directory '{new_directory}' created successfully.")
except OSError as e:
print(f"Error: Failed to create directory '{new_directory}'. {e}")
Example
Following is an example to create a directory test in the current
directory −
Open Compiler
import os
# Create a directory "test"
os.mkdir("test")
print ("Directory created successfully")
Syntax
Following is the basic syntax of the getcwd() function in Python −
os.getcwd()
Example
Following is an example to display the current working directory using
the getcwd() function −
Open Compiler
import os
current_directory = os.getcwd()
print(f"Current working directory: {current_directory}")
Example
In the example below, we are listing the contents of the specified
directory path using the listdir() function −
import os
directory_path = r"D:\MyFolder\Pictures"
try:
contents = os.listdir(directory_path)
print(f"Contents of '{directory_path}':")
for item in contents:
print(item)
except OSError as e:
print(f"Error: Failed to list contents of directory '{directory_path}'.
{e}")
Syntax
Following is the syntax of the chdir() method in Python −
os.chdir("newdir")
Example
Following is an example to change the current directory to Desktop
using the chdir() method −
import os
new_directory = r"D:\MyFolder\Pictures"
try:
os.chdir(new_directory)
print(f"Current working directory changed to '{new_directory}'.")
except OSError as e:
print(f"Error: Failed to change working directory to '{new_directory}'.
{e}")
Removing a Directory
You can remove an empty directory in Python using the os.rmdir()
method. If the directory contains files or other directories, you can use
shutil.rmtree() method to delete it recursively.
Syntax
Following is the basic syntax to delete a directory in Python −
os.rmdir(directory_path)
# or
shutil.rmtree(directory_path)
Example
In the following example, we remove an empty directory using the
os.rmdir() method −
import os
directory_path = r"D:\MyFolder\new_dir"
try:
os.rmdir(directory_path)
print(f"Directory '{directory_path}' successfully removed.")
except OSError as e:
print(f"Error: Failed to remove directory '{directory_path}'. {e}")
File Methods
A file object is created using the open() function. The file class defines
the following methods with which different file IO operations can be
done. The methods can be used with any file-like object such as byte
stream or network stream.
1 file.close()
Close the file. A closed file cannot be read or written any more.
2 file.flush()
Flush the internal buffer, like the studio's fflush. This may be a
no-op on some file-like objects.
3 file.fileno()
Returns the integer file descriptor that is used by the
underlying implementation to request I/O operations from the
operating system.
4 file.isatty()
Returns True if the file is connected to a tty(-like) device, else
False.
5 file.next()
Returns the next line from the file each time it is being called.
6 file.read([size])
Reads at most size bytes from the file (less if the read hits EOF
before obtaining size bytes).
7 file.readline([size])
Reads one entire line from the file. A trailing newline character
is kept in the string.
8 file.readlines([sizehint])
Reads until EOF using readline() and returns a list containing
the lines. If the optional sizehint argument is present, instead
of reading up to EOF, whole lines totalling approximately
sizehint bytes (possibly after rounding up to an internal buffer
size) are read.
9 file.seek(offset[, whence])
Sets the file's current position
10 file.tell()
Returns the file's current position
11 file.truncate([size])
Truncates the file's size. If the optional size argument is
present, the file is truncated to (at most) that size.
12 file.write(str)
Writes a string to the file. There is no return value.
13 file.writelines(sequence)
Writes a sequence of strings to the file. The sequence can be
any iterable object producing strings, typically a list of strings.
Python OS File/Directory
Methods
The OS module of Python provides a wide range of useful methods to
manage files and directories. These are the built-in methods that help
in interacting with operating systems. Most of the useful methods are
listed here −
1 os.access(path, mode)
Use the real uid/gid to test for access to the path.
2 os.chdir(path)
Change the current working directory to path
3 os.chflags(path, flags)
Set the flags of path to the numeric flags.
4 os.chmod(path, mode)
Change the mode of path to the numeric mode.
6 os.chroot(path)
Change the root directory of the current process to path.
7 os.close(fd)
Close file descriptor fd.
8 os.closerange(fd_low, fd_high)
Close all file descriptors from fd_low (inclusive) to fd_high
(exclusive), ignoring errors.
9 os.dup(fd)
Return a duplicate of file descriptor fd.
10 os.dup2(fd, fd2)
Duplicate file descriptor fd to fd2, closing the latter first if
necessary.
11 os.fchdir(fd)
Change the current working directory to the directory
represented by the file descriptor fd.
12 os.fchmod(fd, mode)
Change the mode of the file given by fd to the numeric mode.
14 os.fdatasync(fd)
Force write of file with filedescriptor fd to disk.
16 os.fpathconf(fd, name)
Return system configuration information relevant to an open
file. name specifies the configuration value to retrieve.
17 os.fstat(fd)
Return status for file descriptor fd, like stat().
18 os.statvfs(fd)
Return information about the filesystem containing the file
associated with file descriptor fd, like statvfs().
19 os.fsync(fd)
Force write of file with filedescriptor fd to disk.
20 os.ftruncate(fd, length)
Truncate the file corresponding to file descriptor fd, so that it is
at most length bytes in size.
21 os.getcwd()
Return a string representing the current working directory.
22 os.getcwdu()
Return a Unicode object representing the current working
directory.
23 os.isatty(fd)
Return True if the file descriptor fd is open and connected to a
tty(-like) device, else False.
24 os.chflags(path, flags)
Set the flags of path to the numeric flags, like chflags(), but do
not follow symbolic links.
25 os.lchmod(path, mode)
Change the mode of path to the numeric mode.
27 os.link(src, dst)
Create a hard link pointing to src named dst.
28 os.listdir(path)
Return a list containing the names of the entries in the
directory given by path.
30 os.lstat(path)
Like stat(), but do not follow symbolic links.
31 os.major(device)
Extract the device major number from a raw device number.
32 os.makedev(major, minor)
Compose a raw device number from the major and minor
device numbers.
33 os.makedirs(path[, mode])
Recursive directory creation function.
34 os.minor(device)
Extract the device minor number from a raw device number.
35 os.mkdir(path[, mode])
Create a directory named path with numeric mode mode.
36 os.mkfifo(path[, mode])
Create a FIFO (a named pipe) named path with numeric mode
mode. The default mode is 0666 (octal).
39 os.openpty()
Open a new pseudo-terminal pair. Return a pair of file
descriptors (master, slave) for the pty and the tty,
respectively.
40 os.pathconf(path, name)
Return system configuration information relevant to a named
file.
41 os.pipe()
Create a pipe. Return a pair of file descriptors (r, w) usable for
reading and writing, respectively.
43 os.read(fd, n)
Read at most n bytes from file descriptor fd. Return a string
containing the bytes read. If the end of the file referred to by
fd has been reached, an empty string is returned.
44 os.readlink(path)
Return a string representing the path to which the symbolic
link points.
45 os.remove(path)
Remove the file path.
46 os.removedirs(path)
Remove directories recursively.
47 os.rename(src, dst)
Rename the file or directory src to dst.
48 os.renames(old, new)
Recursive directory or file renaming function.
49 os.rmdir(path)
Remove the directory path
50 os.stat(path)
Perform a stat system call on the given path.
51 os.stat_float_times([newvalue])
Determine whether stat_result represents time stamps as float
objects.
52 os.statvfs(path)
Perform a statvfs system call on the given path.
53 os.symlink(src, dst)
Create a symbolic link pointing to src named dst.
54 os.tcgetpgrp(fd)
Return the process group associated with the terminal given
by fd (an open file descriptor as returned by open()).
55 os.tcsetpgrp(fd, pg)
Set the process group associated with the terminal given by fd
(an open file descriptor as returned by open()) to pg.
56 os.tempnam([dir[, prefix]])
Return a unique path name that is reasonable for creating a
temporary file.
57 os.tmpfile()
Return a new file object opened in update mode (w+b).
58 os.tmpnam()
Return a unique path name that is reasonable for creating a
temporary file.
59 os.ttyname(fd)
Return a string which specifies the terminal device associated
with file descriptor fd. If fd is not associated with a terminal
device, an exception is raised.
60 os.unlink(path)
Remove the file path.
61 os.utime(path, times)
Set the access and modified times of the file specified by path.
63 os.write(fd, str)
Write the string str to file descriptor fd. Return the number of
bytes actually written.
The os.path is another Python module, which also provides a big range
of useful methods to manipulate files and directories. Most of the useful
methods are listed here −
1 os.path.abspath(path)
Returns a normalised absolutized version of the pathname
path.
2 os.path.basename(path)
Returns the base name of pathname path.
3 os.path.commonprefix(list)
Returns the longest path prefix (taken character-by-character)
that is a prefix of all paths in the list.
4 os.path.dirname(path)
Returns the directory name of pathname path.
5 os.path.exists(path)
Returns True if path refers to an existing path. Returns False
for broken symbolic links.
6 os.path.lexists(path)
Returns True if path refers to an existing path. Returns True for
broken symbolic links.
7 os.path.expanduser(path)
On Unix and Windows, it returns the argument with an initial
component of ~ or ~user replaced by that user's home
directory.
8 os.path.expandvars(path)
Returns the argument with environment variables expanded.
9 os.path.getatime(path)
Returns the time of last access to the path.
10 os.path.getmtime(path)
Returns the time of last modification of path.
11 os.path.getctime(path)
Returns the system's ctime, which on some systems (like Unix)
is the time of the last change, and, on others (like Windows), is
the creation time for path.
12 os.path.getsize(path)
Returns the size, in bytes, of the path.
13 os.path.isabs(path)
Returns True if path is an absolute pathname.
14 os.path.isfile(path)
Returns True if path is an existing regular file.
15 os.path.isdir(path)
Returns True if path is an existing directory.
16 os.path.islink(path)
Returns True if path refers to a directory entry that is a
symbolic link.
17 os.path.ismount(path)
Returns True if pathname path is a mount point: a point in a
file system where a different file system has been mounted.
19 os.path.normcase(path)
Normalises the case of a pathname.
20 os.path.normpath(path)
Normalises a pathname.
21 os.path.realpath(path)
Returns the canonical path of the specified filename,
eliminating any symbolic links encountered in the path
22 os.path.relpath(path[, start])
Returns a relative file path to path either from the current
directory or from an optional start point.
23 os.path.samefile(path1, path2)
Returns True if both pathname arguments refer to the same
file or directory
25 os.path.samestat(stat1, stat2)
Returns True if the stat tuples stat1 and stat2 refer to the
same file.
26 os.path.split(path)
Splits the pathname path into a pair, (head, tail) where tail is
the last pathname component and head is everything leading
up to that.
27 os.path.splitdrive(path)
Splits the pathname path into a pair (drive, tail) where drive is
either a drive specification or the empty string.
28 os.path.splitext(path)
Splits the pathname path into a pair (root, ext) such that root
+ ext == path, and ext is empty or begins with a period and
contains at most one period.
OOP Concepts
OOP is an abbreviation that stands for Object-oriented
programming paradigm. It is defined as a programming model that
uses the concept of objects which refers to real-world entities with
state and behaviour. This chapter helps you become an expert in using
object-oriented programming support in Python language.
Python is a programming language that supports object-oriented
programming. This makes it simple to create and use classes and
objects. If you do not have any prior experience with object-oriented
programming, you are at the right place. Let's start by discussing a
small introduction of Object-Oriented Programming (OOP) to help you.
Attributes
Name, class, subjects, marks, etc., of student
Name, designation, department, salary, etc., of employee
Invoice number, customer, product code and name, price and
quantity, etc., in an invoice
Registration number, owner, company, brand, horsepower,
speed, etc., of car
Behaviour
Processing attributes associated with an object.
Compute percentage of student's marks
Calculate incentives payable to employee
Apply GST to invoice value
Measure speed of car
Example
The below example illustrates how to create a class and its object in
Python.
Open Compiler
# defining class
class Smartphone:
# constructor
def __init__(self, device, brand):
self.device = device
self.brand = brand
# method of the class
def description(self):
return f"{self.device} of {self.brand} supports Android 14"
# creating object of the class
phoneObj = Smartphone("Smartphone", "Samsung")
print(phoneObj.description())
Encapsulation
Data members of class are available for processing to functions defined
within the class only. Functions of class on the other hand are
accessible from outside class context. So object data is hidden from an
environment that is external to the class. Class function (also called
method) encapsulates object data so that unwarranted access to it is
prevented.
Example
In this example, we are using the concept of encapsulation to set the
price of a desktop.
Open Compiler
class Desktop:
def __init__(self):
self.__max_price = 25000
def sell(self):
return f"Selling Price: {self.__max_price}"
def set_max_price(self, price):
if price > self.__max_price:
self.__max_price = price
# Object
desktopObj = Desktop()
print(desktopObj.sell())
# modifying the price directly
desktopObj.__max_price = 35000
print(desktopObj.sell())
# modifying the price using setter function
desktopObj.set_max_price(35000)
print(desktopObj.sell())
Inheritance
A software modelling approach of OOP enables extending the capability
of an existing class to build a new class instead of building from
scratch. In OOP terminology, the existing class is called base or
parent class , while the new class is called child or subclass .
Child class inherits data definitions and methods from the parent class.
This facilitates reuse of features already available. Child class can add a
few more definitions or redefine a base class function.
Syntax
Derived classes are declared much like their parent class; however, a
list of base classes to inherit from is given after the class name −
class SubClassName (ParentClass1[, ParentClass2, ...]):
'Optional class documentation string'
class_suite
Example
The following example demonstrates the concept of Inheritance in
Python −
Open Compiler
#!/usr/bin/python
# define parent class
class Parent:
parentAttr = 100
def __init__(self):
print ("Calling parent constructor")
def parentMethod(self):
print ("Calling parent method")
def setAttr(self, attr):
Parent.parentAttr = attr
def getAttr(self):
print ("Parent attribute :", Parent.parentAttr)
# define child class
class Child(Parent):
def __init__(self):
print ("Calling child constructor")
def childMethod(self):
print ("Calling child method")
# instance of child
c = Child()
# child calls its method
c.childMethod()
# calls parent's method
c.parentMethod()
# again call parent's method
c.setAttr(200)
# again call parent's method
c.getAttr()
Similar way, you can drive a class from multiple parent classes as
follows −
class A: # define your class A
.....
class B: # define your class B
.....
class C(A, B): # subclass of A and B
.....
Polymorphism
Polymorphism is a Greek word meaning having multiple forms. In OOP,
polymorphism occurs when each sub class provides its own
implementation of an abstract method in base class.
You can always override your parent class methods. One reason for
overriding parent's methods is because you may want special or
different functionality in your subclass.
Example
In this example, we are overriding the parent's method.
Open Compiler
# define parent class
class Parent:
def myMethod(self):
print ("Calling parent method")
# define child class
class Child(Parent):
def myMethod(self):
print ("Calling child method")
# instance of child
c = Child()
# child calls overridden method
c.myMethod()
When the above code is executed, it produces the following result −
Calling child method
2 __del__( self )
Destructor, deletes an object
Sample Call : del obj
3 __repr__( self )
Evaluable string representation
Sample Call : repr(obj)
4 __str__( self )
Printable string representation
Sample Call : str(obj)
5 __cmp__ ( self, x )
Object comparison
Sample Call : cmp(obj, x)
Example
Open Compiler
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)
Example
Following is the example of a simple Python class −
class Employee:
'Common base class for all employees'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print "Total Employee %d" % Employee.empCount
def displayEmployee(self):
print "Name : ", self.name, ", Salary: ", self.salary
What is an Object?
An object is referred to as an instance of a given Python class. Each
object has its own attributes and methods, which are defined by its
class.
When a class is created, it only describes the structure of objects. The
memory is allocated when an object is instantiated from a class.
In the above figure, Vehicle is the class name and Car , Bus and
SUV are its objects.
You can add, remove, or modify attributes of classes and objects at any
time −
# Add an 'age' attribute
emp1.age = 7
# Modify 'age' attribute
emp1.age = 8
# Delete 'age' attribute
del emp1.age
1 __dict__
Dictionary containing the class's namespace.
2 __doc__
Class documentation string or none, if undefined.
3 __name__
Class name
4 __module__
Module name in which the class is defined. This attribute is
"__main__" in interactive mode.
5 __bases__
A possibly empty tuple containing the base classes, in the order
of their occurrence in the base class list.
Example
For the above Employee class, let us try to access its attributes −
Open Compiler
class Employee:
'Common base class for all employees'
empCount = 0
def __init__(self, name, salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print ("Total Employee %d" % Employee.empCount)
def displayEmployee(self):
print ("Name : ", self.name, ", Salary: ", self.salary)
print ("Employee.__doc__:", Employee.__doc__)
print ("Employee.__name__:", Employee.__name__)
print ("Employee.__module__:", Employee.__module__)
print ("Employee.__bases__:", Employee.__bases__)
print ("Employee.__dict__:", Employee.__dict__)
When you execute this code, it will display the corresponding classes of
Python data types −
<class 'int'>
<class 'float'>
<class 'str'>
<class 'dict'>
<class 'function'>
You normally will not notice when the garbage collector destroys an
unused instance and reclaims its space. But a class can implement the
special method __del__() , called a destructor, that is invoked when the
instance is about to be destroyed. This method might be used to clean
up any non memory resources used by an instance.
Example
The __del__() destructor prints the class name of an instance that is
about to be destroyed as shown in the below code block −
Open Compiler
class Point:
def __init__( self, x=0, y=0):
self.x = x
self.y = y
def __del__(self):
class_name = self.__class__.__name__
print (class_name, "destroyed")
pt1 = Point()
pt2 = pt1
pt3 = pt1
# prints the ids of the objects
print (id(pt1), id(pt2), id(pt3))
del pt1
del pt2
del pt3
Example
Open Compiler
class JustCounter:
__secretCount = 0
def count(self):
self.__secretCount += 1
print self.__secretCount
counter = JustCounter()
counter.count()
counter.count()
print counter.__secretCount
Class Attributes
The properties or variables defined inside a class are called as
Attributes. An attribute provides information about the type of data a
class contains. There are two types of attributes in Python namely
instance attribute and class attribute.
The instance attribute is defined within the constructor of a Python
class and is unique to each instance of the class. And, a class attribute
is declared and initialised outside the constructor of the class.
Example
The below example demonstrates how to access the attributes of a
Python class.
Open Compiler
class Employee:
name = "Bhavesh Aggarwal"
age = "30"
# instance of the class
emp = Employee()
# accessing class attributes
print("Name of the Employee:", emp.name)
print("Age of the Employee:", emp.age)
Output
Name of the Employee: Bhavesh Aggarwal
Age of the Employee: 30
Example
In the below example, we are initialising a class variable called
empCount in Employee class. For each object declared, the __init__()
method is automatically called. This method initialises the instance
variables as well as increments the empCount by 1.
Open Compiler
class Employee:
# class attribute
empCount = 0
def __init__(self, name, age):
self.__name = name
self.__age = age
# modifying class attribute
Employee.empCount += 1
print ("Name:", self.__name, ", Age: ", self.__age)
# accessing class attribute
print ("Employee Count:", Employee.empCount)
e1 = Employee("Bhavana", 24)
print()
e2 = Employee("Rajesh", 26)
Output
We have declared two objects. Every time, the empCount increments
by 1.
Name: Bhavana , Age: 24
Employee Count: 1
Name: Rajesh , Age: 26
Employee Count: 2
Example
For the Employee class, we are trying to access all the built-in class
attributes −
Open Compiler
class Employee:
def __init__(self, name="Bhavana", age=24):
self.name = name
self.age = age
def displayEmployee(self):
print ("Name : ", self.name, ", age: ", self.age)
print ("Employee.__doc__:", Employee.__doc__)
print ("Employee.__name__:", Employee.__name__)
print ("Employee.__module__:", Employee.__module__)
print ("Employee.__bases__:", Employee.__bases__)
print ("Employee.__dict__:", Employee.__dict__ )
Output
It will produce the following output −
Employee.__doc__: None
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: (<class 'object'>,)
Employee.__dict__: {'__module__': '__main__', '__init__': <function
Employee.__init__ at 0x0000022F866B8B80>, 'displayEmployee':
<function Employee.displayEmployee at 0x0000022F866B9760>,
'__dict__': <attribute '__dict__' of 'Employee' objects>, '__weakref__':
<attribute '__weakref__' of 'Employee' objects>, '__doc__': None}
Instance Attributes
As stated earlier, an instance attribute in Python is a variable that is
specific to an individual object of a class. It is defined inside the
__init__() method.
The first parameter of this method is self and using this parameter
the instance attributes are defined.
Example
In the following code, we are illustrating the working of instance
attributes.
Open Compiler
class Student:
def __init__(self, name, grade):
self.__name = name
self.__grade = grade
print ("Name:", self.__name, ", Grade:", self.__grade)
# Creating instances
student1 = Student("Ram", "B")
student2 = Student("Shyam", "C")
Output
On running the above code, it will produce the following output −
Name: Ram , Grade: B
Name: Shyam , Grade: C
Syntax
classmethod(instance_method)
Example
In the Employee class, define a ShowCount() instance method with the
"self" argument (reference to calling object). It prints the value of
empCount. Next, transform the method to class method counter() that
can be accessed through the class reference.
Open Compiler
class Employee:
empCount = 0
def __init__(self, name, age):
self.__name = name
self.__age = age
Employee.empCount += 1
def showcount(self):
print (self.empCount)
counter = classmethod(showcount)
e1 = Employee("Bhavana", 24)
e2 = Employee("Rajesh", 26)
e3 = Employee("John", 27)
e1.showcount()
Employee.counter()
Output
Call showcount() with object and call count() with class, both show the
value of employee count.
3
3
Syntax
@classmethod
def method_name():
# your code
Example
The class method acts as an alternate constructor. Define a new
employee() class method with arguments required to construct a new
object. It returns the constructed object, something that the __init__()
method does.
Open Compiler
class Employee:
empCount = 0
def __init__(self, name, age):
self.name = name
self.age = age
Employee.empCount += 1
@classmethod
def showcount(cls):
print (cls.empCount)
@classmethod
def new employee(cls, name, age):
return cls(name, age)
e1 = Employee("Bhavana", 24)
e2 = Employee("Rajesh", 26)
e3 = Employee("John", 27)
e4 = Employee.new employee("Anil", 21)
Employee.showcount()
There are four Employee objects now. If we run the above program, it
will show the count of Employee object −
4
Example
In this example, we are accessing a class attribute in class method.
Open Compiler
class Cloth:
# Class attribute
price = 4000
@classmethod
def showPrice(cls):
return cls.price
# Accessing class attribute
print(Cloth.showPrice())
Example
The following example shows how to add a class method dynamically
to a Python class.
Open Compiler
class Cloth:
pass
# class method
@classmethod
def brandName(cls):
print("Name of the brand is Raymond")
# adding dynamically
setattr(Cloth, "brand_name", brandName)
newObj = Cloth()
newObj.brand_name()
When we execute the above code, it will show the following output −
Name of the brand is Raymond
Example
In the below example, we are deleting the class method named
"brandName" using del operator.
Open Compiler
class Cloth:
# class method
@classmethod
def brandName(cls):
print("Name of the brand is Raymond")
# deleting dynamically
del Cloth.brandName
print("Method deleted")
Static Methods
Syntax
staticmethod(method)
Example
In the Employee class below, the showcount() method is converted into
a static method. This static method can now be called by its object or
reference of the class itself.
Open Compiler
class Employee:
empCount = 0
def __init__(self, name, age):
self.__name = name
self.__age = age
Employee.empCount += 1
# creating staticmethod
def showcount():
print (Employee.empCount)
return
counter = staticmethod(showcount)
e1 = Employee("Bhavana", 24)
e2 = Employee("Rajesh", 26)
e3 = Employee("John", 27)
e1.counter()
Employee.counter()
Syntax
@staticmethod
def method_name():
# your code
Example
In the following example, we are creating a static method using the
@staticmethod decorator.
Open Compiler
class Student:
stdCount = 0
def __init__(self, name, age):
self.__name = name
self.__age = age
Student.stdCount += 1
# creating staticmethod
@staticmethod
def showcount():
print (Student.stdCount)
e1 = Student("Bhavana", 24)
e2 = Student("Rajesh", 26)
e3 = Student("John", 27)
print("Number of Students:")
Student.showcount()
Constructors
Python constructor is an instance method in a class that is
automatically called whenever a new object of the class is created. The
constructor's role is to assign value to instance variables as soon as the
object is declared.
Python uses a special method called __init__() to initialise the instance
variables for the object, as soon as it is declared.
Example
Let us define the constructor in the Employee class to initialise name
and age as instance variables. We can then access these attributes
through its object.
Open Compiler
class Employee:
'Common base class for all employees'
def __init__(self):
self.name = "Bhavana"
self.age = 24
e1 = Employee()
print ("Name: {}".format(e1.name))
print ("age: {}".format(e1.age))
For the above Employee class, each object we declare will have the
same value for its instance variables name and age. To declare objects
with varying attributes instead of the default, define arguments for the
__init__() method.
Parameterized Constructor
If a constructor is defined with multiple parameters along with self, it
is called a parameterized constructor.
Example
In this example, the __init__() constructor has two formal arguments.
We declare Employee objects with different values −
Open Compiler
class Employee:
'Common base class for all employees'
def __init__(self, name, age):
self.name = name
self.age = age
e1 = Employee("Bhavana", 24)
e2 = Employee("Bharat", 25)
print ("Name: {}".format(e1.name))
print ("age: {}".format(e1.age))
print ("Name: {}".format(e2.name))
print ("age: {}".format(e2.age))
You can also assign default values to the formal arguments in the
constructor so that the object can be instantiated with or without
passing parameters.
Open Compiler
class Employee:
'Common base class for all employees'
def __init__(self, name="Bhavana", age=24):
self.name = name
self.age = age
e1 = Employee()
e2 = Employee("Bharat", 25)
print ("Name: {}".format(e1.name))
print ("age: {}".format(e1.age))
print ("Name: {}".format(e2.name))
print ("age: {}".format(e2.age))
Example
In the following example a displayEmployee() method has been defined
as an instance method. It returns the name and age attributes of the
Employee object that calls the method.
Open Compiler
class Employee:
def __init__(self, name="Bhavana", age=24):
self.name = name
self.age = age
def displayEmployee(self):
print ("Name : ", self.name, ", age: ", self.age)
e1 = Employee()
e2 = Employee("Bharat", 25)
e1.displayEmployee()
e2.displayEmployee()
You can add, remove, or modify attributes of classes and objects at any
time −
# Add a 'salary' attribute
emp1.salary = 7000
# Modify 'name' attribute
emp1.name = 'xyz'
# Delete 'salary' attribute
del emp1.salary
Instead of using the normal statements to access attributes, you can
use the following functions −
The getattr(obj, name[, default]) − to access the attribute
of the object.
The hasattr(obj,name) − to check if an attribute exists or
not.
The setattr(obj,name,value) − to set an attribute. If the
attribute does not exist, then it would be created.
The delattr(obj, name) − to delete an attribute.
# Returns true if 'salary' attribute exists
print (hasattr(e1, 'salary'))
# Returns value of 'name' attribute
print (getattr(e1, 'name'))
# Set attribute 'salary' at 8
setattr(e1, 'salary', 7000)
# Delete attribute 'age'
delattr(e1, 'age')
Example
The following example shows how to achieve functionality similar to
multiple constructors.
Open Compiler
class Student:
def __init__(self, *args):
if len(args) == 1:
self.name = args[0]
elif len(args) == 2:
self.name = args[0]
self.age = args[1]
elif len(args) == 3:
self.name = args[0]
self.age = args[1]
self.gender = args[2]
st1 = Student("Shrey")
print("Name:", st1.name)
st2 = Student("Ram", 25)
print(f"Name: {st2.name} and Age: {st2.age}")
st3 = Student("Shyam", 26, "M")
print(f"Name: {st3.name}, Age: {st3.age} and Gender: {st3.gender}")
When we run the above code, it will produce the following output −
Name: Shrey
Name: Ram and Age: 25
Name: Shyam, Age: 26 and Gender: M
Access Modifiers
The Python access modifiers are used to restrict access to class
members (i.e., variables and methods) from outside the class. There
are three types of access modifiers namely public, protected, and
private.
Public members − A class member is said to be public if it
can be accessed from anywhere in the program.
Protected members − They are accessible from within the
class as well as by classes derived from that class.
Private members − They can be accessed from within the
class only.
Example
Here, we have an Employee class with instance variables name and
age. An object of this class has these two attributes. They can be
directly accessed from outside the class, because they are public.
Open Compiler
class Employee:
'Common base class for all employees'
def __init__(self, name="Bhavana", age=24):
self.name = name
self.age = age
e1 = Employee()
e2 = Employee("Bharat", 25)
print ("Name: {}".format(e1.name))
print ("age: {}".format(e1.age))
print ("Name: {}".format(e2.name))
print ("age: {}".format(e2.age))
Another Example
Let us modify the Employee class. Add another instance of variable
salary. Make age private and salary as protected by prefixing double
and single underscores respectively.
Open Compiler
class Employee:
def __init__(self, name, age, salary):
self.name = name # public variable
self.__age = age # private variable
self._salary = salary # protected variable
def displayEmployee(self):
print ("Name : ", self.name, ", age: ", self.__age, ", salary: ",
self._salary)
e1=Employee("Bhavana", 24, 10000)
print (e1.name)
print (e1._salary)
print (e1.__age)
When you run this code, it will produce the following output −
Bhavana
10000
Traceback (most recent call last):
File "C:\Users\user\example.py", line 14, in <module>
print (e1.__age)
^^^^^^^^
AttributeError: 'Employee' object has no attribute '__age'
So, to access the value of the "__age" instance variable of the "e1"
object, change it to "e1._Employee__age".
Change the print() statement in the above program to −
print (e1._Employee__age)
Syntax
property(get=None, fset=None, fdel=None, doc=None)
Parameters
get − an instance method that retrieves the value of an
instance variable.
fset − an instance method that assigns value to an instance
variable.
fdel − an instance method that removes an instance variable
fdoc − Documentation string for the property.
The function uses getter and setter methods to return the property
object.
Example
Let us define getter methods get_name() and get_age(), and setters
set_name() and set_age() in the Employee class.
Open Compiler
class Employee:
def __init__(self, name, age):
self.__name = name
self.__age = age
def get_name(self):
return self.__name
def get_age(self):
return self.__age
def set_name(self, name):
self.__name = name
return
def set_age(self, age):
self.__age=age
e1=Employee("Bhavana", 24)
print ("Name:", e1.get_name(), "age:", e1.get_age())
e1.set_name("Archana")
e1.set_age(21)
print ("Name:", e1.get_name(), "age:", e1.get_age())
It will produce the following output −
Name: Bhavana age: 24
Name: Archana age: 21
The getter and setter methods can retrieve or assign value to instance
variables. The property() function uses them to add property objects as
class attributes.
The name property is defined as −
name = property(get_name, set_name, "name")
The advantage of the property object is that you can retrieve the value
of its associated instance variable, as well as assign value.
For example,
print (e1.name) displays value of e1.__name
e1.name = "Archana" assigns value to e1.__age
Example
The complete program with property objects and their use is given
below −
Open Compiler
class Employee:
def __init__(self, name, age):
self.__name = name
self.__age = age
def get_name(self):
return self.__name
def get_age(self):
return self.__age
def set_name(self, name):
self.__name = name
return
def set_age(self, age):
self.__age=age
return
name = property(get_name, set_name, "name")
age = property(get_age, set_age, "age")
e1=Employee("Bhavana", 24)
print ("Name:", e1.name, "age:", e1.age)
e1.name = "Archana"
e1.age = 23
print ("Name:", e1.name, "age:", e1.age)
Inheritance
What is Inheritance in Python?
Inheritance is one of the most important features of object-oriented
programming languages like Python. It is used to inherit the properties
and behaviours of one class to another. The class that inherits another
class is called a child class and the class that gets inherited is called a
base class or parent class.
If you have to design a new class whose most of the attributes are
already well defined in an existing class, then why redefine them?
Inheritance allows capabilities of existing classes to be reused and if
required extended to design a new class.
Inheritance comes into picture when a new class possesses 'IS A'
relationship with an existing class. For example, Car IS a vehicle, Bus IS
a vehicle, Bike IS also a vehicle. Here, vehicles are the parent class,
whereas cars, buses and bikes are the child classes.
Creating a Parent Class
The class whose attributes and methods are inherited is called the
parent class. It is defined just like other classes i.e. using the class
keyword.
Syntax
The syntax for creating a parent class is shown below −
class ParentClassName:
{class body}
Syntax
Following is the syntax of child class −
class SubClassName (ParentClass1[, ParentClass2, ...]):
{subclass body}
Types of Inheritance
In Python, inheritance can be divided in five different categories −
Single Inheritance
Multiple Inheritance
Multilevel Inheritance
Hierarchical Inheritance
Hybrid Inheritance
Example
The below example shows single inheritance concept in Python −
Open Compiler
# parent class
class Parent:
def parentMethod(self):
print ("Calling parent method")
# child class
class Child(Parent):
def childMethod(self):
print ("Calling child method")
# instance of child
c = Child()
# calling method of child class
c.childMethod()
# calling method of parent class
c.parentMethod()
Syntax
class parent1:
#statements
class parent2:
#statements
Example
Python's standard library has a built-in divmod() function that returns a
two-item tuple. First number is the division of two arguments, the
second is the mod value of the two operands.
This example tries to emulate the divmod() function. We define two
classes division and modulus, and then have a div_mod class that
inherits them.
class division:
def __init__(self, a,b):
self.n=a
self.d=b
def divide(self):
return self.and/self.d
class modulus:
def __init__(self, a,b):
self.n=a
self.d=b
def mod_divide(self):
return self.n%self.d
class div_mod(division,modulus):
def __init__(self, a,b):
self.n=a
self.d=b
def div_and_mod(self):
divval=division.divide(self)
modval=modulus.mod_divide(self)
return (divval, modval)
The child class has a new method div_and_mod() which internally calls
the divide() and mod_divide() methods from its inherited classes to
return the division and mod values.
x=div_mod(10,3)
print ("division:",x.divide())
print ("mod_division:",x.mod_divide())
print ("divmod:",x.div_and_mod())
Output
division: 3.3333333333333335
mod_division: 1
divmod: (3.3333333333333335, 1)
Example
In the following example, we are illustrating the working of multilevel
inheritance.
Open Compiler
# parent class
class Universe:
def universeMethod(self):
print ("I am in the Universe")
# child class
class Earth(Universe):
def earthMethod(self):
print ("I am on Earth")
# another child class
class India(Earth):
def indianMethod(self):
print ("I am in India")
# creating instance
person = India()
# method calls
person.universeMethod()
person.earthMethod()
person.indianMethod()
When we execute the above code, it will produce the following result −
I am in the Universe
I am on Earth
I am in India
Python - Hierarchical Inheritance
This type of inheritance contains multiple derived classes that are
inherited from a single base class. This is similar to the hierarchy within
an organisation.
Example
The following example illustrates hierarchical inheritance. Here, we
have defined two child classes of Manager class.
Open Compiler
# parent class
class Manager:
def managerMethod(self):
print ("I am the Manager")
# child class
class Employee1(Manager):
def employee1 Method(self):
print ("I am Employee one")
# second child class
class Employee2(Manager):
def employee Method(self):
print ("I am Employee two")
# creating instances
emp1 = Employee1()
emp2 = Employee2()
# method calls
emp1.managerMethod()
emp1.employee1 Method()
emp2.managerMethod()
emp2.employee w2 method()
On executing the above program, you will get the following output −
I am the Manager
I am Employee one
I am the Manager
I am Employee two
Example
In this example, we have combined single and multiple inheritance to
form a hybrid inheritance of classes.
Open Compiler
# parent class
class CEO:
def ceoMethod(self):
print ("I am the CEO")
class Manager(CEO):
def managerMethod(self):
print ("I am the Manager")
class Employee1(Manager):
def employee1 Method(self):
print ("I am Employee one")
class Employee2(Manager, CEO):
def employee Method(self):
print ("I am Employee two")
# creating instances
emp = Employee2()
# method calls
emp.managerMethod()
emp.ceoMethod()
emp.employee w2 method()
Polymorphism
What is Polymorphism in Python?
The term polymorphism refers to a function or method taking
different forms in different contexts. Since Python is a dynamically
typed language, polymorphism in Python is very easily implemented.
If a method in a parent class is overridden with different business logic
in its different child classes, the base class method is a polymorphic
method.
Ways of implementing Polymorphism in Python
There are four ways to implement polymorphism in Python −
Duck Typing
Operator Overloading
Method Overriding
Method Overloading
Example
In the code given below, we are practically demonstrating the concept
of duck typing.
Open Compiler
class Duck:
def sound(self):
return "Quack, quack!"
class AnotherBird:
def sound(self):
return "I'm similar to a duck!"
def makeSound(duck):
print(duck.sound())
# creating instances
duck = Duck()
anotherBird = AnotherBird()
# calling methods
makeSound(duck)
makeSound(anotherBird)
When you execute this code, it will produce the following output −
Quack, quack!
I'm similar to a duck!
Example
As an example of polymorphism given below, we have a shape which is
an abstract class. It is used as a parent by two classes: circle and
rectangle. Both classes override parent's draw() method in different
ways.
Open Compiler
from abc import ABC, abstractmethod
class shape(ABC):
@abstractmethod
def draw(self):
"Abstract method"
return
class circle(shape):
def draw(self):
super().draw()
print ("Draw a circle")
return
class rectangle(shape):
def draw(self):
super().draw()
print ("Draw a rectangle")
return
shapes = [circle(), rectangle()]
for shp in shapes:
shp.draw()
Output
When you run the above code, it will produce the following output −
Draw a circle
Draw a rectangle
The variable shp first refers to the circle object and calls the draw()
method from the circle class. In the next iteration, it refers to a
rectangle object and calls the draw() method from the rectangle class.
Hence the draw() method in the shape class is polymorphic.
Example
Open Compiler
class Vector:
def __init__(self, a, b):
self.a = a
self.b = b
def __str__(self):
return 'Vector (%d, %d)' % (self.a, self.b)
def __add__(self,other):
return Vector(self.a + other.a, self.b + other.b)
v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)
Example
In the following example, we are using the variable-length argument
lists to achieve method overloading.
Open Compiler
def add(*nums):
return sum(nums)
# Call the function with different number of parameters
result1 = add(10, 25)
result2 = add(10, 25, 35)
print(result1)
print(result2)
Method Overriding
Method Overriding in Python
The Python method overriding refers to defining a method in a
subclass with the same name as a method in its superclass. In this
case, the Python interpreter determines which method to call at
runtime based on the actual object being referred to.
You can always override your parent class methods. One reason for
overriding parent's methods is that you may want special or different
functionality in your subclass.
Example
In the code below, we are overriding a method named myMethod of
the Parent class.
Open Compiler
# define parent class
class Parent:
def myMethod(self):
print ('Calling parent method')
# define child class
class Child(Parent):
def myMethod(self):
print ('Calling child method')
# instance of child
c = Child()
# child calls overridden method
c.myMethod()
Example
Declare the object of parent and child classes and see the effect of
overriding. Complete code is below −
Open Compiler
class Employee:
def __init__(self,nm, sal):
self.name=nm
self.salary=sal
def getName(self):
return self.name
def getSalary(self):
return self.salary
class SalesOfficer(Employee):
def __init__(self,nm, sal, inc):
super().__init__(nm,sal)
self.incnt=inc
def getSalary(self):
return self.salary+self.incnt
e1=Employee("Rajesh", 9000)
print ("Total salary for {} is Rs
{}".format(e1.getName(),e1.getSalary()))
s1=SalesOfficer('Kiran', 10000, 1000)
print ("Total salary for {} is Rs
{}".format(s1.getName(),s1.getSalary()))
When you execute this code, it will produce the following output −
Total salary for Rajesh is Rs 9000
Total salary for Kiran is Rs 11000
2 __del__( self )
Destructor, deletes an object
Sample Call : del obj
3 __repr__( self )
Evaluatable string representation
Sample Call : repr(obj)
4 __str__( self )
Printable string representation
Sample Call : str(obj)
Method Overloading
Method overloading is a feature of object-oriented programming
where a class can have multiple methods with the same name but
different parameters. To overload methods, we must change the
number of parameters or the type of parameters, or both.
Example
If you define a method multiple times as shown in the below code, the
last definition will override the previous ones. Therefore, this way of
achieving method overloading in Python generates errors.
Open Compiler
class example:
def add(self, a, b):
x = a+b
return x
def add(self, a, b, c):
x = a+b+c
return x
obj = example()
print (obj.add(10,20,30))
print (obj.add(10,20))
The first call to the add() method with three arguments is successful.
However, calling add() method with two arguments as defined in the
class fails.
60
Traceback (most recent call last):
File "C:\Users\user\example.py", line 12, in <module>
print (obj.add(10,20))
^^^^^^^^^^^^^^
TypeError: example.add() missing 1 required positional argument: 'c'
The output tells you that Python considers only the latest definition of
add() method, discarding the earlier definitions.
To simulate method overloading, we can use a workaround by defining
default value to method arguments as None, so that it can be used with
one, two or three arguments.
Example
The below example shows how to achieve method overloading in
Python −
Open Compiler
class example:
def add(self, a = None, b = None, c = None):
x=0
if a !=None and b != None and c != None:
x = a+b+c
elif a !=None and b != None and c == None:
x = a+b
return x
obj = example()
print (obj.add(10,20,30))
print (obj.add(10,20))
Example
In this example, we are using multiple dispatch to overload a method in
Python.
from multiple dispatch import dispatch
class example:
@dispatch(int, int)
def add(self, a, b):
x = a+b
return x
@dispatch(int, int, int)
def add(self, a, b, c):
x = a+b+c
return x
obj = example()
print (obj.add(10,20,30))
print (obj.add(10,20))
Output
60
30
Dynamic Binding
In object-oriented programming, the concept of dynamic binding is
closely related to polymorphism. In Python, dynamic binding is the
process of resolving a method or attribute at runtime, instead of at
compile time.
According to the polymorphism feature, different objects respond
differently to the same method call based on their implementations.
This behaviour is achieved through method overriding, where a
subclass provides its implementation of a method defined in its
superclass.
The Python interpreter determines which is the appropriate method or
attribute to invoke based on the object's type or class hierarchy at
runtime. This means that the specific method or attribute to be called
is determined dynamically, based on the actual type of the object.
Example
The following example illustrates dynamic binding in Python −
Open Compiler
class shape:
def draw(self):
print ("draw method")
return
class circle(shape):
def draw(self):
print ("Draw a circle")
return
class rectangle(shape):
def draw(self):
print ("Draw a rectangle")
return
shapes = [circle(), rectangle()]
for shp in shapes:
shp.draw()
Duck Typing
Another concept closely related to dynamic binding is duck typing.
Whether an object is suitable for a particular use is determined by the
presence of certain methods or attributes, rather than its type. This
allows for greater flexibility and code reuse in Python.
Duck typing is an important feature of dynamic typing languages like
Python (Perl, Ruby, PHP, Javascript, etc.) that focuses on an object's
behaviour rather than its specific type. According to the "duck typing"
concept, "If it walks like a duck and quacks like a duck, then it must be
a duck."
Duck typing allows objects of different types to be used
interchangeably as long as they have the required methods or
attributes. The goal is to promote flexibility and code reuse. It is a
broader concept that emphasises object behaviour and interface rather
than formal types.
Here is an example of duck typing −
Open Compiler
class circle:
def draw(self):
print ("Draw a circle")
return
class rectangle:
def draw(self):
print ("Draw a rectangle")
return
class area:
def area(self):
print ("calculate area")
return
def duck_function(obj):
obj.draw()
objects = [circle(), rectangle(), area()]
for obj in objects:
duck_function(obj)
Dynamic Typing
One of the standout features of the Python language is that it is a
dynamically typed language. The compiler-based languages C/C++,
Java, etc. are statically typed. Let us try to understand the difference
between static typing and dynamic typing.
In a statically typed language, each variable and its data type must be
declared before assigning it a value. Any other type of value is not
acceptable to the compiler, and it raises a compile-time error.
Let us take the following snippet of a Java program −
public class MyClass {
public static void main(String args[]) {
int var;
var="Hello";
So, var is of string type. However, it is not permanently bound. It's just
a label; and can be assigned to any other type of object, say a float,
which will be stored with a different id() −
>>> var=25.50
>>> print ("id of var is ", id(var))
id of var is 2822589562256
>>> print ("type of var is ", type(var))
type of var is <class 'float'>
We can see that the type of var changes every time it refers to a new
object. That's why Python is a dynamically typed language.
Dynamic typing feature of Python makes it flexible compared to
C/C++ and Java. However, it is prone to runtime errors, so the
programmer has to be careful.
Abstraction
The demo class here may be used as a parent for another class.
However, the child class must override the abstract method in the
parent class. If not, Python throws this error −
TypeError: Can't instantiate abstract class concrete class with abstract
method method1
Example
Open Compiler
from abc import ABC, abstractmethod
class demo class(ABC):
@abstractmethod
def method1(self):
print ("abstract method")
return
def method2(self):
print ("concrete method")
class concrete class(democlass):
def method1(self):
super().method1()
return
obj = concrete class()
obj.method1()
obj.method2()
Output
When you execute this code, it will produce the following output −
abstract method
concrete method
Encapsulation
Encapsulation is the process of bundling attributes and methods
within a single unit. It is one of the main pillars on which the object-
oriented programming paradigm is based.
We know that a class is a user-defined prototype for an object. It
defines a set of data members and methods, capable of processing the
data.
According to the principle of data encapsulation, the data members
that describe an object are hidden from the environment external to
the class. They can only be accessed through the methods within the
same class. Methods themselves on the other hand are accessible from
outside class context. Hence, object data is said to be encapsulated by
the methods. In this way, encapsulation prevents direct access to the
object data.
Example 1
Here, we have an Employee class with instance variables, name and
age. An object of this class has these two attributes. They can be
directly accessed from outside the class, because they are public.
Open Compiler
class Student:
def __init__(self, name="Rajaram", marks=50):
self.name = name
self.marks = marks
s1 = Student()
s2 = Student("Bharat", 25)
print ("Name: {} marks: {}".format(s1.name, s2.marks))
print ("Name: {} marks: {}".format(s2.name, s2.marks))
In the above example, the instance variables are initialised inside the
class. However, there is no restriction on accessing the value of
instance variables from outside the class, which is against the principle
of encapsulation.
Although there are no keywords to enforce visibility, Python has a
convention of naming the instance variables in a peculiar way. In
Python, prefixing the name of a variable/method with a single or double
underscore to emulate the behaviour of protected and private access
modifiers.
If a variable is prefixed by a single double underscore (such as
"__age"), the instance variable is private, similarly if a variable name is
prefixed with a single underscore (such as "_salary")
Example 2
Let us modify the Student class. Add another instance of variable
salary. Make the name private and mark it as private by prefixing
double underscores to them.
Open Compiler
class Student:
def __init__(self, name="Rajaram", marks=50):
self.__name = name
self.__marks = marks
deaf student data(self):
print ("Name: {} marks: {}".format(self.__name, self.__marks))
s1 = Student()
s2 = Student("Bharat", 25)
s1.student data()
s2.student data()
print ("Name: {} marks: {}".format(s1.__name, s2.__marks))
print ("Name: {} marks: {}".format(s2.__name, __s2.marks))
When you run this code, it will produce the following output −
Name: Rajaram marks: 50
Name: Bharat marks: 25
Traceback (most recent call last):
File "C:\Python311\hello.py", line 14, in <module>
print ("Name: {} marks: {}".format(s1.__name, s2.__marks))
AttributeError: 'Student' object has no attribute '__name'
The above output makes it clear that the instance variables name and
age, can be accessed by a method declared inside the class (the
student data() method), but the double underscores prefix makes the
variables private, and hence, accessing them outside the class is
restricted which raises Attribute error.
What is Name Mangling?
Python doesn't block access to private data entirely. It just leaves it to
the wisdom of the programmer, not to write any code that accesses it
from outside the class. You can still access the private members by
Python's name mangling technique.
Name mangling is the process of changing the name of a member
with double underscore to the form object._class__variable. If so
required, it can still be accessed from outside the class, but the
practice should be refrained.
In our example, the private instance variable "__name" is mangled by
changing it to the format
obj._class__privatevar
Interfaces
In software engineering, an interface is a software architectural
pattern. It is similar to a class but its methods just have prototype
signature definition without any executable code or implementation
body. The required functionality must be implemented by the methods
of any class that inherits the interface.
The method defined without any executable code is known as an
abstract method.
Interfaces in Python
In languages like Java and Go, there is a keyword called interface which
is used to define an interface. Python doesn't have it or any similar
keyword. It uses abstract base classes (in short ABC module) and
@abstractmethod decorator to create interfaces.
NOTE: In Python, abstract classes are also created using the ABC
module.
An abstract class and interface appear similar in Python. The only
difference in two is that the abstract class may have some non-abstract
methods, while all methods in interface must be abstract, and the
implementing class must override all the abstract methods.
Formal Interface
Formal interfaces in Python are implemented using abstract base
class (ABC). To use this class, you need to import it from the abc
module.
Example
In this example, we are creating a formal interface with two abstract
methods.
from abc import ABC, abstractmethod
# creating interface
class demoInterface(ABC):
@abstractmethod
def method1(self):
print ("Abstract method1")
return
@abstractmethod
def method2(self):
print ("Abstract method1")
return
def method2(self):
print ("This is method2")
return
# creating instance
obj = concrete class()
# method call
obj.method1()
obj.method2()
Output
When you execute this code, it will produce the following output −
This is method1
This is method2
Informal Interface
In Python, the informal interface refers to a class with methods that
can be overridden. However, the compiler cannot strictly enforce the
implementation of all the provided methods.
This type of interface works on the principle of duck typing . It allows
us to call any method on an object without checking its type, as long as
the method exists.
Example
In the below example, we are demonstrating the concept of informal
interface.
Open Compiler
class demoInterface:
def displayMsg(self):
pass
class newClass(demoInterface):
def displayMsg(self):
print ("This is my message")
# creating instance
obj = newClass()
# method call
obj.displayMsg()
Output
On running the above code, it will produce the following output −
This is my message
Packages
In Python, the module is a Python script with a .py extension and
contains objects such as classes, functions, etc. Packages in Python
extend the concept of the modular approach further. The package is a
folder containing one or more module files; additionally, a special file
"__init__.py" file may be empty but may contain the package list.
Create a Python Package
Let us create a Python package with the name mypackage. Follow
the steps given below −
1. Create an outer folder to hold the contents of mypackage. Let
its name be a package demo.
2. Inside it, create another folder mypackage. This will be the
Python package we are going to construct. Two Python
modules areafunctions.py and mathfunctions.py will be
created inside mypackage.
3. Create an empty "__.init__.py" file inside mypackage folder.
4. Inside the outer folder, we shall later store a Python script
example.py to test our package.
Using your favourite code editor, save the following two Python
modules in mypackage folder.
def average(x,y):
val = (x+y)/2
return val
def power(x,y):
val = x**y
return val
def circle(r):
import maths
area = math.pi*math.pow(r,2)
return area
Let us now test the myexample package with the help of a Python
script above this package folder. Refer to the folder structure above.
#example.py
from mypackage.area functions import rectangle
print ("Area :", rectangle(10,20))
from mypackage.math functions import average
print ("average:", average(10,20))
To import the available functions from this package, save the following
script as testpackage.py, above the package folder as before.
Package Installation
Right now, we are able to access the package resources from a script
just above the package folder. To be able to use the package anywhere
in the file system, you need to install it using the PIP utility.
First of all, save the following script in the parent folder, at the level of
the package folder.
#setup.py
from setuptools import setup
setup(name='mypackage',
version='0.1',
description='Package setup script',
url='#',
author='anonymous',
author_email='[email protected]',
licence='MIT',
packages=['mypackage'],
zip_safe=False)
Run the PIP utility from the command prompt, while remaining in the
parent folder.
C:\Users\user\packagedemo>pip3 install .
Processing c:\users\user\package demo
Preparing metadata (setup.py) ... done
Installing collected packages: mypackage
Running setup.py install for mypackage ... done
Successfully installed mypackage-0.1
You should now be able to import the contents of the package in any
environment.
C:\Users>python
Python 3.11.2 (tags/v3.11.2:878ead1, Feb 7 2023, 16:38:35) [MSC
v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "licence" for more information.
>>> import mypackage
>>> mypackage.circle(5)
78.53981633974483
Inner Classes
Inner Class in Python
A class defined inside another class is known as an inner class in
Python. Sometimes inner classes are also called nested classes. If the
inner class is instantiated, the object of the inner class can also be used
by the parent class. Object of the inner class becomes one of the
attributes of the outer class. Inner class automatically inherits the
attributes of the outer class without formally establishing inheritance.
Syntax
class outer:
def __init__(self):
pass
class inner:
def __init__(self):
pass
An inner class lets you group classes. One of the advantages of nesting
classes is that it becomes easy to understand which classes are
related. The inner class has a local scope. It acts as one of the
attributes of the outer class.
Example
In the following code, we have students as the outer class and subjects
as the inner class. The __init__() constructor of student initialises name
attribute and an instance of subject class. On the other hand, the
constructor of inner subjects class initialises two instance variables
sub1, sub2.
A show() method of outer class calls the method of inner class with the
object that has been instantiated.
Open Compiler
class student:
def __init__(self):
self.name = "Ashish"
self.subs = self.subjects()
return
def show(self):
print ("Name:", self.name)
self.subs.display()
class subjects:
def __init__(self):
self.sub1 = "Phy"
self.sub2 = "Che"
return
def display(self):
print ("Subjects:",self.sub1, self.sub2)
s1 = student()
s1.show()
When you execute this code, it will produce the following output −
Name: Ashish
Subjects: Phy Che
Example
In the below example, we have created an outer class named
Organization and two inner classes.
Open Compiler
class Organisation:
def __init__(self):
self.inner1 = self.Department1()
self.inner = self.Department 2()
def showName(self):
print("Organization Name: Tutorials Point")
class Department1:
def displayDepartment1(self):
print("In Department 1")
class Department2:
def displayDepartment2(self):
print("In Department 2")
# instance of OuterClass
outer = Organization()
# Calling show method
outer.showName()
# InnerClass instance 1
inner1 = outer.inner 1
# Calling display method
inner1.displayDepartment1()
# InnerClass instance 2
inner2 = outer.inner 2
# Calling display method
inner2.displayDepartment2()
Example
The following code explains the working of Multilevel Inner Class in
Python −
Open Compiler
class Organisation:
def __init__(self):
self.inner = self.Department()
def showName(self):
print("Organization Name: Tutorials Point")
class Department:
def __init__(self):
self.innerTeam = self.Team1()
define displayDep(self):
print("In Department")
class Team1:
def displayTeam(self):
print("Team 1 of the department")
# instance of outer class
outer = Organization()
# call the method of outer class
outer.showName()
# Inner Class instance
inner = outer.inner
inner.displayDep()
# Access Team1 instance
innerTeam = inner.innerTeam
# Calling display method
innerTeam.displayTeam()
When you run the above code, it will produce the below output −
Organisation Name: Tutorials Point
In Department
Team 1 of the department
Example
Open Compiler
class myclass:
def __init__(self):
self.myvar=10
return
obj = myclass()
print ('class of int', type(int))
print ('class of list', type(list))
print ('class of dict', type(dict))
print ('class of myclass', type(myclass))
print ('class of obj', type(obj))
Syntax
new class=type(name, bases, dict)
Singleton Class
In Python, a Singleton class is the implementation of singleton design
pattern which means this type of class can have only one object. This
helps in optimising memory usage when you perform some heavy
operation, like creating a database connection.
If we try to create multiple objects for a singleton class, the object will
be created only for the first time. After that, the same object instance
will be returned.
Using __init__
The __init__ method is an instance method that is used for initialising
a newly created object. It’s automatically called when an object is
created from a class.
If we use this method with a static method and provide necessary
checks i.e., whether an instance of the class already exists or not, we
can restrict the creation of a new object after the first one is created.
Example
In the below example, we are creating a singleton class using the
__init__ method.
Open Compiler
class Singleton:
__uniqueInstance = None
@staticmethod
def createInstance():
if Singleton.__uniqueInstance == None:
Singleton()
return Singleton.__uniqueInstance
def __init__(self):
if Singleton.__uniqueInstance != None:
raise Exception("Object exist!")
else:
Singleton.__uniqueInstance = self
obj1 = Singleton.createInstance()
print(obj1)
obj2 = Singleton.createInstance()
print(obj2)
When we run the above code, it will show the following result −
<__main__.Singleton object at 0x7e4da068a910>
<__main__.Singleton object at 0x7e4da068a910>
Using __new__
The __new__ method is a special static method in Python that is
called to create a new instance of a class. It takes the class itself as the
first argument and returns a new instance of that class.
When an instance of a Python class is declared, it internally calls the
__new__() method. If you want to implement a Singleton class, you can
override this method.
In the overridden method, you first check whether an instance of the
class already exists. If it doesn’t (i.e., if the instance is None), you call
the super() method to create a new object. At the end, save this
instance in a class attribute and return the result.
Example
In the following example, we are creating a singleton class using the
__new__ method.
Open Compiler
class SingletonClass:
_instance = None
def __new__(cls):
if cls._instance is None:
print('Creating the object')
cls._instance = super(SingletonClass, cls).__new__(cls)
return cls._instance
obj1 = SingletonClass()
print(obj1)
obj2 = SingletonClass()
print(obj2)
Wrapper Classes
A function in Python is a first-order object. A function can have another
function as its argument and wrap another function definition inside it.
This helps in modifying a function without actually changing it. Such
functions are called decorators.
This feature is also available for wrapping a class. This technique is
used to manage the class after it is instantiated by wrapping its logic
inside a decorator.
Example
Open Compiler
def decorator_function(Wrapped):
class Wrapper:
def __init__(self,x):
self.wrap = Wrapped(x)
def print_name(self):
return self.wrap.name
return Wrapper
@decorator_function
class Wrapped:
def __init__(self,x):
self.name = x
obj = Wrapped('TutorialsPoint')
print(obj.print_name())
Enums
Enums in Python
In Python, the term enumeration refers to the process of assigning
fixed constant values to a set of strings so that each string can be
identified by the value bound to it. The Enum class included in the
enum module (which is a part of Python's standard library) is used as
the parent class to define enumeration of a set of identifiers −
conventionally written in upper case.
Example
In the code below, "subjects" is the enumeration. It has different
enumeration members and each member is an object of the
enumeration class subjects. These members have name and value
attributes.
Open Compiler
# importing enum
from enum import Enum
class subjects(Enum):
ENGLISH = 1
MATHS = 2
SCIENCE = 3
SANSKRIT = 4
obj = subjects.MATHS
print (type(obj))
Example
In this example, we are using the @unique decorator to restrict
duplicates.
Open Compiler
from enum import Enum, unique
@unique
class subjects(Enum):
ENGLISH = 1
MATHS = 2
GEOGRAPHY = 3
SANSKRIT = 2
Example
following is an alternative method of defining an enumeration −
from enum import Enum
subjects = Enum("subjects", "ENGLISH MATHS SCIENCE SANSKRIT")
print(subjects.ENGLISH)
print(subjects.MATHS)
print(subjects.SCIENCE)
print(subjects.SANSKRIT)
Example
The following example illustrates how to access the value and name of
the enum member.
Open Compiler
from enum import Enum
class subjects(Enum):
ENGLISH = "E"
MATHS = "M"
GEOGRAPHY = "G"
SANSKRIT = "S"
obj = subjects.SANSKRIT
print(type(obj))
print(obj.name)
print(obj.value)
Example
The following example shows how to iterate through an enumeration
using for loop −
Open Compiler
from enum import Enum
class subjects(Enum):
ENGLISH = "E"
MATHS = "M"
GEOGRAPHY = "G"
SANSKRIT = "S"
for sub in subjects:
print (sub.name, sub.value)
We know that enum members can be accessed with the unique value
assigned to it, or by its name attribute. Hence, subjects("E") as well as
subjects["ENGLISH"] return subjects.ENGLISH members.
Reflection
In object-oriented programming, reflection refers to the ability to
extract information about any object in use. You can get to know the
type of object, whether it is a subclass of any other class, what are its
attributes, and much more. Python's standard library has several
functions that reflect on different properties of an object. Reflection is
also sometimes called introspect.
Following is the list of reflection functions in Python −
type() Function
isinstance() Function
issubclass() Function
callable() Function
getattr() Function
setattr() Function
hasattr() Function
dir() Function
Example
Following statements print the respective class of different built-in data
type objects
Open Compiler
print (type(10))
print (type(2.56))
print (type(2+3j))
print (type("Hello World"))
print (type([1,2,3]))
print (type({1:'one', 2:'two'}))
Here, you will get the following output −
<class 'int'>
<class 'float'>
<class 'complex'>
<class 'str'>
<class 'list'>
<class 'dict'>
Syntax
isinstance(obj, class)
This function always returns a Boolean value, true if the object indeed
belongs to the given class and false if not.
Example
Following statements return True −
Open Compiler
print (isinstance(10, int))
print (isinstance(2.56, float))
print (isinstance(2+3j, complex))
print (isinstance("Hello World", str))
It will produce the following output −
True
True
True
True
In Python, even the classes are objects. All classes are objects of object
class. It can be verified by following code −
Open Compiler
class test:
pass
print (isinstance(int, object))
print (isinstance(str, object))
print (isinstance(test, object))
Example
Open Compiler
def test():
pass
print (callable("Hello"))
print (callable(abs))
print (callable(list.clear([1,2])))
print (callable(test))
Example
Open Compiler
class test:
def __init__(self):
self.name = "Manav"
obj = test()
print (getattr(obj, "name"))
It will produce the following output −
Manav
Example
Open Compiler
print ("dir(int):", dir(int))
Example
Open Compiler
print ("dir(dict):", dir(dict))
Example
Open Compiler
class test:
def __init__(self):
self.name = "Manav"
obj = test()
print ("dir(obj):", dir(obj))
Syntax Errors
Popular IDEs with these features include PyCharm, Visual Studio Code,
and Jupyter Notebook.
To fix this error, you need to ensure that every opening parenthesis has
a corresponding closing parenthesis. Here is the corrected code −
Open Compiler
print("Hello, World!")
Exceptions Handling
Exception Handling in Python
Exception handling in Python refers to managing runtime errors that
may occur during the execution of a program. In Python, exceptions are
raised when errors or unexpected situations arise during program
execution, such as division by zero, trying to access a file that does not
exist, or attempting to perform an operation on incompatible data
types.
Python provides two very important features to handle any unexpected
error in your Python programs and to add debugging capabilities in
them −
Exception Handling − This would be covered in this tutorial.
Here is a list of standard Exceptions available in Python:
Standard Exceptions.
Assertions − This would be covered in Assertions in Python
tutorial.
Assertions in Python
An assertion is a sanity-check that you can turn on or turn off when you
are done with your testing of the program.
The easiest way to think of an assertion is to liken it to a raise-if
statement (or to be more accurate, a raise-if-not statement). An
expression is tested, and if the result comes up false, an exception is
raised.
Assertions are carried out by the assert statement, the newest keyword
to Python, introduced in version 1.5.
Programmers often place assertions at the start of a function to check
for valid input, and after a function call to check for valid output.
Example
Here is a function that converts a temperature from degrees Kelvin to
degrees Fahrenheit. Since zero degrees Kelvin is as cold as it gets, the
function bails out if it sees a negative temperature −
Open Compiler
define KelvinToFahrenheit(Temperature):
assert (Temperature >= 0),"Colder than absolute zero!"
return ((Temperature-273)*1.8)+32
print (KelvinToFahrenheit(273))
print (int(KelvinToFahrenheit(505.78)))
print (KelvinToFahrenheit(-5))
What is an Exception?
An exception is an event, which occurs during the execution of a
program that disrupts the normal flow of the program's instructions. In
general, when a Python script encounters a situation that it cannot
cope with, it raises an exception. An exception is a Python object that
represents an error.
When a Python script raises an exception, it must either handle the
exception immediately otherwise it terminates and quits.
Example
This example opens a file, writes content in the file and comes out
gracefully because there is no problem at all.
Open Compiler
try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
except IOError:
print ("Error: can\'t find file or read data")
else:
print ("Written content in the file successfully")
fh.close()
It will produce the following output −
Written content in the file successfully
Example
This example tries to open a file where you do not have write
permission, so it raises an exception −
Open Compiler
try:
fh = open("testfile", "r")
fh.write("This is my test file for exception handling!!")
except IOError:
print ("Error: can\'t find file or read data")
else:
print ("Written content in the file successfully")
You cannot use the else clause as well along with the finally clause.
Example
Open Compiler
try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
finally:
print ("Error: can\'t find file or read data")
If you do not have permission to open the file in writing mode, then this
will produce the following result −
Error: can't find file or read data
Argument of an Exception
An exception can have an argument, which is a value that gives
additional information about the problem. The contents of the
argument vary by exception. You capture an exception's argument by
supplying a variable in the except clause as follows −
try:
You do your operations here;
......................
except ExceptionType, Argument:
You can print the value of the Argument here...
If you write the code to handle a single exception, you can have a
variable follow the name of the exception in the except statement. If
you are trapping multiple exceptions, you can have a variable follow
the tuple of the exception.
This variable receives the value of the exception mostly containing the
cause of the exception. The variable can receive a single value or
multiple values in the form of a tuple. This tuple usually contains the
error string, the error number, and an error location.
Example
Following is an example for a single exception −
Open Compiler
# Define a function here.
def temp_convert(var):
try:
return int(var)
except ValueError as Argument:
print ("The argument does not contain numbers\n", Argument)
# Call above function here.
temp_convert("xyz")
Raising an Exceptions
You can raise exceptions in several ways by using the raise statement.
The general syntax for the raise statement is as follows.
Syntax
raise [Exception [, args [, traceback]]]
Example
An exception can be a string, a class or an object. Most of the
exceptions that the Python core raises are classes, with an argument
that is an instance of the class. Defining new exceptions is quite easy
and can be done as follows −
def functionName( level ):
if level < 1:
raise "Invalid level!", level
# The code below to this would not be executed
# if we raise the exception
User-Defined Exceptions
Python also allows you to create your own exceptions by deriving
classes from the standard built-in exceptions.
Here is an example related to RuntimeError. Here, a class is created
that is subclassed from RuntimeError. This is useful when you need to
display more specific information when an exception is caught.
In the try block, the user-defined exception is raised and caught in the
except block. The variable e is used to create an instance of the class
Networkerror.
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args = arg
So once you defined above class, you can raise the exception as follows
−
try:
raise Networkerror("Bad hostname")
except Networkerror,e:
print (e.args)
Standard Exceptions
Here is a list of Standard Exceptions available in Python −
1 Exception
Base class for all exceptions
2 StopIteration
Raised when the next() method of an iterator does not point to
any object.
3 SystemExit
Raised by the sys.exit() function.
4 StandardError
Base class for all built-in exceptions except StopIteration and
SystemExit.
5 ArithmeticError
Base class for all errors that occur for numeric calculation.
6 OverflowError
Raised when a calculation exceeds the maximum limit for a
numeric type.
7 FloatingPointError
Raised when a floating point calculation fails.
8 ZeroDivisionError
Raised when division or modulo by zero takes place for all
numeric types.
9 AssertionError
Raised in case of failure of the Assert statement.
10 AttributeError
Raised in case of failure of attribute reference or assignment.
11 EOFError
Raised when there is no input from either the raw_input() or
input() function and the end of file is reached.
12 ImportError
Raised when an import statement fails.
13 KeyboardInterrupt
Raised when the user interrupts program execution, usually by
pressing Ctrl+c.
14 LookupError
Base class for all lookup errors.
15 IndexError
Raised when an index is not found in a sequence.
16 KeyError
Raised when the specified key is not found in the dictionary.
17 NameError
Raised when an identifier is not found in the local or global
namespace.
18 UnboundLocalError
Raised when trying to access a local variable in a function or
method but no value has been assigned to it.
19 EnvironmentError
Base class for all exceptions that occur outside the Python
environment.
20 IOError
Raised when an input/ output operation fails, such as the print
statement or the open() function when trying to open a file
that does not exist.
21 IOError
Raised for operating system-related errors.
22 SyntaxError
Raised when there is an error in Python syntax.
23 IndentationError
Raised when indentation is not specified properly.
24 SystemError
Raised when the interpreter finds an internal problem, but
when this error is encountered the Python interpreter does not
exist.
25 SystemExit
Raised when the Python interpreter is quit by using the
sys.exit() function. If not handled in the code, causes the
interpreter to exit.
26 TypeError
Raised when an operation or function is attempted that is
invalid for the specified data type.
27 ValueError
Raised when the built-in function for a data type has the valid
type of arguments, but the arguments have invalid values
specified.
28 RuntimeError
Raised when a generated error does not fall into any category.
29 NotImplementedError
Raised when an abstract method that needs to be
implemented in an inherited class is not actually implemented.
Syntax
Following is the basic syntax of the try-except block in Python −
try:
# Code that might cause an exception
risky_code()
except SomeException as e:
# Code that runs if an exception occurs
handle_exception(e)
Example
In this example, if you enter a non-numeric value, a ValueError will be
raised. If you enter zero, a ZeroDivisionError will be raised. The
except blocks handle these exceptions and prints appropriate error
messages −
try:
number = int(input("Enter a number: "))
result = 10 / number
print(f"Result: {result}")
except ZeroDivisionError as e:
print("Error: Cannot divide by zero.")
except ValueError as e:
print("Error: Invalid input. Please enter a valid number.")
Syntax
Following is the basic syntax for handling multiple exceptions in Python
−
try:
# Code that might raise exceptions
risky_code()
except FirstExceptionType:
# Handle the first type of exception
handle_first_exception()
except SecondExceptionType:
# Handle the second type of exception
handle_second_exception()
# Add more except blocks as needed for other exception types
Example
In the following example −
If you enter zero as the divisor, a "ZeroDivisionError" will be
raised, and the corresponding except ZeroDivisionError block
will handle it by printing an error message.
If you enter a non-numeric input for either the dividend or the
divisor, a "ValueError" will be raised, and the except
ValueError block will handle it by printing a different error
message.
try:
dividend = int(input("Enter the dividend: "))
divisor = int(input("Enter the divisor: "))
result = dividend / divisor
print(f"Result of division: {result}")
except ZeroDivisionError:
print("Error: Cannot divide by zero.")
except ValueError:
print("Error: Invalid input. Please enter valid integers.")
Syntax
Following is the basic syntax of the else clause in Python −
try:
# Code that might raise exceptions
risky_code()
except SomeExceptionType:
# Handle the exception
handle_exception()
else:
# Code that runs if no exceptions occurred
no_exceptions_code()
Example
In the following example −
1. If you enter a non-integer input, a ValueError will be raised,
and the corresponding except ValueError block will handle it.
2. If you enter zero as the denominator, a ZeroDivisionError will
be raised, and the corresponding except ZeroDivisionError
block will handle it.
3. If the division is successful (i.e., no exceptions are raised), the
else block will execute and print the result of the division.
try:
numerator = int(input("Enter the numerator: "))
denominator = int(input("Enter the denominator: "))
result = numerator / denominator
except ValueError:
print("Error: Invalid input. Please enter valid integers.")
except ZeroDivisionError:
print("Error: Cannot divide by zero.")
else:
print(f"Result of division: {result}")
Syntax
Following is the basic syntax of the finally clause in Python −
try:
# Code that might raise exceptions
risky_code()
except SomeExceptionType:
# Handle the exception
handle_exception()
else:
# Code that runs if no exceptions occurred
no_exceptions_code()
finally:
# Code that always runs, regardless of exceptions
cleanup_code()
Example
In this example −
If the file "example.txt" exists, its content is read and printed,
and the else block confirms the successful operation.
If the file is not found (FileNotFoundError), an appropriate
error message is printed in the except block.
The finally block ensures that the file is closed (file.close())
regardless of whether the file operation succeeds or an
exception occurs.
try:
file = open("example.txt", "r")
content = file.read()
print(content)
except FileNotFoundError:
print("Error: The file was not found.")
else:
print("File read operation successful.")
finally:
if 'file' in locals():
file.close()
print("File operation is complete.")
Print Page
Syntax
The syntax of the try-finally statement is as follows −
try:
# Code that might raise exceptions
risky_code()
finally:
# Code that always runs, regardless of exceptions
cleanup_code()
In Python, when using exception handling with try blocks, you have the
option to include either except clauses to catch specific exceptions or a
finally clause to ensure certain cleanup operations are executed, but
not both together.
Example
Let us consider an example where we want to open a file in write mode
("w"), writes some content to it, and ensures the file is closed
regardless of success or failure using a finally block −
try:
fh = open("testfile", "w")
fh.write("This is my test file for exception handling!!")
finally:
print ("Error: can\'t find file or read data")
fh.close()
If you do not have permission to open the file in writing mode, then it
will produce the following output −
Error: can't find file or read data
If you write the code to handle a single exception, you can have a
variable follow the name of the exception in the except statement. If
you are trapping multiple exceptions, you can have a variable follow
the tuple of the exception.
This variable receives the value of the exception mostly containing the
cause of the exception. The variable can receive a single value or
multiple values in the form of a tuple. This tuple usually contains the
error string, the error number, and an error location.
Example
Following is an example for a single exception −
Open Compiler
# Define a function here.
def temp_convert(var):
try:
return int(var)
except ValueError as Argument:
print("The argument does not contain numbers\n",Argument)
# Call above function here.
temp_convert("xyz")
Raising Exceptions
Raising Exceptions in Python
In Python, you can raise exceptions explicitly using the raise
statement. Raising exceptions allows you to indicate that an error has
occurred and to control the flow of your program by handling these
exceptions appropriately.
Raising an exception refers to explicitly triggering an error condition in
your program. This can be useful for handling situations where the
normal flow of your program cannot continue due to an error or an
unexpected condition.
In Python, you can raise built-in exceptions like ValueError or TypeError
to indicate common error conditions. Additionally, you can create and
raise custom exceptions.
Example
In this example −
We define a custom exception class "InvalidAgeError" that
inherits from "Exception".
The __init__() method initialises the exception with the invalid
age and a default error message.
The set_age() function raises "InvalidAgeError" if the
provided age is outside the valid range.
Open Compiler
class InvalidAgeError(Exception):
def __init__(self, age, message="Age must be between 18 and 100"):
self.age = age
self.message = message
super().__init__(self.message)
def set_age(age):
if age < 18 or age > 100:
raise InvalidAgeError(age)
print(f"Age is set to {age}")
try:
set_age(150)
except InvalidAgeError as e:
print(f"Invalid age: {e.age}. {e.message}")
Re-Raising Exceptions
Sometimes, you may need to catch an exception, perform specific
actions (such as logging, cleanup, or providing additional context), and
then re-raise the same exception to be handled further up the call stack
This is useful when you want to ensure certain actions are taken when
an exception occurs, but still allow the exception to propagate for
higher-level handling.
To re-raise an exception in Python, you use the "raise" statement
without specifying an exception, which will re-raise the last exception
that was active in the current scope.
Example
In the following example −
The process_file() function attempts to open and read a file.
If the file is not found, it prints an error message and re-raises
the "FileNotFoundError" exception.
The exception is then caught and handled at a higher level in
the call stack.
Open Compiler
def process_file(filename):
try:
with open(filename, "r") as file:
data = file.read()
# Process data
except FileNotFoundError as e:
print(f"File not found: {filename}")
# Re-raise the exception
raise
try:
process_file("nonexistentfile.txt")
except FileNotFoundError as e:
print("Handling the exception at a higher level")
Example
In the following code snippet, trying to open a non-existent file raises
FileNotFoundError. It is detected by the except block. While handling
another exception is raised.
Open Compiler
try:
open("nofile.txt")
except OSError:
raise RuntimeError("unable to handle error")
Example 1
Here, the try block has a "division by 0" situation, hence the except
block comes into play. It is equipped to handle the generic exception
with the Exception class.
Open Compiler
a=10
b=0
try:
print (a/b)
except Exception:
print ("General Exception")
finally:
print ("inside outer finally block")
Example 2
Let us now see how to nest the try constructs. We put another "try −
except − finally" block inside the existing try block. The except keyword
for inner try now handles generic Exception, while we ask the except
block of outer try to handle ZeroDivisionError.
Since exception doesn't occur in the inner try block, its corresponding
generic Except isn't called. The division by 0 situation is handled by the
outer except clause.
Open Compiler
a=10
b=0
try:
print (a/b)
try:
print ("This is inner try block")
except Exception:
print ("General exception")
finally:
print ("inside inner finally block")
except ZeroDivisionError:
print ("Division by 0")
finally:
print ("inside outer finally block")
Example 3
Now we reverse the situation. Out of the nested try blocks, the outer
one doesn't have any exception raised, but the statement causing
division by 0 is inside the inner try, and hence the exception is handled
by the inner except block. Obviously, the except part corresponding
to outer try: will not be called upon.
Open Compiler
a=10
b=0
try:
print ("This is outer try block")
try:
print (a/b)
except ZeroDivisionError:
print ("Division by 0")
finally:
print ("inside inner finally block")
except Exception:
print ("General Exception")
finally:
print ("inside outer finally block")
In the end, let us discuss another situation which may occur in case of
nested blocks. While there isn't any exception in the outer try:, there
isn't a suitable except block to handle the one inside the inner try:
block.
Example 4
In the following example, the inner try: faces "division by 0", but its
corresponding except: is looking for KeyError instead of
ZeroDivisionError. Hence, the exception object is passed on to the
except: block of the subsequent except statement matching with outer
try: statement. There, the zeroDivisionError exception is trapped and
handled.
Open Compiler
a=10
b=0
try:
print ("This is outer try block")
try:
print (a/b)
except KeyError:
print ("Key Error")
finally:
print ("inside inner finally block")
except ZeroDivisionError:
print ("Division by 0")
finally:
print ("inside outer finally block")
User-Defined Exceptions
User-Defined Exceptions in Python
User-defined exceptions in Python are custom error classes that you
create to handle specific error conditions in your code. They are derived
from the built-in Exception class or any of its subclasses.
User-defined exceptions provide more precise control over error
handling in your application −
1. Clarity − They provide specific error messages that make it
clear what went wrong.
2. Granularity − They allow you to handle different error
conditions separately.
3. Maintainability − They centralised error handling logic,
making your code easier to maintain.
Explanation
1. Inheritance − By inheriting from "Exception", your custom
exception will have the same behaviour and attributes as the
built-in exceptions.
2. Class Definition − The class is defined using the standard
Python class syntax. For simple custom exceptions, you can
define an empty class body using the "pass" statement.
Explanation
1. Attributes − Define attributes such as "age" and "message"
to store information about the error.
2. Initialization − The "__init__" method initialises these
attributes. The "super().__init__(self.message)" call ensures
that the base "Exception" class is properly initialised with the
error message.
3. Default Message − A default message is provided, but you
can override it when raising the exception.
Explanation
1. __str__ Method − The "__str__" method returns a string
representation of the exception. This is what will be displayed
when the exception is printed.
2. Custom Message − Customise the message to include
relevant information, such as the provided age in this
example.
Syntax
Following is the basic syntax for raising an exception −
raise ExceptionType(args)
Example
In this example, the "set_age" function raises an "InvalidAgeError" if the
age is outside the valid range −
def set_age(age):
if age < 18 or age > 100:
raise InvalidAgeError(age)
print(f"Age is set to {age}")
Syntax
Following is the basic syntax for handling exceptions −
try:
# Code that may raise an exception
except ExceptionType as e:
# Code to handle the exception
Example
In the below example, the "try" block calls "set_age" with an invalid
age. The "except" block catches the "InvalidAgeError" and prints the
custom error message −
try:
set_age(150)
except InvalidAgeError as e:
print(f"Invalid age: {e.age}. {e.message}")
Complete Example
Combining all the steps, here is a complete example of creating and
using a user-defined exception −
Open Compiler
class InvalidAgeError(Exception):
def __init__(self, age, message="Age must be between 18 and 100"):
self.age = age
self.message = message
super().__init__(self.message)
def __str__(self):
return f"{self.message}. Provided age: {self.age}"
def set_age(age):
if age < 18 or age > 100:
raise InvalidAgeError(age)
print(f"Age is set to {age}")
try:
set_age(150)
except InvalidAgeError as e:
print(f"Invalid age: {e.age}. {e.message}")
Logging
Logging in Python
Logging is the process of recording messages during the execution of a
program to provide runtime information that can be useful for
monitoring, debugging, and auditing.
In Python, logging is achieved through the built-in logging module,
which provides a flexible framework for generating log messages.
Benefits of Logging
Following are the benefits of using logging in Python −
1. Debugging − Helps identify and diagnose issues by
capturing relevant information during program execution.
2. Monitoring − Provides insights into the application's
behaviour and performance.
3. Auditing − Keeps a record of important events and actions
for security purposes.
4. Troubleshooting − Facilitates tracking of program flow and
variable values to understand unexpected behaviour.
Logging Levels
Logging levels in Python define the severity of log messages, allowing
developers to categorise and filter messages based on their
importance. Each logging level has a specific purpose and helps in
understanding the significance of the logged information −
1. DEBUG − Detailed information, typically useful only for
debugging purposes. These messages are used to trace the
flow of the program and are usually not seen in production
environments.
2. INFO − Confirmation that things are working as expected.
These messages provide general information about the
progress of the application.
3. WARNING − Indicates potential issues that do not prevent
the program from running but might require attention. These
messages can be used to alert developers about unexpected
situations.
4. ERROR − Indicates a more serious problem that prevents a
specific function or operation from completing successfully.
These messages highlight errors that need immediate
attention but do not necessarily terminate the application.
5. CRITICAL − The most severe level, indicating a critical error
that may lead to the termination of the program. These
messages are reserved for critical failures that require
immediate intervention.
Usage
Following are the usage scenarios for each logging level in Python
applications −
Choosing the Right Level − Selecting the appropriate logging level
ensures that log messages provide relevant information without
cluttering the logs.
Setting Levels − Loggers, handlers, and specific log messages can be
configured with different levels to control which messages are recorded
and where they are outputted.
Hierarchy − Logging levels are hierarchical, meaning that setting a
level on a logger also affects the handlers and log messages associated
with it.
Output
Following is the output of the above code −
2024-06-19 09:00:06,774 - INFO - Starting the program
2024-06-19 09:00:06,774 - DEBUG - Calculating sum of 10 and 20
2024-06-19 09:00:06,774 - INFO - Sum calculated successfully: 30
2024-06-19 09:00:06,775 - INFO - Program completed
Configuring Logging
Configuring logging in Python refers to setting up various components
such as loggers, handlers, and formatters to control how and where log
messages are stored and displayed. This configuration allows
developers to customise logging behaviour according to their
application's requirements and deployment environment.
Example
In the following example, the getLogger() function retrieves or creates
a named logger. Loggers are organised hierarchically based on their
names. Then, handlers like "StreamHandler" (console handler) are
created to define where log messages go. They can be configured with
specific log levels and formatters.
The formatters specify the layout of log records, determining how log
messages appear when printed or stored −
Open Compiler
import logging
# Create logger
logger = logging.getLogger('my_app')
logger.setLevel(logging.DEBUG) # Set global log level
# Create console handler and set level to debug
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)
# Create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %
(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
# Add console handler to logger
logger.addHandler(console_handler)
# Example usage
logger.debug('This is a debug message')
logger.info('This is an info message')
logger.warning('This is a warning message')
logger.error('This is an error message')
logger.critical('This is a critical message')
Logging Handlers
Logging handlers in Python determine where and how log messages
are processed and outputted. They play an important role in directing
log messages to specific destinations such as the console, files, email,
databases, or even remote servers.
Each handler can be configured independently to control the format,
log level, and other properties of the messages it processes.
Assertions
Assertions in Python
Assertions in Python are statements that assert or assume a condition
to be true. If the condition turns out to be false, Python raises an
AssertionError exception. They are used to detect programming
errors that should never occur if the code is correct.
1. The easiest way to think of an assertion is to liken it to a raise-
if statement (or to be more accurate, a raise-if-not statement).
An expression is tested, and if the result comes up false, an
exception is raised.
2. Assertions are carried out by the assert statement, the newest
keyword to Python, introduced in version 1.5.
3. Programmers often place assertions at the start of a function
to check for valid input, and after a function call to check for
valid output.
Where,
condition − A boolean expression that should be true.
message (optional) − An optional message to be displayed
if the assertion fails.
Using Assertions
Assertions are generally used during development and testing phases
to check conditions that should always hold true.
Example
In the following example, we are using assertions to ensure that the
variable "num" falls within the valid range of "0" to "100". If the
assertion fails, Python raises an "AssertionError", preventing further
execution of the subsequent print statement −
print('Enter marks out of 100:')
num = 75
assert num >= 0 and num <= 100
print('Marks obtained:', num)
num = 125
assert num >= 0 and num <= 100
print('Marks obtained:', num) # This line won't be reached if assertion
fails
Handling AssertionError
Assertions can be caught and handled like any other exception using a
try-except block. If they are not handled, they will terminate the
program and produce a traceback −
try:
num = int(input('Enter a number: '))
assert num >= 0, "Only non-negative numbers are accepted"
print(num)
except AssertionError as msg:
print(msg)
Built-in Exceptions
Built-in exceptions are pre-defined error classes in Python that handle
errors and exceptional conditions in programs. They are derived from
the base class "BaseException" and are part of the standard library.
1 Exception
Base class for all exceptions
2 StopIteration
Raised when the next() method of an iterator does not point to
any object.
3 SystemExit
Raised by the sys.exit() function.
4 StandardError
Base class for all built-in exceptions except StopIteration and
SystemExit.
5 ArithmeticError
Base class for all errors that occur for numeric calculation.
6 OverflowError
Raised when a calculation exceeds the maximum limit for a
numeric type.
7 FloatingPointError
Raised when a floating point calculation fails.
8 ZeroDivisionError
Raised when division or modulo by zero takes place for all
numeric types.
9 AssertionError
Raised in case of failure of the Assert statement.
10 AttributeError
Raised in case of failure of attribute reference or assignment.
11 EOFError
Raised when there is no input from either the raw_input() or
input() function and the end of file is reached.
12 ImportError
Raised when an import statement fails.
13 KeyboardInterrupt
Raised when the user interrupts program execution, usually by
pressing Ctrl+C.
14 LookupError
Base class for all lookup errors.
15 IndexError
Raised when an index is not found in a sequence.
16 KeyError
Raised when the specified key is not found in the dictionary.
17 NameError
Raised when an identifier is not found in the local or global
namespace.
18 UnboundLocalError
Raised when trying to access a local variable in a function or
method but no value has been assigned to it.
19 EnvironmentError
Base class for all exceptions that occur outside the Python
environment.
20 IOError
Raised when an input/ output operation fails, such as the print
statement or the open() function when trying to open a file
that does not exist.
21 OSError
Raised for operating system-related errors.
22 SyntaxError
Raised when there is an error in Python syntax.
23 IndentationError
Raised when indentation is not specified properly.
24 SystemError
Raised when the interpreter finds an internal problem, but
when this error is encountered the Python interpreter does not
exist.
25 SystemExit
Raised when the Python interpreter is quit by using the
sys.exit() function. If not handled in the code, causes the
interpreter to exit.
26 TypeError
Raised when an operation or function is attempted that is
invalid for the specified data type.
27 ValueError
Raised when the built-in function for a data type has the valid
type of arguments, but the arguments have invalid values
specified.
28 RuntimeError
Raised when a generated error does not fall into any category.
29 NotImplementedError
Raised when an abstract method that needs to be
implemented in an inherited class is not actually implemented.
IndexError
It is shown when trying to access an item at invalid index.
Open Compiler
numbers=[10,20,30,40]
for n in range(5):
print (numbers[n])
ModuleNotFoundError
This is displayed when the module could not be found.
import notamodule
Traceback (most recent call last):
import notamodule
ModuleNotFoundError: No module named 'notamodule'
KeyError
It occurs as the dictionary key is not found.
D1={'1':"aa", '2':"bb", '3':"cc"}
print ( D1['4'])
Traceback (most recent call last):
D1['4']
KeyError: '4'
ImportError
It is shown when a specified function is not available for import.
from maths import cube
Traceback (most recent call last):
from maths import cube
ImportError: cannot import name 'cube'
StopIteration
This error appears when the next() function is called after the iterator
stream exhausts.
.it=iter([1,2,3])
next(it)
next(it)
next(it)
next(it)
Traceback (most recent call last):
next(it)
StopIteration
TypeError
This is shown when operator or function is applied to an object of
inappropriate type.
print ('2'+2)
Traceback (most recent call last):
'2'+2
TypeError: must be str, not int
ValueError
It is displayed when the function's argument is of an inappropriate
type.
print (int('xyz'))
Traceback (most recent call last):
int('xyz')
ValueError: invalid literal for int() with base 10: 'xyz'
NameError
This is encountered when objects could not be found.
print (age)
Traceback (most recent call last):
age
NameError: name 'age' is not defined
ZeroDivisionError
It is shown when the second operator in division is zero.
x=100/0
Traceback (most recent call last):
x=100/0
ZeroDivisionError: division by zero
KeyboardInterrupt
When the user hits the interrupt key normally Control-C during
execution of the program.
name=input('enter your name')
enter your name^c
Traceback (most recent call last):
name=input('enter your name')
KeyboardInterrupt
Exception
a. ArithmeticError
FloatingPointError
OverflowError
ZeroDivisionError
b. AttributeError
c. EOFError
d. ImportError
e. LookupError
IndexError
KeyError
f. MemoryError
g. NameError
UnboundLocalError
h. OSError
FileNotFoundError
i. TypeError
j. ValueError
k. ---(Many others)---
Syntax
Following is the basic syntax for raising built-in exception −
raise ExceptionClassName("Error message")
Example
In this example, the "divide" function attempts to divide two numbers
"a" and "b". If "b" is zero, it raises a "ZeroDivisionError" with a custom
message −
Open Compiler
def divide(a, b):
if b == 0:
raise ZeroDivisionError("Cannot divide by zero")
return a / b
try:
result = divide(10, 0)
except ZeroDivisionError as e:
print(f"Error: {e}")
Multithreading
In Python, multithreading allows you to run multiple threads
concurrently within a single process, which is also known as thread-
based parallelism. This means a program can perform multiple tasks at
the same time, enhancing its efficiency and responsiveness.
Multithreading in Python is especially useful for multiple I/O-bound
operations, rather than for tasks that require heavy computation.
Generally, a computer program sequentially executes the instructions,
from start to the end. Whereas, Multithreading divides the main task
into more than one sub-task and executes them in an overlapping
manner.
In addition to the methods, the threading module has the Thread class
that implements threading. The methods provided by the Thread class
are as follows −
run() − The run() method is the entry point for a thread.
start() − The start() method starts a thread by calling the run
method.
join([time]) − The join() waits for threads to terminate.
isAlive() − The isAlive() method checks whether a thread is
still executing.
getName() − The getName() method returns the name of a
thread.
setName() − The setName() method sets the name of a
thread.
This method call returns immediately, and the new thread starts
executing the specified function with the given arguments. When the
function returns, the thread terminates.
Example
This example demonstrates how to use the _thread module to create
and run threads. Each thread runs the print_name function with
different arguments. The time.sleep(0.5) call ensures that the main
program waits for the threads to complete their execution before
exiting.
Open Compiler
import _thread
import time
def print_name(name, *arg):
print(name, *arg)
name="Tutorialspoint..."
_thread.start_new_thread(print_name, (name, 1))
_thread.start_new_thread(print_name, (name, 1, 2))
time.sleep(0.5)
Example
The following example demonstrates how to create and start threads
using the threading module. It runs a function print_name that prints a
name along with some arguments. This example creates two threads,
starts them using the start() method, and waits for them to complete
using the join method.
Open Compiler
import threading
import time
def print_name(name, *args):
print(name, *args)
name = "Tutorialspoint..."
# Create and start threads
thread1 = threading.Thread(target=print_name, args=(name, 1))
thread2 = threading.Thread(target=print_name, args=(name, 1, 2))
thread1.start()
thread2.start()
# Wait for threads to complete
thread1.join()
thread.join()
print("Threads are finished...exiting")
Synchronising Threads
The threading module provided with Python includes a simple-to-
implement locking mechanism that allows you to synchronise threads.
A new lock is created by calling the Lock() method, which returns the
new lock.
The acquire(blocking) method of the new lock object is used to force
threads to run synchronously. The optional blocking parameter enables
you to control whether the thread waits to acquire the lock.
If blocking is set to 0, the thread returns immediately with a 0 value if
the lock cannot be acquired and with a 1 if the lock was acquired. If
blocking is set to 1, the thread blocks and waits for the lock to be
released.
The release() method of the new lock object is used to release the lock
when it is no longer required.
Example
Open Compiler
import threading
import time
class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print ("Starting " + self.name)
# Get lock to synchronise threads
threadLock.acquire()
print_time(self.name, self.counter, 3)
# Free lock to release next thread
threadLock.release()
def print_time(threadName, delay, counter):
while counter:
time.sleep(delay)
print ("%s: %s" % (threadName, time.ctime(time.time())))
counter -= 1
threadLock = threading.Lock()
threads = []
# Create new threads
thread = myThread(1, "Thread-1", 1)
thread = myThread(2, "Thread-2", 2)
# Start new Threads
thread1.start()
thread2.start()
# Add threads to thread list
threads.append(thread1)
threads.append(thread2)
# Wait for all threads to complete
for t in threads:
t.join()
print ("Exiting Main Thread")
Example
Open Compiler
import queue
import threading
import time
exitFlag = 0
class myThread (threading.Thread):
def __init__(self, threadID, name, q):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.q = q
def run(self):
print ("Starting " + self.name)
process_data(self.name, self.q)
print ("Exiting " + self.name)
def process_data(threadName, q):
while not exitFlag:
queueLock.acquire()
if not workQueue.empty():
data = q.get()
queueLock.release()
print ("%s processing %s" % (threadName, data))
else:
queueLock.release()
time.sleep(1)
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = queue.Queue(10)
threads = []
threadID = 1
# Create new threads
for tName in threadList:
thread = myThread(threadID, tName, workQueue)
thread.start()
threads.append(thread)
threadID += 1
# Fill the queue
queueLock.acquire()
for word in nameList:
workQueue.put(word)
queueLock.release()
# Wait for queue to empty
while not workQueue.empty():
pass
# Notify threads it's time to exit
exitFlag = 1
# Wait for all threads to complete
for t in threads:
t.join()
print ("Exiting Main Thread")
Output
When the above code is executed, it produces the following output −
Thread State: CREATED
Current Thread Details: <Thread(Thread-1 (func), started
140051032258112)>
Thread-1 (func) Running 0
Thread-1 (func) Running 1
Internal Thread Finished...
Current Thread Details: <Thread(Thread-2 (func), started
140051023865408)>
Thread-2 (func) Running 0
Thread-2 (func) Running 1
Thread-2 (func) Running 2
Internal Thread Finished...
Threads State: FINISHED
Main Thread Running 0
Main Thread Running 1
Main Thread Running 2
Main Thread Finished...
Output
When the above code is executed, it produces the following output −
Thread-1 has been created
Thread-1 has started working
Thread-2 has been created
Thread-2 has started working
Thread-3 has been created
Thread-4 has been created
Thread-5 has been created
Thread-1 has finished working
Thread-2 has finished working
Thread-3 has started working
Thread-1 has terminated
Thread-2 has terminated
Thread-4 has started working
Thread-3 has finished working
Thread-5 has started working
Thread-3 has terminated
Thread-4 has finished working
Thread-4 has terminated
Thread-5 has finished working
Thread-5 has terminated
Threads State: All are FINISHED
Main Thread Finished...
Creating a Thread
Creating a thread in Python involves initiating a separate flow of
execution within a program, allowing multiple operations to run
concurrently. This is particularly useful for performing tasks
simultaneously, such as handling various I/O operations in parallel.
Python provides multiple ways to create and manage threads.
Creating a thread using the threading module is generally
recommended due to its higher-level interface and additional
functionalities.
On the other hand, the _thread module offers a simpler,
lower-level approach to create and manage threads, which
can be useful for straightforward, low-overhead threading
tasks.
In this tutorial, you will learn the basics of creating threads in Python
using different approaches. We will cover creating threads using
functions, extending the Thread class from the threading module, and
utilising the _thread module.
Example
The following example demonstrates concurrent execution using
threads in Python. It creates and starts multiple threads that execute
different tasks concurrently by specifying user-defined functions as
targets within the Thread class.
Open Compiler
from threading import Thread
def addition_of_numbers(x, y):
result = x + y
print('Addition of {} + {} = {}'.format(x, y, result))
def cube_number(i):
result = i ** 3
print('Cube of {} = {}'.format(i, result))
def basic_function():
print("Basic function is running concurrently...")
Thread(target=addition_of_numbers, args=(2, 4)).start()
Thread(target=cube_number, args=(4,)).start()
Thread(target=basic_function).start()
Example
This example demonstrates how to create and manage multiple
threads using a custom MyThread class that extends the
threading.Thread class in Python.
Open Compiler
import threading
import time
exitFlag = 0
class myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print ("Starting " + self.name)
print_time(self.name, 5, self.counter)
print ("Exiting " + self.name)
def print_time(threadName, counter, delay):
while counter:
if exitFlag:
threadName.exit()
time.sleep(delay)
print ("%s: %s" % (threadName, time.ctime(time.time())))
counter -= 1
# Create new threads
thread = myThread(1, "Thread-1", 1)
thread = myThread(2, "Thread-2", 2)
# Start new Threads
thread1.start()
thread2.start()
print ("Exiting Main Thread")
This function starts a new thread and returns its identifier. The
function parameter specifies the function that the new thread will
execute. Any arguments required by this function can be passed using
args and kwargs.
Example
import _thread
import time
# Define a function for the thread
def thread_task( threadName, delay):
for count in range(1, 6):
time.sleep(delay)
print ("Thread name: {} Count: {}".format ( threadName, count ))
# Create two threads as follows
try:
_thread.start_new_thread( thread_task, ("Thread-1", 2, ) )
_thread.start_new_thread( thread_task, ("Thread-2", 4, ) )
except:
print ("Error: unable to start thread")
while True:
pass
thread_task("test", 0.3)
The program goes in an infinite loop. You will have to press ctrl-c to
stop.
Starting a Thread
In Python, starting a thread involves using the start() method provided
by the Thread class in the threading module. This method initiates the
thread's activity and automatically calls its run() method in a separate
thread of execution. Meaning that, when you call start() on each thread
object (for example., thread1, thread2, thread3) to initiate their
execution.
Python to launch separate threads that concurrently execute the run()
method defined in each Thread instance. And the main thread
continues its execution after starting the child threads.
In this tutorial, you will see a detailed explanation and example of how
to use the start() method effectively in multi-threaded programming to
understand its behaviour in multi-thread applications.
Example
Let's see the example below, which demonstrates how to start a new
thread in Python using the start() method.
Open Compiler
from threading import Thread
from time import sleep
def my_function(arg):
for i in range(arg):
print("child Thread running", i)
sleep(0.5)
thread = Thread(target = my_function, args = (10, ))
thread.start()
print("thread finished...exiting")
Example
Here is another example demonstrating the working of the start()
method. You can observe that, by not calling the start() method on
thread2, it remains inactive and does not begin execution.
Open Compiler
import threading
import time
class MyThread(threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print("Starting " + self.name)
print_time(self.name, self.counter)
print("Exiting " + self.name)
def print_time(threadName, counter):
while counter:
time.sleep(1)
print("%s: %s" % (threadName, time.ctime(time.time())))
counter -= 1
# Create new threads
thread = MyThread(1, "Thread-1", 1)
thread = MyThread(2, "Thread-2", 2)
thread = MyThread(3, "Thread-3", 3)
# Start new Threads
thread1.start()
thread 3.start()
print("Exiting Main Thread")
The above code will produce the following output −
Starting Thread-1
Starting Thread-3
Exiting Main Thread
Thread-1: Mon Jun 24 18:24:59 2024
Exiting Thread-1
Thread-3: Mon Jun 24 18:24:59 2024
Thread-3: Mon Jun 24 18:25:00 2024
Thread-3: Mon Jun 24 18:25:01 2024
Exiting Thread-3
Example
The following example demonstrates the use of join() in a
multithreaded program. It starts two threads (thread1 and thread2).
Initially, it blocks the main thread until the thread finishes executing
the my_function_1. After thread completes, thread2.start() is called,
followed by thread.join() to ensure that the main thread waits until
thread finishes executing my_function_2().
Open Compiler
from threading import Thread
from time import sleep
def my_function_1(arg):
for i in range(arg):
print("Child Thread 1 running", i)
sleep(0.5)
def my_function_2(arg):
for i in range(arg):
print("Child Thread 2 running", i)
sleep(0.1)
# Create thread objects
thread1 = Thread(target=my_function_1, args=(5,))
thread2 = Thread(target=my_function_2, args=(3,))
# Start the first thread and wait for it to complete
thread1.start()
thread1.join()
# Start the second thread and wait for it to complete
thread2.start()
thread.join()
print("Main thread finished...exiting")
Example
Here is another example that demonstrates how the join() method
with a timeout allows waiting for a thread to complete for a specified
period, then proceeding even if the thread hasn't finished.
from threading import Thread
from time import sleep
def my_function_1(arg):
for i in range(arg):
print("Child Thread 1 running", i)
sleep(0.5)
def my_function_2(arg):
for i in range(arg):
print("Child Thread 2 running", i)
sleep(0.1)
# Create thread objects
thread1 = Thread(target=my_function_1, args=(5,))
thread2 = Thread(target=my_function_2, args=(3,))
# Start the first thread and wait for 0.2 seconds
thread1.start()
thread1.join(timeout=0.2)
# Start the second thread and wait for it to complete
thread2.start()
thread.join()
print("Main thread finished...exiting")
When you run the above code, you can see the following output −
Child Thread 1 running 0
Child Thread 2 running 0
Child Thread 2 running 1
Child Thread 2 running 2
Child Thread 1 running 1
Main thread finished...exiting
Child Thread 1 running 2
Child Thread 1 running 3
Child Thread 1 running 4
Example
Here is an example demonstrating assigning custom and default names
to threads created using threading.Thread() class, and displays how
names can reflect target functions.
Open Compiler
from threading import Thread
import threading
from time import sleep
def my_function_1(arg):
print("This tread name is", threading.current_thread().name)
# Create thread objects
thread1 = Thread(target=my_function_1, name='My_thread', args=
(2,))
thread2 = Thread(target=my_function_1, args=(3,))
print("This tread name is", threading.current_thread().name)
# Start the first thread and wait for 0.2 seconds
thread1.start()
thread1.join()
# Start the second thread and wait for it to complete
thread2.start()
thread.join()
Example
This example shows how to dynamically change thread names by
modifying the name attribute of the thread object.
from threading import Thread
import threading
from time import sleep
def my_function_1(arg):
threading.current_thread().name = "custom_name"
print("This tread name is", threading.current_thread().name)
# Create thread objects
thread1 = Thread(target=my_function_1, name='My_thread', args=
(2,))
thread2 = Thread(target=my_function_1, args=(3,))
print("This tread name is", threading.current_thread().name)
# Start the first thread and wait for 0.2 seconds
thread1.start()
thread1.join()
# Start the second thread and wait for it to complete
thread2.start()
thread.join()
When you execute the above code, it will produce the following results
−
This thread name is MainThread
This tread name is custom_name
This tread name is custom_name
Example
Threads can be initialised with custom names and even renamed after
creation. This example demonstrates creating threads with custom
names and modifying a thread's name after creation.
import threading
def addition_of_numbers(x, y):
print("This Thread name is :", threading.current_thread().name)
result = x + y
def cube_number(i):
result = i ** 3
print("This Thread name is :", threading.current_thread().name)
def basic_function():
print("This Thread name is :", threading.current_thread().name)
# Create threads with custom names
t1 = threading.Thread(target=addition_of_numbers,
name='My_thread', args=(2, 4))
t2 = threading.Thread(target=cube_number, args=(4,))
t3 = threading.Thread(target=basic_function)
# Start and join threads
t1.start()
t1.join()
t2.start()
t2.join()
t3.name = 'custom_name' # Assigning name after thread creation
t3.start()
t3.join()
print(threading.current_thread().name) # Print main thread's name
Upon execution, the above code will produce the following results −
This Thread name is : My_thread
This Thread name is : Thread-1 (cube_number)
This Thread name is : custom_name
MainThread
Thread Scheduling
Thread scheduling in Python is a process of deciding which thread runs
at any given time. In a multi-threaded program, multiple threads are
executed independently, allowing for parallel execution of tasks.
However, Python does not have built-in support for controlling thread
priorities or scheduling policies directly. Instead, it relies on the
operating system's thread scheduler.
Python threads are mapped to native threads of the host operating
system, such as POSIX threads (pthreads) on Unix-like systems or
Windows threads. The operating system's scheduler manages the
execution of these threads, including context switching, thread
priorities, and scheduling policies. Python provides basic thread
scheduling capabilities through the threading.Timer class and the
sched module.
In this tutorial will learn the basics of thread scheduling in Python,
including how to use the sched module for scheduling tasks and the
threading.Timer class for delayed execution of functions.
Example
This example demonstrates how to use the threading.Timer() class to
schedule and manage the execution of tasks (custom threads) in
Python.
Open Compiler
import threading
import time
# Define the event function
def schedule_event(name, start):
now = time.time()
elapsed = int(now - start)
print('Elapsed:', elapsed, 'Name:', name)
# Start time
start = time.time()
print('START:', time.ctime(start))
# Schedule events using Timer
t1 = threading.Timer(3, schedule_event, args=('EVENT_1', start))
t2 = threading.Timer(2, schedule_event, args=('EVENT_2', start))
# Start the timers
t1.start()
t2.start()
t1.join()
t2.join()
# End time
end = time.time()
print('End:', time.ctime(end))
Example
This example demonstrates how to schedule events to run after a delay
using the sched module. It schedules two different events −
Open Compiler
import sched
import time
scheduler = sched.scheduler(time.time, time.sleep)
def schedule_event(name, start):
now = time.time()
elapsed = int(now - start)
print('elapsed=',elapsed, 'name=', name)
start = time.time()
print('START:', time.ctime(start))
scheduler.enter(2, 1, schedule_event, ('EVENT_1', start))
scheduler.enter(5, 1, schedule_event, ('EVENT_2', start))
scheduler.run()
# End time
end = time.time()
print('End:', time.ctime(end))
Example
Let's take another example to understand the concept better. This
example schedules a function to perform an addition after a 4-second
delay using the sched module in Python.
Open Compiler
import sched
from datetime import datetime
import time
def addition(a,b):
print("Performing Addition : ", datetime.now())
print("Time : ", time.monotonic())
print("Result {}+{} =".format(a, b), a+b)
s = sched.scheduler()
print("Start Time : ", datetime.now())
event1 = s.enter(4, 1, addition, argument = (5,6))
print("Event Created : ", event1)
s.run()
print("End Time : ", datetime.now())
Thread Pools
Example
This example demonstrates the parallel execution of the square and
cube functions on the list of numbers using the Python thread pool,
where each function is applied to the numbers concurrently with up to
3 threads, each with a delay of 1 second between executions.
Open Compiler
from multiprocessing.dummy import Pool as ThreadPool
import time
def square(number):
sqr = number * number
time.sleep(1)
print("Number:{} Square:{}".format(number, sqr))
def cube(number):
cub = number*number*number
time.sleep(1)
print("Number:{} Cube:{}".format(number, cub))
numbers = [1, 2, 3, 4, 5]
pool = ThreadPool(3)
pool.map(square, numbers)
pool.map(cube, numbers)
pool.close()
Output
On executing the above code you will get the following output −
Number:2 Square:4
Number:1 Square:1
Number:3 Square:9
Number:4 Square:16
Number:5 Square:25
Number:1 Cube:1
Number:2 Cube:8
Number:3 Cube:27
Number:4 Cube:64
Number:5 Cube:125
Example
Here is an example that uses the
concurrent.futures.ThreadPoolExecutor class to manage and
execute tasks asynchronously in Python. Specifically, it shows how to
submit multiple tasks to a thread pool and how to check their execution
status.
Open Compiler
from concurrent.futures import ThreadPoolExecutor
from time import sleep
def square(numbers):
for val in numbers:
ret = val*val
sleep(1)
print("Number:{} Square:{}".format(val, ret))
def cube(numbers):
for val in numbers:
ret = val*val*val
sleep(1)
print("Number:{} Cube:{}".format(val, ret))
if __name__ == '__main__':
numbers = [1,2,3,4,5]
executor = ThreadPoolExecutor(4)
thread1 = executor.submit(square, (numbers))
thread = executor.submit(cube, (numbers))
print("Thread 1 executed ? :",thread1.done())
print("Thread 2 executed ? :",thread2.done())
sleep(2)
print("Thread 1 executed ? :",thread1.done())
print("Thread 2 executed ? :",thread2.done())
Main Thread
In Python, the main thread is the initial thread that starts when the
Python interpreter is executed. It is the default thread within a Python
process, responsible for managing the program and creating additional
threads. Every Python program has at least one thread of execution
called the main thread.
The main thread by default is a non-daemon thread. In this tutorial you
will see the detailed explanation with relevant examples about the
main thread in Python programming.
Example
The threading.current_thread() function returns a threading.Thread
instance representing the current thread. Here is an example.
Open Compiler
import threading
name = 'Tutorialspoint'
print('Output:', name)
print(threading.current_thread())
Example
This example demonstrates how to use the threading.main_thread()
function to get a reference to the main thread. And it also shows the
difference between the main thread and other threads using
threading.current_thread() function.
Open Compiler
import threading
import time
def func(x):
time.sleep(x)
if not threading.current_thread() is threading.main_thread():
print('threading.current_thread() not threading.main_thread()')
t = threading.Thread(target=func, args=(0.5,))
t.start()
print(threading.main_thread())
print("Main thread finished")
When the above code is executed, it produces the following result −
<_MainThread(MainThread, started 140032182964224)>
Main thread finished
threading.current_thread() not threading.main_thread()
Example
The following example shows the main thread behaviour in a python
multithreaded program.
Open Compiler
import threading
import time
def func(x):
print('Current Thread Details:',threading.current_thread())
for n in range(x):
print('Internal Thread Running', n)
print('Internal Thread Finished...')
t = threading.Thread(target=func, args=(6,))
t.start()
for i in range(3):
print('Main Thread Running',i)
print("Main Thread Finished...")
Example
This example demonstrates how to properly manage the main thread
and ensure it does not exist before the worker threads have finished
their tasks.
Open Compiler
from threading import Thread
from time import sleep
def my_function_1():
print("Worker 1 started")
sleep(1)
print("Worker 1 done")
def my_function_2(main_thread):
print("Worker 2 waiting for Worker 1 to finish")
main_thread.join()
print("Worker 2 started")
sleep(1)
print("Worker 2 done")
worker1 = Thread(target=my_function_1)
worker2 = Thread(target=my_function_2, args=(worker1,))
worker1.start()
worker2.start()
for num in range(6):
print("Main thread is still working on task", num)
sleep(0.60)
worker1.join()
print("Main thread Completed")
Thread Priority
In Python, currently thread priority is not directly supported by the
threading module. Unlike Java, Python does not support thread
priorities, thread groups, or certain thread control mechanisms like
destroying, stopping, suspending, resuming, or interrupting threads.
Even though Python threads are designed simple and are loosely based
on Java's threading model. This is because of Python's Global
Interpreter Lock (GIL), which manages Python threads.
However, you can simulate priority-based behaviour using techniques
such as sleep durations, custom scheduling logic within threads or
using the additional module which manages task priorities.
Example
Here's a simple example to demonstrate how to customise the thread
priorities using the delays in Python threads. In this example, Thread-2
completes before Thread-1 because it has a lower priority value,
resulting in a shorter sleep time.
Open Compiler
import threading
import time
class DummyThread(threading.Thread):
def __init__(self, name, priority):
threading.Thread.__init__(self)
self.name = name
self.priority = priority
def run(self):
name = self.name
time.sleep(1.0 * self.priority)
print(f"{name} thread with priority {self.priority} is running")
# Creating threads with different priorities
t1 = DummyThread(name='Thread-1', priority=4)
t2 = DummyThread(name='Thread-2', priority=1)
# Starting the threads
t1.start()
t2.start()
# Waiting for both threads to complete
t1.join()
t2.join()
print('All Threads are executed')
Output
On executing the above program, you will get the following results −
Thread-2 thread with priority 1 is running
Thread-1 thread with priority 4 is running
All Threads are executed
Example
This example demonstrates how to manually set the priority of threads
in Python on a Windows system using the ctypes module.
import threading
import ctypes
import time
# Constants for Windows API
w32 = ctypes.windll.kernel32
SET_THREAD = 0x20
PRIORITIZE_THE_THREAD = 1
class MyThread(threading.Thread):
def __init__(self, start_event, name, iterations):
super().__init__()
self.start_event = start_event
self.thread_id = None
self.iterations = iterations
self.name = name
def set_priority(self, priority):
if not self.is_alive():
print('Cannot set priority for a non-active thread')
return
thread_handle = w32.OpenThread(SET_THREAD, False,
self.thread_id)
success = w32.SetThreadPriority(thread_handle, priority)
w32.CloseHandle(thread_handle)
if not success:
print('Failed to set thread priority:', w32.GetLastError())
def run(self):
self.thread_id = w32.GetCurrentThreadId()
self.start_event.wait()
while self.iterations:
print(f"{self.name} running")
start_time = time.time()
while time.time() - start_time < 1:
pass
self.iterations -= 1
# Create an event to synchronise thread start
start_event = threading.Event()
# Create threads
thread_normal = MyThread(start_event, name='normal', iterations=4)
thread_high = MyThread(start_event, name='high', iterations=4)
# Start the threads
thread_normal.start()
thread_high.start()
# Adjusting priority of 'high' thread
thread_high.set_priority(PRIORITIZE_THE_THREAD)
# Trigger thread execution
start_event.set()
Output
While executing this code in your Python interpreter, you will get the
following results −
high running
normal running
high running
normal running
high running
normal running
high running
normal running
Example
This example demonstrates the use of the PriorityQueue class in the
queue module to manage task priorities between the two threads.
Open Compiler
from time import sleep
from random import random, randint
from threading import Thread
from queue import PriorityQueue
queue = PriorityQueue()
def producer(queue):
print('Producer: Running')
for i in range(5):
# create item with priority
value = random()
priority = randint(0, 5)
item = (priority, value)
queue.put(item)
# wait for all items to be processed
queue.join()
queue.put(None)
print('Producer: Done')
define consumer(queue):
print('Consumer: Running')
while True:
# get a unit of work
item = queue.get()
if item is None:
break
sleep(item[1])
print(item)
queue.task_done()
print('Consumer: Done')
producer = Thread(target=producer, args=(queue,))
producer.start()
consumer = Thread(target=consumer, args=(queue,))
consumer.start()
producer.join()
consumer.join()
Output
On execution, It will produce the following output −
Producer: Running
Consumer: Running
(0, 0.15332707626852804)
(2, 0.4730737391435892)
(2, 0.8679231358257962)
(3, 0.051924220435665025)
(4, 0.23945882716108446)
Producer: Done
Consumer: Done
Daemon Threads
Daemon threads in Python are useful for running background tasks that
are not critical to the program's operation. They allow you to run tasks
in the background without worrying about keeping track of them.
Python provides two types of threads: non-daemon and daemon
threads. By default, threads are non-daemon threads. This tutorial
provides a detailed explanation with relevant examples about daemon
threads in Python programming.
Example
Take a look at the following example to create a daemon thread and
check whether the thread is daemonic or not using the daemon
attribute.
Open Compiler
import threading
from time import sleep
# function to be executed in a new thread
def run():
# get the current thread
thread = threading.current_thread()
# Is it a daemon thread?
print(Daemon thread: {thread.daemon}')
# Create a new thread and set it as daemon
thread = threading.Thread(target=run, daemon=True)
# start the thread
thread.start()
print('Is Main Thread is Daemon thread:',
threading.current_thread().daemon)
# Block for a short time to allow the daemon thread to run
sleep(0.5)
Example
Here is an example −
Open Compiler
import threading
from time import sleep
# function to be executed in a new thread
def run():
# get the current thread
thread = threading.current_thread()
# Is it a daemon thread?
print(Daemon thread: {thread.daemon}')
# Create a new thread
thread = threading.Thread(target=run)
# Using the daemon property set the thread as daemon before starting
the thread
thread.daemon = True
# start the thread
thread.start()
print('Is Main Thread is Daemon thread:',
threading.current_thread().daemon)
# Block for a short time to allow the daemon thread to run
sleep(0.5)
Example
Here is another example that demonstrates getting the RuntimeError
when you try to set the daemon status of a thread after starting it.
Open Compiler
from time import sleep
from threading import current_thread
from threading import Thread
# function to be executed in a new thread
def run():
# get the current thread
thread = current_thread()
# Is it a daemon thread?
print(Daemon thread: {thread.daemon}')
thread.daemon = True
# create a new thread
thread = Thread(target=run)
# start the new thread
thread.start()
# block for a 0.5 sec for daemon thread to run
sleep(0.5)
Synchronising Threads
In Python, when multiple threads are working concurrently with shared
resources, it's important to synchronise their access to maintain data
integrity and program correctness. Synchronising threads in python can
be achieved using various synchronisation primitives provided by the
threading module, such as locks, conditions, semaphores, and barriers
to control access to shared resources and coordinate the execution of
multiple threads.
In this tutorial, we'll learn about various synchronisation primitives
provided by Python's threading module.
Example
The following example demonstrates how to use locks (the
threading.Lock() method) to synchronise threads in Python, ensuring
that multiple threads access shared resources safely and correctly.
Open Compiler
import threading
counter = 10
def increment(theLock, N):
global counter
for i in range(N):
theLock.acquire()
counter += 1
theLock.release()
lock = threading.Lock()
t1 = threading.Thread(target=increment, args=[lock, 2])
t2 = threading.Thread(target=increment, args=[lock, 10])
t3 = threading.Thread(target=increment, args=[lock, 4])
t1.start()
t2.start()
t3.start()
# Wait for all threads to complete
for thread in (t1, t2, t3):
thread.join()
print("All threads have completed")
print("The Final Counter Value:", counter)
Output
When the above code is executed, it produces the following output −
All threads have completed
The Final Counter Value: 26
Example
This example demonstrates how Condition objects can synchronise
threads using the notify() and wait() methods.
Open Compiler
import threading
counter = 0
# Consumer function
define consumer(cv):
global counter
with cv:
print("Consumer is waiting")
cv.wait() # Wait until notified by increment
print("Consumer has been notified. Current Counter value:",
counter)
# increment function
def increment(cv, N):
global counter
with cv:
print("increment is producing items")
for i in range(1, N + 1):
counter += i # Increment counter by i
# Notify the consumer
cv.notify()
print("Increment has finished")
# Create a Condition object
cv = threading.Condition()
# Create and start threads
consumer_thread = threading.Thread(target=consumer, args=[cv])
increment_thread = threading.Thread(target=increment, args=[cv, 5])
consumer_thread.start()
increment_thread.start()
consumer_thread.join()
increment_thread.join()
print("The Final Counter Value:", counter)
Output
On executing the above program, it will produce the following output −
Consumer is waiting
increment is producing items
Increment has finished
Consumers have been notified. Current Counter value: 15
The Final Counter Value: 15
Example
This demonstrates synchronisation of threads using the join() method
to ensure that the main thread waits for all started threads to complete
their work before proceeding.
Open Compiler
import threading
import time
class MyThread(threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.counter = counter
def run(self):
print("Starting " + self.name)
print_time(self.name, self.counter, 3)
def print_time(threadName, delay, counter):
while counter:
time.sleep(delay)
print("%s: %s" % (threadName, time.ctime(time.time())))
counter -= 1
threads = []
# Create new threads
thread = MyThread(1, "Thread-1", 1)
thread = MyThread(2, "Thread-2", 2)
# Start the new Threads
thread1.start()
thread2.start()
# Join the threads
thread1.join()
thread.join()
print("Exiting Main Thread")
Output
On executing the above program, it will produce the following output −
Starting Thread-1
Starting Thread-2
Thread-1: Mon Jul 1 16:05:14 2024
Thread-2: Mon Jul 1 16:05:15 2024
Thread-1: Mon Jul 1 16:05:15 2024
Thread-1: Mon Jul 1 16:05:16 2024
Thread-2: Mon Jul 1 16:05:17 2024
Thread-2: Mon Jul 1 16:05:19 2024
Exiting Main Thread
Inter-Thread Communication
Inter-Thread Communication refers to the process of enabling
communication and synchronisation between threads within a Python
multi-threaded program.
Generally, threads in Python share the same memory space within a
process, which allows them to exchange data and coordinate their
activities through shared variables, objects, and specialised
synchronisation mechanisms provided by the threading module.
To facilitate inter-thread communication, the threading module provides
various synchronisation primitives like, Locks, Events, Conditions, and
Semaphores objects. In this tutorial you will learn how to use the Event
and Condition object for providing the communication between threads
in a multi-threaded program.
Example
The following code attempts to simulate the traffic flow being
controlled by the state of traffic signal either GREEN or RED.
There are two threads in the program, targeting two different functions.
The signal_state() function periodically sets and resets the event
indicating change of signal from GREEN to RED.
The traffic_flow() function waits for the event to be set, and runs a loop
till it remains set.
Open Compiler
from threading import Event, Thread
import time
terminate = False
def signal_state():
global terminate
while not terminate:
time.sleep(0.5)
print("Traffic Police Giving GREEN Signal")
event.set()
time.sleep(1)
print("Traffic Police Giving RED Signal")
event.clear()
def traffic_flow():
global terminate
num = 0
while num < 10 and not terminate:
print("Waiting for GREEN Signal")
event.wait()
print("GREEN Signal ... Traffic can move")
while event.is_set() and not terminate:
num += 1
print("Vehicle No:", num," Crossing the Signal")
time.sleep(1)
print("RED Signal ... Traffic has to wait")
event = Event()
t1 = Thread(target=signal_state)
t2 = Thread(target=traffic_flow)
t1.start()
t2.start()
# Terminate the threads after some time
time.sleep(5)
terminate = True
# join all threads to complete
t1.join()
t2.join()
print("Exiting Main Thread")
Output
On executing the above code you will get the following output −
Waiting for GREEN Signal
Traffic Police Giving GREEN Signal
GREEN Signal ... Traffic can move
Vehicle No: 1 Crossing the Signal
Traffic Police Giving RED Signal
RED Signal ... Traffic has to wait
Waiting for GREEN Signal
Traffic Police Giving GREEN Signal
GREEN Signal ... Traffic can move
Vehicle No: 2 Crossing the Signal
Vehicle No: 3 Crossing the Signal
Traffic Police Giving RED Signal
Traffic Police Giving GREEN Signal
Vehicle No: 4 Crossing the Signal
Traffic Police Giving RED Signal
RED Signal ... Traffic has to wait
Traffic Police Giving GREEN Signal
Traffic Police Giving RED Signal
Exiting Main Thread
Example
This example demonstrates a simple form of inter-thread
communication using the Condition object of Python's threading
module. Here thread_a and thread_b are communicated using a
Condition object, the thread_a waits until it receives a notification from
thread_b. the thread_b sleeps for 2 seconds before notifying
thread_a and then finishes.
Open Compiler
from threading import Condition, Thread
import time
c = Condition()
def thread_a():
print("Thread A started")
with c:
print("Thread A waiting for permission...")
c.wait()
print("Thread A got permission!")
print("Thread A finished")
def thread_b():
print("Thread B started")
with c:
time.sleep(2)
print("Notifying Thread A...")
c.notify()
print("Thread B finished")
Thread(target=thread_a).start()
Thread(target=thread_b).start()
Output
On executing the above code you will get the following output −
Thread A started
Thread A waiting for permission...
Thread B started
Notifying Thread A...
Thread B finished
Thread A got permission!
Thread A finished
Example
Here is another code demonstrating how the Condition object is used
for providing the communication between threads. In this, the thread t2
runs the taskB() function, and the thread t1 runs the taskA() function.
The t1 thread acquires the condition and notifies it.
By that time, the t2 thread is in a waiting state. After the condition is
released, the waiting thread proceeds to consume the random number
generated by the notifying function.
Open Compiler
from threading import Condition, Thread
import time
import random
numbers = []
def taskA(c):
for _ in range(5):
with c:
num = random.randint(1, 10)
print("Generated random number:", num)
numbers.append(num)
print("Notification issued")
c.notify()
time.sleep(0.3)
def taskB(c):
for i in range(5):
with c:
print("waiting for update")
while not numbers:
c.wait()
print("Obtained random number", numbers.pop())
time.sleep(0.3)
c = Condition()
t1 = Thread(target=taskB, args=(c,))
t2 = Thread(target=taskA, args=(c,))
t1.start()
t2.start()
t1.join()
t2.join()
print("Done")
When you execute this code, it will produce the following output −
waiting for update
Generated random number: 2
Notification issued
Obtained random number 2
Generated random number: 5
Notification issued
waiting for update
Obtained random number 5
Generated random number: 1
Notification issued
waiting for update
Obtained random number 1
Generated random number: 9
Notification issued
waiting for update
Obtained random number 9
Generated random number: 2
Notification issued
waiting for update
Obtained random number 2
Done
Thread Deadlock
A deadlock may be described as a concurrency failure mode. It is a
situation in a program where one or more threads wait for a condition
that never occurs. As a result, the threads are unable to progress and
the program is stuck or frozen and must be terminated manually.
Deadlock situations may arise in many ways in your concurrent
program. Deadlocks are never not developed intentionally, instead,
they are in fact a side effect or bug in the code.
Common causes of thread deadlocks are listed below −
1. A thread that attempts to acquire the same mutex lock twice.
2. Threads that wait on each other (e.g. A waits on B, B waits on
A).
3. When a thread that fails to release a resource such as lock,
semaphore, condition, event, etc.
4. Threads that acquire mutex locks in different orders (e.g. fail
to perform lock ordering).
Where,
blocking − If set to False, it means do not block. If a call with
blocking set to True would block, return False immediately;
otherwise, set the lock to locked and return True.
timeout − Specifies a timeout period for acquiring the lock.
Example
In the following program, two threads try to call the synchronised()
method. One of them acquires the lock and gains the access while the
other waits. When the run() method is completed for the first thread,
the lock is released and the synchronised method is available for the
second thread.
When both the threads join, the program comes to an end.
from threading import Thread, Lock
import time
lock=Lock()
threads=[]
class myThread(Thread):
def __init__(self,name):
Thread.__init__(self)
self.name=name
def run(self):
lock.acquire()
synchronised(self.name)
lock.release()
define synchronised(threadName):
print ("{} has acquired lock and is running synchronised
method".format(threadName))
counter=5
while counter:
print ('**', end='')
time.sleep(2)
counter=counter-1
print('\block released for', threadName)
t1=myThread('Thread1')
t2=myThread('Thread2')
t1.start()
threads.append(t1)
t2.start()
threads.append(t2)
for t in threads:
t.join()
print ("end of main thread")
Interrupting a Thread
Example
In this example, we have a MyThread class. Its object starts executing
the run() method. The main thread sleeps for a certain period and then
sets an event. Till the event is detected, the loop in the run() method
continues. As soon as the event is detected, the loop terminates.
Open Compiler
from time import sleep
from threading import Thread
from threading import Event
class MyThread(Thread):
def __init__(self, event):
super(MyThread, self).__init__()
self.event = event
def run(self):
i=0
while True:
i+=1
print ('Child thread running...',i)
sleep(0.5)
if self.event.is_set():
break
print()
print('Child Thread Interrupted')
event = Event()
thread = MyThread(event)
thread1.start()
sleep(3)
print('Main thread stopping child thread')
event.set()
thread1.join()
When you execute this code, it will produce the following output −
Child thread running... 1
Child thread running... 2
Child thread running... 3
Child thread running... 4
Child thread running... 5
Child thread running... 6
Main thread stopping child thread
Child Thread Interrupted
Example
This example demonstrates how to use a flag to control and stop a
running thread in a Python multithreaded program.
Open Compiler
import threading
import time
def foo():
t = threading.current_thread()
while getattr(t, "do_run", True):
print("working on a task")
time.sleep(1)
print("Stopping the Thread after some time.")
# Create a thread
t = threading.Thread(target=foo)
t.start()
# Allow the thread to run for 5 seconds
time.sleep(5)
# Set the termination flag to stop the thread
t.do_run = False
When you execute this code, it will produce the following output −
working on a task
working on a task
working on a task
working on a task
working on a task
Stopping the Thread after some time.
Network Programming
The threading module in Python's standard library is capable of
handling multiple threads and their interaction within a single process.
Communication between two processes running on the same machine
is handled by Unix domain sockets, whereas for the processes running
on different machines connected with TCP (Transmission control
protocol), Internet domain sockets are used.
Python's standard library consists of various built-in modules that
support interprocess communication and networking. Python provides
two levels of access to the network services. At a low level, you can
access the basic socket support in the underlying operating system,
which allows you to implement clients and servers for both connection-
oriented and connectionless protocols.
Python also has libraries that provide higher-level access to specific
application-level network protocols, such as FTP, HTTP, and so on.
Syntax
The following is the syntax of socket.socket() constructor –
socket.socket (socket_family, socket_type, protocol=0)
Parameters
family − AF_INET by default. Other values - AF_INET6 (eight
groups of four hexadecimal digits), AF_UNIX, AF_CAN
(Controller Area Network) or AF_RDS (Reliable Datagram
Sockets).
socket_type − should be SOCK_STREAM (the default),
SOCK_DGRAM, SOCK_RAW or perhaps one of the other SOCK_
constants.
protocol − number is usually zero and may be omitted.
Return Type
This method returns a socket object.
Once you have the socket object, then you can use the required
methods to create your client or server program.
connect() method
This method takes a two-item tuple object as argument. The two items
are IP address and port number of the server.
obj=socket.socket()
obj.connect((host,port))
Once the connection is accepted by the server, both the socket objects
can send and/or receive data.
send() method
The server sends data to the client by using the address it has
intercepted.
client.send(bytes)
sendall() method
similar to send(). However, unlike send(),this method continues to send
data from bytes until either all data has been sent or an error occurs.
None is returned on success.
sendto() method
This method is to be used in case of UDP protocol only.
recv() method
This method is used to retrieve data sent to the client. In the case of a
server, it uses the remote socket whose request has been accepted.
client.recv(bytes)
recvfrom() method
This method is used in the case of the UDP protocol.
Change host string in both the server and client codes with IPv4
Address value and run them as before.
Server Code
The code for establishing connection is the same as before. After the
connection request is accepted, a file on server is opened in binary
mode for reading, and bytes are successively read and sent to the
client stream till end of file is reached.
import socket
host = "127.0.0.1"
port = 5001
server = socket.socket()
server.bind((host, port))
server.listen()
conn, addr = server.accept()
data = conn.recv(1024).decode()
filename='test.txt'
f = open(filename,'rb')
while True:
l = f.read(1024)
if not l:
break
conn.send(l)
print('Sent ',repr(l))
f.close()
print('File transferred')
conn.close()
Client Code
On the client side, a new file is opened in wb mode. The stream of data
received from the server is written to the file. As the stream ends, the
output file is closed. A new file will be created on the client machine.
import socket
s = socket.socket()
host = "127.0.0.1"
port = 5001
s.connect((host, port))
s.send("Hello server!".encode())
with open('recv.txt', 'wb') as f:
while True:
print('receiving data...')
data = s.recv(1024)
if not data:
break
f.write(data)
f.close()
print('Successfully received')
s.close()
print('connection closed')
Server Code
You must write a RequestHandler class. It is instantiated once per
connection to the server, and must override the handle() method to
implement communication to the client.
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):
def handle(self):
self.data = self.request.recv(1024).strip()
host,port=self.client_address
print("{}:{} wrote:".format(host,port))
print(self.data.decode())
msg=input("enter text .. ")
self.request.sendall(msg.encode())
Client Code
When working with socketserver, the client code is more or less similar
with the socket client application.
import socket
import sys
HOST, PORT = "localhost", 9999
while True:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
# Connect to server and send data
sock.connect((HOST, PORT))
data = input("enter text .. .")
sock.sendall(bytes(data + "\n", "utf-8"))
Run the server code in one command prompt terminal. Open multiple
terminals for client instances. You can simulate a concurrent
communication between the server and more than one client.
urlparse(urlstring)
Parse a URL into six components, returning a 6-item named tuple. Each
tuple item is a string corresponding to following attributes −
passwor Password
d
Example
Open Compiler
from urllib.parse import urlparse
url = "https://example.com/employees/name/?salary>=25000"
parsed_url = urlparse(url)
print (type(parsed_url))
print ("Scheme:",parsed_url.scheme)
print ("netloc:", parsed_url.netloc)
print ("path:", parsed_url.path)
print ("params:", parsed_url.params)
print ("Query string:", parsed_url.query)
print ("Fragment:", parsed_url.fragment)
parse_qs(qs))
This function Parses a query string given as a string argument. Data is
returned as a dictionary. The dictionary keys are the unique query
variable names and the values are lists of values for each name.
To further fetch the query parameters from the query string into a
dictionary, use parse_qs() function of the query attribute of ParseResult
object as follows −
Example
Open Compiler
from urllib.parse import urlparse, parse_qs
url = "https://example.com/employees?name=Anand&salary=25000"
parsed_url = urlparse(url)
dct = parse_qs(parsed_url.query)
print ("Query parameters:", dct)
urlsplit(urlstring)
This is similar to urlparse(), but does not split the params from the URL.
This should generally be used instead of urlparse() if the more recent
URL syntax allowing parameters to be applied to each segment of the
path portion of the URL is wanted.
urlunparse(parts)
This function is the opposite of the urlparse() function. It constructs a
URL from a tuple as returned by urlparse(). The parts argument can be
any six-item iterable. This returns an equivalent URL.
Example
Open Compiler
from urllib.parse import urlparse
lst = ['https', 'example.com', '/employees/name/', '', 'salary>=25000',
'']
new_url = urlparse(lst)
print ("URL:", new_url)
urlunsplit(parts)
Combine the elements of a tuple as returned by urlsplit() into a
complete URL as a string. The parts argument can be any five-item
iterable.
urlopen() function
This function opens the given URL, which can be either a string or a
Request object. The optional timeout parameter specifies a timeout in
seconds for blocking operations This actually only works for HTTP,
HTTPS and FTP connections.
This function always returns an object which can work as a context
manager and has the properties url, headers, and status. For HTTP and
HTTPS URLs, this function returns a http.client.HTTPResponse object
slightly modified.
Example
The following code uses urlopen() function to read the binary data from
an image file, and writes it to a local file. You can open the image file
on your computer using any image viewer.
from urllib.request import urlopen
obj = urlopen("https://www.tutorialspoint.com/images/logo.png")
data = obj.read()
img = open("img.jpg", "wb")
img.write(data)
img.close()
Syntax
urllib.request.Request(url, data, headers, origin_req_host,
method=None)
Parameters
1. url − A string that is a valid URL
2. data − An object specifying additional data to send to the
server. This parameter can only be used with HTTP requests.
Data may be bytes, file-like objects, and iterables of bytes-like
objects.
3. headers − Should be a dictionary of headers and their
associated values.
4. origin_req_host − Should be the request-host of the origin
transaction
5. method − should be a string that indicates the HTTP request
method. One of GET, POST, PUT, DELETE and other HTTP
verbs. Default is GET.
Example
from urllib.request import Request
obj = Request("https://www.tutorialspoint.com/")
Sending Data
If you define a data argument to the Request constructor, a POST
request will be sent to the server. The data should be any object
represented in bytes.
from urllib.request import Request, urlopen
from urllib.parse import urlencode
values = {'name': 'Madhu',
'location': 'India',
'language': 'Hindi' }
data = urlencode(values).encode('utf-8')
obj = Request("https://example.com", data)
Sending Headers
The Request constructor also accepts header arguments to push
header information into the request. It should be in a dictionary object.
headers = {'User-Agent': user_agent}
obj = Request("https://example.com", data, headers)
URLError
URLError is raised because there is no network connection (no route to
the specified server), or the specified server doesn't exist. In this case,
the exception raised will have a 'reason' attribute.
Example
from urllib.request import Request, urlopen
import urllib.error as err
obj = Request("http://www.nosuchserver.com")
try:
urlopen(obj)
except err.URLError as e:
print(e)
HTTPError
Every time the server sends a HTTP response it is associated with a
numeric "status code". It code indicates why the server is unable to
fulfil the request. The default handlers will handle some of these
responses for you. For those it can't handle, the urlopen() function
raises an HTTPError. Typical examples of HTTPErrors are '404' (page not
found), '403' (request forbidden), and '401' (authentication required).
Example
from urllib.request import Request, urlopen
import urllib.error as err
obj = Request("http://www.python.org/fish.html")
try:
urlopen(obj)
except err.HTTPError as e:
print(e.code)
Generics
In Python, generics is a mechanism with which you define functions,
classes, or methods that can operate on multiple types while
maintaining type safety. With the implementation of Generics enable it
is possible to write reusable code that can be used with different data
types. It ensures promoting code flexibility and type correctness.
Normally, in Python programming, you don't need to declare a variable
type. The type is determined dynamically by the value assigned to it.
Python's interpreter doesn't perform type checks and hence it may
raise runtime exceptions.
Python introduced generics with type hints in version 3.5, allowing you
to specify the expected types of variables, function arguments, and
return values. This feature helps in reducing runtime errors and
improving code readability.
Generics extend the concept of type hints by introducing type
variables, which represent generic types that can be replaced with
specific types when using the generic function or class.
Python Miscellaneous
Example
Open Compiler
import time # This is required to include a time module.
ticks = time.time()
print ("Number of ticks since 12:00 am, January 1, 1970:", ticks)
What is TimeTuple?
Many of the Python's time functions handle time as a tuple of 9
numbers, as shown below −
1 Month 1 to 12
2 Day 1 to 31
3 Hour 0 to 23
4 Minute 0 to 59
For example,
>>>import time
>>> print (time.localtime())
0 tm_year 2016
1 tm_mon 1 to 12
2 tm_mday 1 to 31
3 tm_hour 0 to 23
4 tm_min 0 to 59
6 tm_wday 0 to 6 (0 is Monday)
1 time.altzone
The offset of the local DST timezone, in seconds west of UTC, if
one is defined. This is negative if the local DST timezone is
east of UTC (as in Western Europe, including the UK). Only use
this if daylight is nonzero.
2 time.asctime([tupletime])
Accepts a time-tuple and returns a readable 24-character
string such as 'Tue Dec 11 18:07:14 2008'.
3 time.clock( )
Returns the current CPU time as a floating-point number of
seconds. To measure computational costs of different
approaches, the value of time.clock is more useful than that of
time.time().
4 time.ctime([secs])
Like asctime(localtime(secs)) and without arguments is like
asctime( )
5 time.gmtime([secs])
Accepts an instant expressed in seconds since the epoch and
returns a time-tuple t with the UTC time. Note : t.tm_isdst is
always 0
6 time.localtime([secs])
Accepts an instant expressed in seconds since the epoch and
returns a time-tuple t with the local time (t.tm_isdst is 0 or 1,
depending on whether DST applies to instant secs by local
rules).
7 time.mktime(tupletime)
Accepts an instant expressed as a time-tuple in local time and
returns a floating-point value with the instant expressed in
seconds since the epoch.
8 time.sleep(secs)
Suspends the calling thread for seconds.
9 time.strftime(fmt[,tupletime])
Accepts an instant expressed as a time-tuple in local time and
returns a string representing the instant as specified by string
fmt.
11 time.time( )
Returns the current time instant, a floating-point number of
seconds since the epoch.
12 time.tzset()
Resets the time conversion rules used by the library routines.
The environment variable TZ specifies how this is done.
2 time.tzname
Attribute time.tzname is a pair of locale-dependent strings,
which are the names of the local time zone without and with
DST, respectively.
1 calendar.calendar(year,w=2,l=1,c=6)
Returns a multiline string with a calendar for year formatted
into three columns separated by c spaces. w is the width in
characters of each date; each line has length 21*w+18+2*c. l
is the number of lines for each week.
2 calendar.firstweekday( )
Returns the current setting for the weekday that starts each
week. By default, when the calendar is first imported, this is 0,
meaning Monday.
3 calendar.isleap(year)
Returns True if year is a leap year; otherwise, False.
4 calendar.leap days(y1,y2)
Returns the total number of leap days in the years within
range(y1,y2).
5 calendar.month(year,month,w=2,l=1)
Returns a multiline string with a calendar for month month of
year year, one line per week plus two header lines. w is the
width in characters of each date; each line has length 7*w+6. l
is the number of lines for each week.
6 calendar.monthcalendar(year,month)
Returns a list of lists of ints. Each sublist denotes a week. Days
outside the month of the year are set to 0; days within the
month are set to their day-of-month, 1 and up.
7 calendar.monthrange(year,month)
Returns two integers. The first one is the code of the weekdays
for the first day of the month in a year; the second one is the
number of days in the month. Weekday codes are 0 (Monday)
to 6 (Sunday); month numbers are 1 to 12.
8 calendar.prcal(year,w=2,l=1,c=6)
Like print calendar.calendar(year,w,l,c).
9 calendar.prmonth(year,month,w=2,l=1)
Like print calendar.month(year,month,w,l).
10 calendar.setfirstweekday(weekday)
Sets the first day of each week to weekday code weekday.
Weekday codes are 0 (Monday) to 6 (Sunday).
11 calendar.timegm(tupletime)
The inverse of time.gmtime: accepts a time instant in time-
tuple form and returns the same instant as a floating-point
number of seconds since the epoch.
12 calendar.weekday(year,month,day)
Returns the weekday code for the given date. Weekday codes
are 0 (Monday) to 6 (Sunday); month numbers are 1 (January)
to 12 (December).
Syntax
datetime.date(year, month, day)
Example
Open Compiler
from datetime import date
date1 = date(2023, 4, 19)
print("Date:", date1)
date2 = date(2023, 4, 31)
Example
Open Compiler
from datetime import date
# Getting min date
mindate = date.min
print("Minimum Date:", mindate)
# Getting max date
maxdate = date.max
print("Maximum Date:", maxdate)
Date1 = date(2023, 4, 20)
print("Year:", Date1.year)
print("Month:", Date1.month)
print("Day:", Date1.day)
Example
from datetime import date
print (date.today())
d1=date.from isoformat('2023-04-20')
print (d1)
d2=date.from isoformat('20230420')
print (d2)
d3=date.from isoformat('2023-W16-4')
print (d3)
Example
Open Compiler
from datetime import date
d = date.fromordinal(738630) # 738630th day after 1. 1. 0001
print (d)
print (d.timetuple())
# Methods related to formatting string output
print (d.isoformat())
print (d.strftime("%d/%m/%y"))
print (d.strftime("%A %d. %B %Y"))
print (d.ctime())
print ('The {1} is {0:%d}, the {2} is {0:%B}.'.format(d, "day",
"month"))
# Methods for to extracting 'components' under different calendars
t = d.timetuple()
for i in t:
print(i)
ic = d.isocalendar()
for i in ic:
print(i)
# A date object is immutable; all operations produce a new object
print (d.replace(month=5))
Syntax
datetime.time(hour=0, minute=0, second=0, microsecond=0,
tzinfo=None)
Example
Open Compiler
from datetime import time
time1 = time(8, 14, 36)
print("Time:", time1)
time2 = time(minute = 12)
print("time", time2)
time3 = time()
print("time", time3)
time4 = time(hour = 26)
Class attributes
time.min − The earliest representable time, time(0, 0, 0, 0).
time.max − The latest representable time, time(23, 59, 59,
999999).
time.resolution − The smallest possible difference between
non-equal time objects.
Example
Open Compiler
from datetime import time
print(time.min)
print(time.max)
print (time.resolution)
Instance attributes
time.hour − In range(24)
time.minute − In range(60)
time.second − In range(60)
time.microsecond − In range(1000000)
time.tzinfo − the tzinfo argument to the time constructor, or
None.
Example
Open Compiler
from datetime import time
t = time(8,23,45,5000)
print(t.hour)
print(t.minute)
print (t.second)
print (t.microsecond)
Syntax
datetime.datetime(year, month, day, hour=0, minute=0, second=0,
microsecond=0, tzinfo=None, *, fold=0)
Example
Open Compiler
from datetime import datetime
dt = datetime(2023, 4, 20)
print(dt)
dt = datetime(2023, 4, 20, 11, 6, 32, 5000)
print(dt)
Class attributes
datetime.min − The earliest representable datetime,
datetime(MINYEAR, 1, 1, tzinfo=None).
datetime.max − The latest representable datetime,
datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, tzinfo=None).
datetime.resolution − The smallest possible difference
between non-equal datetime objects,
timedelta(microseconds=1).
Example
Open Compiler
from datetime import datetime
min = datetime.min
print("Min DateTime ", min)
max = datetime.max
print("Max DateTime ", max)
Example
Open Compiler
from datetime import datetime
dt = datetime.now()
print("Day: ", dt.day)
print("Month: ", dt.month)
print("Year: ", dt.year)
print("Hour: ", dt.hour)
print("Minute: ", dt.minute)
print("Second: ", dt.second)
Example
Open Compiler
from datetime import datetime, date, time, timezone
# Using datetime.combine()
d = date(2022, 4, 20)
t = time(12, 30)
datetime.combine(d, t)
# Using datetime.now()
d = datetime.now()
print (d)
# Using datetime.strptime()
dt = datetime.strptime("23/04/20 16:30", "%d/%m/%y %H:%M")
# Using datetime.timetuple() to get tuple of all attributes
tt = dt.timetuple()
for it in tt:
print(it)
# Date in ISO format
ic = dt.isocalendar()
for it in ic:
print(it)
Syntax
datetime.timedelta(days=0, seconds=0, microseconds=0,
milliseconds=0, minutes=0, hours=0, weeks=0)
Internally, the attributes are stored in days, seconds and microseconds.
Other arguments are converted to those units −
A millisecond is converted to 1000 microseconds.
A minute is converted to 60 seconds.
An hour is converted to 3600 seconds.
A week is converted to 7 days.
While days, seconds and microseconds are then normalised so that the
representation is unique.
Example
The following example shows that Python internally stores days,
seconds and microseconds only.
Open Compiler
from datetime import timedelta
delta = timedelta(
days=100,
seconds=27,
microseconds=10,
milliseconds=29000,
minutes=5,
hours=12,
weeks=2
)
# Only days, seconds, and microseconds remain
print (delta)
Example
The following example shows how to add a timedelta object to a
datetime object.
Open Compiler
from datetime import datetime, timedelta
date1 = datetime.now()
date2= date1+timedelta(days = 4)
print("Date after 4 days:", date2)
date3 = date1-timedelta(15)
print("Date before 15 days:", date3)
Example
Open Compiler
from datetime import timedelta
# Getting minimum value
min = timedelta.min
print("Minimum value:", min)
max = timedelta.max
print("Maximum value", max)
Example
Open Compiler
from datetime import timedelta
year = timedelta(days=365)
years = 5 * year
print (years)
print (years.days // 365)
646
year_1 = years // 5
print(year_1.days)
maths Module
Python maths Module
The maths module is a built-in module in Python that is used for
performing mathematical operations. This module provides various
built-in methods for performing different mathematical tasks.
Note: The maths module's methods do not work with complex
numbers. For that, you can use the cmath module.
1 math.ceil(x)
The ceiling of x: the smallest integer not less than x
2 math.comb(n,k)
This function is used to find the number of ways to choose "x"
items from "y" items without repetition and without order.
3 math.copysign(x, y)
This function returns a float with the magnitude (absolute
value) of x but the sign of y.
4 math.cmp(x, y)
This function is used to compare the values of to objects. This
function is deprecated in Python3.
5 math.fabs(x)
This function is used to calculate the absolute value of a given
integer.
6 math.factorial(n)
This function is used to find the factorial of a given integer.
7 math.floor(x)
This function calculates the floor value of a given integer.
8 math.fmod(x, y)
The fmod() function in the maths module returns the same
result as the "%" operator. However fmod() gives a more
accurate result of modulo division than modulo operator.
9 math.frexp(x)
This function is used to calculate the mantissa and exponent
of a given number.
10 math.fsum(iterable)
This function returns the floating point sum of all numeric
items in an iterable i.e. list, tuple, array.
11 math.gcd(*integers)
This function is used to calculate the greatest common divisor
of all the given integers.
12 math.isclose()
This function is used to determine whether two given numeric
values are close to each other.
13 math.isfinite(x)
This function is used to determine whether the given number
is a finite number.
14 math.isinf(x)
This function is used to determine whether the given value is
infinity (+ve or, -ve).
15 math.isnan(x)
This function is used to determine whether the given number
is "NaN".
16 math.sqrt(n)
This function calculates the integer square-root of the given
non negative integer.
17 math.lcm(*integers)
This function is used to calculate the least common factor of
the given integer arguments.
18 math.ldexp(x, i)
This function returns the product of the first number with the
exponent of the second number. So, ldexp(x,y) returns x*2**y.
This is the inverse of the frexp() function.
19 math.modf(x)
This returns the fractional and integer parts of x in a two-item
tuple.
20 math.nextafter(x, y, steps)
This function returns the next floating-point value after x
towards y.
21 math.perm(n, k)
This function is used to calculate the permutation. It returns
the number of ways to choose x items from y items without
repetition and with order.
22 math.prod(iterable, *, start)
This function is used to calculate the product of all numeric
items in the iterable (list, tuple) given as argument.
23 math.remainder(x,y)
This function returns the remainder of x with respect to y. This
is the difference x − n*y, where n is the integer closest to the
quotient x / y.
24 math.trunc(x)
This function returns an integral part of the number, removing
the fractional part. trunc() is equivalent to floor() for positive x,
and equivalent to ceil() for negative x.
25 math.ulp(x)
This function returns the value of the least significant bit of the
float x. trunc() is equivalent to floor() for positive x, and
equivalent to ceil() for negative x.
1 math.cbrt(x)
This function is used to calculate the cube root of a number.
2 math.exp(x)
This function calculate the exponential of x: ex
3 math.exp2(x)
This function returns 2 raised to power x. It is equivalent to
2**x.
4 math.expm1(x)
This function returns e raised to the power x, minus 1. Here e
is the base of natural logarithms.
5 math.log(x)
This function calculates the natural logarithm of x, for x> 0.
6 math.log1p(x)
This function returns the natural logarithm of 1+x (base e).
The result is calculated in a way which is accurate for x near
zero.
7 math.log2(x)
This function returns the base-2 logarithm of x. This is usually
more accurate than log(x, 2).
8 math.log10(x)
The base-10 logarithm of x for x> 0.
9 math.pow(x, y)
The value of x**y.
10 math.sqrt(x)
The square root of x for x > 0
1 math.acos(x)
This function returns the arc cosine of x, in radians.
2 math.asin(x)
This function returns the arc sine of x, in radians.
3 math.atan(x)
This function returns the arc tangent of x, in radians.
4 math.atan2(y, x)
This function returns atan(y / x), in radians.
5 math.cos(x)
This function returns the cosine of x radians.
6 math.sin(x)
This function returns the sine of x radians.
7 math.tan(x)
This function returns the tangent of x radians.
8 math.hypot(x, y)
This function returns the Euclidean norm, sqrt(x*x +
y*y).
1 math.degrees(x)
This function converts the given angle from radians to
degrees.
2 math.radians(x)
This function converts the given angle from degrees to
radians.
1 math.pi
This represents the mathematical constant pi, which equals
"3.141592..." to available precision.
2 math.e
This represents the mathematical constant e, which is equal to
"2.718281..." to available precision.
3 math.tau
This represents the mathematical constant Tau (denoted by τ
). It is equivalent to the ratio of circumference to radius, and is
equal to 2Π.
4 math.inf
This represents positive infinity. For negative infinity use
"−math.inf".
5 math.nan
This constant is a floating-point "not a number" (NaN) value.
Its value is equivalent to the output of float('nan').
1 math.acosh(x)
This function is used to calculate the inverse hyperbolic cosine
of the given value.
2 math.asinh(x)
This function is used to calculate the inverse hyperbolic sine of
a given number.
3 math.atanh(x)
This function is used to calculate the inverse hyperbolic
tangent of a number.
4 math.cosh(x)
This function is used to calculate the hyperbolic cosine of the
given value.
5 math.sinh(x)
This function is used to calculate the hyperbolic sine of a given
number.
6 math.tanh(x)
This function is used to calculate the hyperbolic tangent of a
number.
1 math.erf(x)
This function returns the value of the Gauss error function for
the given parameter.
2 math.erfc(x)
This function is the complement for the error function. Value of
erf(x) is equivalent to 1-erf(x).
3 math.gamma(x)
This is used to calculate the factorial of the complex numbers.
It is defined for all the complex numbers except the non-
positive integers.
4 math.lgamma(x)
This function is used to calculate the natural logarithm of the
absolute value of the Gamma function at x.
Example Usage
The following example demonstrates the use of maths module and its
methods:
Open Compiler
# Importing maths Module
import maths
# Using methods of maths module
print(math.sqrt(9))
print(math.pow(3, 3))
print(math.exp(1))
print(math.log(100, 10))
print(math.factorial(4))
print(math.gcd(12, 3))
Output
3.0
27.0
2.718281828459045
2.0
24
3
Iterators
Python Iterators
An iterator in Python is an object that enables traversal through a
collection such as a list or a tuple, one element at a time. It follows the
iterator protocol by using the implementation of two methods
__iter__() and __next__().
The __iter__() method returns the iterator object itself and the
__next__() method returns the next element in the sequence by raising
a StopIteration exception when no more elements are available.
Iterators provide a memory-efficient way to iterate over data, especially
useful for large datasets. They can be created from iterable objects
using the iter() function or implemented using custom classes and
generators.
Iterables vs Iterators
Before going deep into the iterator working, we should know the
difference between the Iterables and Iterators.
Iterable: An object capable of returning its members one at a
time (e.g., lists, tuples).
Iterator: An object representing a stream of data, returned
one element at a time.
Example
In the following is an example the iterator object we have created have
only 3 elements and we are iterating through it more than thrice −
Open Compiler
it = iter([1,2,3])
print (next(it))
print (it.__next__())
print (it.__next__())
print (next(it))
Custom Iterator
A custom iterator in Python is a user-defined class that implements the
iterator protocol which consists of two methods __iter__() and
__next__(). This allows the class to behave like an iterator, enabling
traversal through its elements one at a time.
To define a custom iterator class in Python, the class must define these
methods.
Example
In the following example, the Oddnumbers is a class implementing
__iter__() and __next__() methods. On every call to __next__(), the
number increments by 2 thereby streaming odd numbers in the range
1 to 10.
Open Compiler
class Oddnumbers:
def __init__(self, end_range):
self.start = -1
self.end = end_range
def __iter__(self):
return self
def __next__(self):
if self.start < self.end-1:
self.start += 2
return self.start
else:
raise StopIteration
counter = Odd Numbers(10)
while True:
try:
no = next(countiter)
print (no)
except StopIteration:
break
Example
Let's create another iterator that generates the first n Fibonacci
numbers with the following code −
Open Compiler
class Fibonacci:
def __init__(self, max_count):
self.max_count = max_count
self.count = 0
self.a, self.b = 0, 1
def __iter__(self):
return self
def __next__(self):
if self.count >= self.max_count:
raise StopIteration
fib_value = self.a
self.a, self.b = self.b, self.a + self.b
self.count += 1
return fib_value
# Using the Fibonacci iterator
fib_iterator = Fibonacci(10)
for number in fib_iterator:
print(number)
Asynchronous Iterator
Asynchronous iterators in Python allow us to iterate over asynchronous
sequences, enabling the handling of async operations within a loop.
They follow the asynchronous iterator protocol which consists of the
methods __aiter__() and __anext__() (added in Python 3.10 version
onwards.). These methods are used in conjunction with the async for
loop to iterate over asynchronous data sources.
The aiter() function returns an asynchronous iterator object. It is an
asynchronous counter part of the classical iterator. Any asynchronous
iterator must support ___aiter()__ and __anext__() methods. These
methods are internally called by the two built-in functions.
Asynchronous functions are called coroutines and are executed with
asyncio.run() method. The main() co-routine contains a while loop
that successively obtains odd numbers and raises StopAsyncIteration if
the number exceeds 9.
Like the classical iterator the asynchronous iterator gives a stream of
objects. When the stream is exhausted, the StopAsyncIteration
exception is raised.
Example
In the example given below, an asynchronous iterator class
Oddnumbers is declared. It implements __aiter__() and __anext__()
method. On each iteration, a next odd number is returned and the
program waits for one second, so that it can perform any other process
asynchronously.
Open Compiler
import asyncio
class Odd Numbers():
def __init__(self):
self.start = -1
def __aiter__(self):
return self
async def __anext__(self):
if self.start >= 9:
raise StopAsyncIteration
self.start += 2
await asyncio.sleep(1)
return self.start
async def main():
it = Oddnumbers()
while True:
try:
awaitable = anext(it)
result = await awaitable
print(result)
except StopAsyncIteration:
break
asyncio.run(main())
Output
It will produce the following output −
1
3
5
7
9
Generators
Python Generators
Generators in Python are a convenient way to create iterators. They
allow us to iterate through a sequence of values which means, values
are generated on the fly and not stored in memory, which is especially
useful for large datasets or infinite sequences.
The generator in Python is a special type of function that returns an
iterator object. It appears similar to a normal Python function in that its
definition also starts with def keyword. However, instead of a return
statement at the end, the generator uses the yield keyword.
Syntax
The following is the syntax of the generator() function −
def generator():
...
...
yield obj
it = generator()
next(it)
...
Creating Generators
There are two primary ways to create generators in python −
Using Generator Functions
Using Generator Expressions
Output
1
2
3
4
5
Output
1
4
9
16
25
Output
1
2
3
4
5
Example
In this example we are creating a normal function and build a list of
Fibonacci numbers and then iterate the list using a loop −
Open Compiler
def fibonacci(n):
fibo = []
a, b = 0, 1
while True:
c=a+b
if c>=n:
break
fibo.append(c)
a, b = b, c
return fibo
f = fibonacci(10)
for i in f:
print (i)
Output
1
2
3
5
8
Example
In the above example we created a fibonacci series using the normal
function and When we want to collect all Fibonacci series numbers in a
list and then the list is traversed using a loop. Imagine that we want
Fibonacci series going upto a large number.
In such cases, all the numbers must be collected in a list requiring huge
memory. This is where the generator is useful as it generates a single
number in the list and gives it for consumption. Following code is the
generator-based solution for list of Fibonacci numbers −
Open Compiler
def fibonacci(n):
a, b = 0, 1
while True:
c=a+b
if c>=n:
break
yield c
a, b = b, c
return
f = fibonacci(10)
while True:
try:
print (next(f))
except StopIteration:
break
Output
1
2
3
5
8
Asynchronous Generator
An asynchronous generator is a coroutine that returns an asynchronous
iterator. A coroutine is a Python function defined with an async
keyword, and it can schedule and await other coroutines and tasks.
Just like a normal generator, the asynchronous generator yields
incremental items in the iterator for every call to a next() function,
instead of next() function.
Syntax
The following is the syntax of the Asynchronous Generator −
async def generator():
...
...
yield obj
it = generator()
next(it)
...
Example
Following code demonstrates a coroutine generator that yields
incrementing integers on every iteration of an async for loop.
Open Compiler
import asyncio
async def async_generator(x):
for i in range(1, x+1):
await asyncio.sleep(1)
yield i
async def main():
async for item in async_generator(5):
print(item)
asyncio.run(main())
Output
1
2
3
4
5
Example
Let us now write an asynchronous generator for Fibonacci numbers. To
simulate some asynchronous task inside the coroutine, the program
calls sleep() method for a duration of 1 second before yielding the next
number. As a result, we will get the numbers printed on the screen
after a delay of one second.
Open Compiler
import asyncio
async def fibonacci(n):
a, b = 0, 1
while True:
c=a+b
if c>=n:
break
await asyncio.sleep(1)
yield c
a, b = b, c
return
async def main():
f = fibonacci(10)
async for num in f:
print (num)
asyncio.run(main())
Output
1
2
3
5
8
Closures
What is a Closure?
A Python closure is a nested function which has access to a variable
from an enclosing function that has finished its execution. Such a
variable is not bound in the local scope. To use immutable variables
(number or string), we have to use the non-local keyword.
The main advantage of Python closures is that we can help avoid the
using global values and provide some form of data hiding. They are
used in Python decorators.
Closures are closely related to nested functions and allow inner
functions to capture and retain the enclosing function's local state,
even after the outer function has finished execution. Understanding
closures requires familiarity with nested functions, variable scope and
how Python handles function objects.
1. Nested Functions: In Python functions can be defined inside
other functions. These are called nested functions or inner
functions.
2. Accessing Enclosing Scope: Inner functions can access
variables from the enclosing i.e. outer scope. This is where
closures come into play.
3. Retention of State: When an inner function i.e. closure
captures and retains variables from its enclosing scope, even
if the outer function has completed execution or the scope is
no longer available.
Nested Functions
Nested functions in Python refer to the practice of defining one function
inside another function. This concept allows us to organise code more
effectively, encapsulate functionality and manage variable scope.
Following is the example of nested functions where functionB is defined
inside functionA. Inner function is then called from inside the outer
function's scope.
Example
Open Compiler
def functionA():
print ("Outer function")
def functionB():
print ("Inner function")
functionB()
functionA()
Output
Outer function
Inner function
If the outer function receives any argument, it can be passed to the
inner function as in the below example.
Open Compiler
def functionA(name):
print ("Outer function")
def functionB():
print ("Inner function")
print ("Hi {}".format(name))
functionB()
functionA("Python")
Output
Outer function
Inner function
Hi Python
Variable Scope
When a closure is created i.e. an inner function that captures variables
from its enclosing scope, it retains access to those variables even after
the outer function has finished executing. This behaviour allows
closures to "remember" and manipulate the values of variables from
the enclosing scope.
Example
Following is the example of the closure with the variable scope −
Open Compiler
def outer_function(x):
y = 10
def inner_function(z):
return x + y + z # x and y are captured from the enclosing scope
return inner_function
closure = outer_function(5)
result = closure(3)
print(result)
Output
18
Creating a closure
Creating a closure in Python involves defining a nested function within
an outer function and returning the inner function. Closures are useful
for capturing and retaining the state of variables from the enclosing
scope.
Example
In the below example, we have a functionA function which creates and
returns another function functionB. The nested functionB function is
the closure.
The outer functionA function returns a functionB function and
assigns it to the myfunction variable. Even if it has finished its
execution. However, the printer closure still has access to the name
variable.
Following is the example of creating the closure in python −
Open Compiler
def functionA(name):
name ="New name"
def functionB():
print (name)
return functionB
myfunction = functionA("My name")
myfunction()
Output
New name
nonlocal Keyword
In Python, nonlocal keywords allow a variable outside the local scope to
be accessed. This is used in a closure to modify an immutable variable
present in the scope of the outer variable. Here is the example of the
closure with the nonlocal keyword.
Open Compiler
def functionA():
counter =0
def functionB():
nonlocal counter
counter+=1
return counter
return functionB
myfunction = function()
retval = myfunction()
print ("Counter:", retval)
retval = myfunction()
print ("Counter:", retval)
retval = myfunction()
print ("Counter:", retval)
Output
Counter: 1
Counter: 2
Counter: 3
Decorators
A Decorator in Python is a function that receives another function as an
argument. The argument function is the one to be decorated by the
decorator. The behaviour of the argument function is extended by the
decorator without actually modifying it.
In this chapter, we shall learn how to use the Python decorator.
You can now decorate this function to extend its behaviour by passing it
to decorator −
function=decorator(function)
Example 1
Following code is a simple example of decorator −
Open Compiler
def my_function(x):
print("The number is=",x)
def my_decorator(some_function,num):
def wrapper(num):
print("Inside wrapper to check odd/even")
if num%2 == 0:
ret= "Even"
else:
ret= "Odd!"
some_function(num)
return ret
print ("wrapper function is called")
return wrapper
no=10
my_function = my_decorator(my_function, no)
print ("It is ",my_function(no))
The my_function() just prints out the received number. However, its
behaviour is modified by passing it to a my_decorator. The inner
function receives the number and returns whether it is odd/even.
Output of above code is −
wrapper function is called
Inside wrapper to check odd/even
The number is= 10
It is Even
Example 2
An elegant way to decorate a function is to mention just before its
definition, the name of the decorator prepended by @ symbol. The
above example is re-written using this notation −
Open Compiler
def my_decorator(some_function):
def wrapper(num):
print("Inside wrapper to check odd/even")
if num%2 == 0:
ret= "Even"
else:
ret= "Odd!"
some_function(num)
return ret
print ("wrapper function is called")
return wrapper
@my_decorator
def my_function(x):
print("The number is=",x)
no=10
print ("It is ",my_function(no))
Python's standard library defines following built-in decorators −
@classmethod Decorator
The classmethod is a built-in function. It transforms a method into a
class method. A class method is different from an instance method. The
Instant method defined in a class is called by its object. The method
received an implicit object referred to by self. A class method on the
other hand implicitly receives the class itself as the first argument.
Syntax
In order to declare a class method, the following notation of decorator
is used −
class Myclass:
@classmethod
def mymethod(cls):
#....
@staticmethod Decorator
The staticmethod is also a built-in function in the Python standard
library. It transforms a method into a static method. Static method
doesn't receive any reference argument whether it is called by instance
of class or class itself. Following notation used to declare a static
method in a class −
Syntax
class Myclass:
@staticmethod
def mymethod():
#....
@property Decorator
Python's property() built-in function is an interface for accessing
instance variables of a class. The @property decorator turns an
instance method into a "getter" for a read-only attribute with the same
name, and it sets the docstring for the property to "Get the current
value of the instance variable."
You can use the following three decorators to define a property −
@property − Declares the method as a property.
@<property-name>.setter: − Specifies the setter method
for a property that sets the value to a property.
@<property-name>.deleter − Specifies the delete method
as a property that deletes a property.
Syntax
The property() object's setter and getter may also be assigned with the
following syntax also.
speed = property()
speed=speed.getter(speed, get_speed)
speed=speed.setter(speed, set_speed)
Recursion
Recursion is a fundamental programming concept where a function
calls itself in order to solve a problem. This technique breaks down a
complex problem into smaller and more manageable sub-problems of
the same type. In Python, recursion is implemented by defining a
function that makes one or more calls to itself within its own body.
Components of Recursion
As we discussed before, Recursion is a technique where a function calls
itself. Here for understanding recursion, it's required to know its key
components. Following are the primary components of the recursion −
Base Case
Recursive Case
Base Case
The Base case is a fundamental concept in recursion, if serving as the
condition under which a recursive function stops calling itself. It is
essential for preventing infinite recursion and subsequent stack
overflow errors.
The base case provides a direct solution to the simplest instance of the
problem ensuring that each recursive call gets closer to this
terminating condition.
The most popular example of recursion is calculation of factorial.
Mathematically factorial is defined as −
n! = n × (n-1)!
It can be seen that we use factorial itself to define factorial. Hence this
is a fit case to write a recursive function. Let us expand the above
definition for calculation of factorial value of 5.
5! = 5 × 4!
5 × 4 × 3!
5 × 4 × 3 × 2!
5 × 4 × 3 × 2 × 1!
5×4×3×2×1
= 120
Example
The following example shows hows you can use a recursive function to
calculate factorial −
Open Compiler
def factorial(n):
if n == 1:
print (n)
return 1 #base case
else:
print (n,'*', end=' ')
return n * factorial(n-1) #Recursive case
print ('factorial of 5=', factorial(5))
Example
Following is the example of the Recursive case. In this example we are
generating the Fibonacci sequence in which the recursive case sums
the results of the two preceding Fibonacci numbers −
Open Compiler
def fibonacci(n):
if n <= 0:
return 0 # Base case for n = 0
elif n == 1:
return 1 # Base case for n = 1
else:
return fibonacci(n - 1) + fibonacci(n - 2) # Recursive case
fib_series = [fibonacci(i) for i in range(6)]
print(fib_series)
Example
The following code implements the recursive binary searching
technique −
Open Compiler
def bsearch(my_list, low, high, elem):
if high >= low:
mid = (high + low) // 2
if my_list[mid] == elem:
return mid
elif my_list[mid] > elem:
return bsearch(my_list, low, mid - 1, elem)
else:
return bsearch(my_list, mid + 1, high, elem)
else:
return -1
my_list = [5,12,23, 45, 49, 67, 71, 77, 82]
num = 67
print("The list is")
print(my_list)
print ("Check for number:", num)
my_result = bsearch(my_list,0,len(my_list)-1,num)
if my_result != -1:
print("Element found at index ", str(my_result))
else:
print("Element not found!")
Output
The list is
[5, 12, 23, 45, 49, 67, 71, 77, 82]
Check for number: 67
Element found at index 5
Regular Expressions
A regular expression is a special sequence of characters that helps you
match or find other strings or sets of strings, using a specialised syntax
held in a pattern. Regular expressions are popularly known as regex or
regexp.
Usually, such patterns are used by string-searching algorithms for
"find" or "find and replace" operations on strings, or for input
validation.
Large scale text processing in data science projects requires
manipulation of textual data. The regular expressions processing is
supported by many programming languages including Python. Python's
standard library has a module for this purpose.
Since most of the functions defined in the module work with raw
strings, let us first understand what the raw strings are.
Raw Strings
Regular expressions use the backslash character ('\') to indicate special
forms or to allow special characters to be used without invoking their
special meaning. Python on the other hand uses the same character as
escape character. Hence Python uses the raw string notation.
A string become a raw string if it is prefixed with r or R before the
quotation symbols. Hence 'Hello' is a normal string where r'Hllor' is a
raw string.
>>> normal="Hello"
>>> print (normal)
Hello
>>> raw=r"Hello"
>>> print (raw)
Hello
Metacharacters
Most letters and characters will simply match themselves. However,
some characters are special metacharacters, and don't match
themselves. Meta characters are characters having a special meaning,
similar to * in the wild card.
Here's a complete list of the metacharacters −
.^$*+?{}[]\|()
The square bracket symbols[ and ] indicate a set of characters that you
wish to match. Characters can be listed individually, or as a range of
characters separating them by a '-'.
Sr. Metacharacters & Description
No.
1 [abc]
match any of the characters a, b, or c
2 [a-c]
which uses a range to express the same set of characters.
3 [a-z]
match only lowercase letters.
4 [0-9]
match only digits.
5 '^'
complements the character set in [].[^5] will match any
character except 5'.
1 \d
Matches any decimal digit; this is equivalent to the class [0-9].
2 \D
Matches any non-digit character; this is equivalent to the class
[^0-9].
4 \S
Matches any non-whitespace character; this is equivalent to
the class [^\t\n\r\f\v].
5 \w
Matches any alphanumeric character; this is equivalent to the
class [a-zAZ0-9_].
6 \W
Matches any non-alphanumeric character. equivalent to the
class [^a-zAZ0-9_].
7 .
Matches with any single character except the newline '\n'.
8 ?
match 0 or 1 occurrence of the pattern to its left
9 +
1 or more occurrences of the pattern to its left
10 *
0 or more occurrences of the pattern to its left
11 \b
boundary between word and nonword and /B is opposite of /b
12 [..]
Matches any single character in a square bracket and [^..]
matches any single character not in square bracket.
13 \
It is used for special meaning characters like \. to match a
period or \+ for plus sign.
14 {n,m}
Matches at least n and at most m occurrences of preceding
15 a| b
Matches either a or b
1 pattern
This is the regular expression to be matched.
2 String
This is the string, which would be searched to match the
pattern at the beginning of the string.
3 Flags
You can specify different flags using bitwise OR (|). These are
modifiers, which are listed in the table below.
Example
Open Compiler
import re
line = "Cats are smarter than dogs"
matchObj = re.match( r Cats', line)
print (matchObj.start(), matchObj.end())
print ("matchObj.group() : ", matchObj.group())
1 Pattern
This is the regular expression to be matched.
2 String
This is the string, which would be searched to match the
pattern anywhere in the string.
3 Flags
You can specify different flags using bitwise OR (|). These are
modifiers, which are listed in the table below.
Example
Open Compiler
import re
line = "Cats are smarter than dogs"
matchObj = re.search( r'than', line)
print (matchObj.start(), matchObj.end())
print ("matchObj.group() : ", matchObj.group())
Matching Vs Searching
Python offers two different primitive operations based on regular
expressions, match checks for a match only at the beginning of the
string, while search checks for a match anywhere in the string (this is
what Perl does by default).
Example
Open Compiler
import re
line = "Cats are smarter than dogs";
matchObj = re.match( dogs', line, re.M|re.I)
if matchObj:
print ("match --> matchObj.group() : ", matchObj.group())
else:
print ("No match!!")
searchObj = re.search( dogs', line, re.M|re.I)
if searchObj:
print ("search --> searchObj.group() : ", searchObj.group())
else:
print ("Nothing found!!")
When the above code is executed, it produces the following output −
No match!!
search --> matchObj.group() : dogs
Syntax
re.findall(pattern, string, flags=0)
Parameters
Sr. Parameter & Description
No.
1 Pattern
This is the regular expression to be matched.
2 String
This is the string, which would be searched to match the
pattern anywhere in the string.
3 Flags
You can specify different flags using bitwise OR (|). These are
modifiers, which are listed in the table below.
Example
Open Compiler
import re
string="Simple is better than complex."
obj=re.findall(r"ple", string)
print (obj)
Syntax
re.sub(pattern, repl, string, max=0)
Example
Open Compiler
import re
phone = "2004-959-559 # This is Phone Number"
# Delete Python-style comments
num = re.sub(r'#.*$', "", phone)
print ("Phone Num : ", num)
# Remove anything other than digits
num = re.sub(r'\D', "", phone)
print ("Phone Num : ", num)
Syntax
re.compile(pattern, flags=0)
Flags
Sr. Modifier & Description
No.
1 re.I
Performs case-insensitive matching.
2 re.L
Interprets words according to the current locale. This
interpretation affects the alphabetic group (\w and \W), as well
as word boundary behaviour (\b and \B).
3 re.
M Makes $ match the end of a line (not just the end of the
string) and makes ^ match the start of any line (not just the
start of the string).
4 re.S
Makes a period (dot) match any character, including a newline.
5 re.U
Interprets letters according to the Unicode character set. This
flag affects the behaviour of \w, \W, \b, \B.
6 re.X
Permits "cuter" regular expression syntax. It ignores
whitespace (except inside a set [] or when escaped by a
backslash) and treats unescaped # as a comment marker.
The sequence −
prog = re.compile(pattern)
result = prog.match(string)
is equivalent to −
result = re.match(pattern, string)
Example
Open Compiler
import re
string="Simple is better than complex. Complex is better than
complicated."
pattern=re.compile(r'is')
obj=pattern.match(string)
obj=pattern.search(string)
print (obj.start(), obj.end())
obj=pattern.findall(string)
print (obj)
obj=pattern.sub(r'was', string)
print (obj)
It will produce the following output −
79
['is', 'is']
Simple was better than complex. Complex was better than
complicated.
Syntax
re.finditer(pattern, string, flags=0)
Example
Open Compiler
import re
string="Simple is better than complex. Complex is better than
complicated."
pattern=re.compile(r'is')
iterator = pattern.finditer(string)
print (iterator )
for match in iterator:
print(match.span())
1 re.I
Performs case-insensitive matching.
2 re.L
Interprets words according to the current locale. This
interpretation affects the alphabetic group (\w and \W), as well
as word boundary behaviour(\b and \B).
3 re.M
Makes $ match the end of a line (not just the end of the string)
and makes ^ match the start of any line (not just the start of
the string).
4 re.S
Makes a period (dot) match any character, including a newline.
5 re.U
Interprets letters according to the Unicode character set. This
flag affects the behaviour of \w, \W, \b, \B.
6 re.X
Permits "cuter" regular expression syntax. It ignores
whitespace (except inside a set [] or when escaped by a
backslash) and treats unescaped # as a comment marker.
1 ^
Matches beginning of line.
2 $
Matches end of line.
3 .
Matches any single character except newline. Using m option
allows it to match newlines as well.
4 [...]
Matches any single character in brackets.
5 [^...]
Matches any single character not in brackets
6 re*
Matches 0 or more occurrences of preceding expression.
7 re+
Matches 1 or more occurrences of preceding expression.
8 re?
Matches 0 or 1 occurrence of preceding expression.
9 re{ n}
Matches exactly n number of occurrences of preceding
expression.
10 re{ n,}
Matches n or more occurrences of preceding expression.
11 re{ n, m}
Matches at least n and at most m occurrences of preceding
expression.
12 a| b
Matches either a or b.
13 (re)
Groups regular expressions and remembers matched text.
14 (?imx)
Temporarily toggles on i, m, or x options within a regular
expression. If in parentheses, only that area is affected.
15 (?-imx)
Temporarily toggles off i, m, or x options within a regular
expression. If in parentheses, only that area is affected.
16 (?: re)
Groups regular expressions without remembering matched
text.
17 (?imx: re)
Temporarily toggles on i, m, or x options within parentheses.
18 (?-imx: re)
Temporarily toggles off i, m, or x options within parentheses.
19 (?#...)
Comment.
20 (?= re)
Specifies position using a pattern. Doesn't have a range.
21 (?! re)
Specifies position using pattern negation. Doesn't have a
range.
22 (?> re)
Matches independent patterns without backtracking.
23 \w
Matches word characters.
24 \W
Matches non word characters.
25 \s
Matches whitespace. Equivalent to [\t\n\r\f].
26 \S
Matches non whitespace.
27 \d
Matches digits. Equivalent to [0-9].
28 \D
Matches non digits.
29 \A
Matches beginning of string.
30 \Z
Matches end of string. If a newline exists, it matches just
before the newline.
31 \z
Matches end of string.
32 \G
Matches point where the last match finished.
33 \b
Matches word boundaries when outside brackets. Matches
backspace (0x08) when inside brackets.
34 \B
Matches nonword boundaries.
36 \1...\9
Matches nth grouped subexpression.
37 \10
Matches nth grouped subexpression if it matched already.
Otherwise refers to the octal representation of a character
code.
1 python
Match "python".
Character classes
Sr.N Example & Description
o.
1 [Pp]python
Match "Python" or "python"
2 rub[ye]
Match "ruby" or "ruby"
3 [aeiou]
Match any one lowercase vowel
4 [0-9]
Match any digit; same as [0123456789]
5 [a-z]
Match any lowercase ASCII letter
6 [A-Z]
Match any uppercase ASCII letter
7 [a-zA-Z0-9]
Match any of the above
8 [^aeiou]
Match anything other than a lowercase
vowel
9 [^0-9]
Match anything other than a digit
1 .
Match any character except newline
2 \d
Match a digit: [0-9]
3 \D
Match a non digit: [^0-9]
4 \s
Match a whitespace character: [ \t\r\n\f]
5 \S
Match non whitespace: [^ \t\r\n\f]
6 \w
Match a single word character: [A-Za-z0-
9_]
7 \W
Match a nonword character: [^A-Za-z0-
9_]
Repetition Cases
Sr.N Example & Description
o.
1 ruby?
Match "rub" or "ruby": the y is
optional
2 ruby*
Match "rub" plus 0 or more ys
3 ruby _
Match "rub" plus 1 or more ys
4 \d{3}
Match exactly 3 digits
5 \d{3,}
Match 3 or more digits
6 \d{3,5}
Match 3, 4, or 5 digits
Nongreedy repetition
This matches the smallest number of repetitions −
1 <.*>
Greedy repetition: matches "<python>perl>"
2 <.*?>
Nongreedy: matches "<python>" in "
<python>perl>"
1 \D\d+
No group: + repeats \d
2 (\D\d)+
Grouped: + repeats \D\d pair
3 ([Pp]python(, )?)+
Match "Python", "Python, python, python",
etc.
Backreferences
This matches a previously matched group again −
1 ([Pp])python 1\nails
Match python pails or Python Pails
2 (['"])[^\1]*\1
Single or double-quoted string. \1 matches whatever the 1st
group matched. \2 matches whatever the 2nd group matched,
etc.
Alternatives
Sr.N Example & Description
o.
1 python|perl
Match "python" or "perl"
2 rub(y|le))
Match "ruby" or "ruble"
3 Python(!+|\?)
"Python" followed by one or more ! or one
?
Anchors
This needs to specify a match position.
1 ^Python
Match "Python" at the start of a string or internal line
2 Python$
Match "Python" at the end of a string or line
3 \APython
Match "Python" at the start of a string
4 Python\Z
Match "Python" at the end of a string
5 \bPython\b
Match "Python" at a word boundary
6 \brub\B
\B is non word boundary: match "rub" in "ruby" and "ruby" but
not alone
7 Python(?=!)
Match "Python", if followed by an exclamation point.
8 Python(?!!)
Match "Python", if not followed by an exclamation point.
1 R(?#comment)
Matches "R". All the rest is a comment
2 R(?i)uby
Case-insensitive while matching "uby"
3 R(?i:uby)
Same as above
4 rub(?:y|le))
Group only without creating \1
backreference
PIP
Pip in Python
In Python, pip is the standard package management system used to
install and manage software packages written in Python. It allows you
to easily install libraries and frameworks to extend the functionality of
Python applications. pip comes bundled with Python, starting from
Python version 3.4 and above.
Installing pip
If you are using Python 3.4 or above, pip is already included. However,
if you don't have pip installed, you can install it using the following
steps −
Download get-pip.py script −
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
Run the Script
python get-pip.py
Example
To install the requests library, you can use the following command −
pip install requests
Upgrading Packages
To upgrade a package to the latest version, you can use the --upgrade
option with the pip install command.
Syntax
Following is the basic syntax to upgrade a package in Python −
pip install --upgrade package_name
Example
To upgrade the requests library, you can use the following command −
pip install --upgrade requests
Listing Installed Packages
You can list all the installed packages in your Python environment using
the pip list command.
When working on Python projects, it is often necessary to know which
packages and versions are installed in your environment. pip provides
several commands to list and manage installed packages.
Basic Listing
To list all installed packages in your current environment, use
the following command −
pip list
This command outputs a list of all installed packages along with
their respective versions. This is useful for quickly checking the
state of your environment.
Detailed Information
For more detailed information about each installed package, you can
use the pip show command followed by the package name −
pip show requests
Outdated Packages
To check for outdated packages in your environment, you can use the
following command −
pip list --outdated
This command lists all installed packages that have newer versions
available. The output includes the current version and the latest
version available.
Uninstalling Packages
To uninstall a package, you can use the pip uninstall command.
When you no longer need a Python package in your environment, you
can uninstall it using pip. Here is how you can uninstall packages −
Creating requirements.txt
To create a "requirements.txt" file with the current environment's
packages, you can use the following command −
pip freeze > requirements.txt
Replace myenv with your preferred name for the virtual environment.
This command creates a directory named myenv (or your specified
name) containing a self-contained Python environment.
Once activated, your command prompt will change to show the name
of the virtual environment (myenv in this case), indicating that you are
now working within it.
Database Access
Database Access in Python
Database access in Python is used to interact with databases, allowing
applications to store, retrieve, update, and manage data consistently.
Various relational database management systems (RDBMS) are
supported for these tasks, each requiring specific Python packages for
connectivity −
1. GadFly
2. MySQL
3. PostgreSQL
4. Microsoft SQL Server
5. Informix
6. Oracle
7. Sybase
8. SQLite
9. and many more...
PostgreS psycopg2
QL
We can now perform all SQL query operations, with the help of its
execute() method available to the cursor object. This method needs a
string argument which must be a valid SQL statement.
When the above program is run, the database with the Employee table
is created in the current working directory.
We can verify by listing out tables in this database in the SQLite
console.
sqlite> .open db.sqlite
sqlite> .tables
Employee
INSERT Operation
The INSERT Operation is required when you want to create your records
into a database table.
Example
The following example, executes SQL INSERT statement to create a
record in the EMPLOYEE table −
Open Compiler
import sqlite3
conn=sqlite3.connect('testdb.sqlite3')
cur=conn.cursor()
qry="""INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME, AGE, SEX, INCOME)
VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""
try:
cur.execute(qry)
conn.commit()
print ('Record inserted successfully')
except:
conn.rollback()
print ('error in INSERT operation')
conn.close()
You can also use the parameter substitution technique to execute the
INSERT query as follows −
import sqlite3
conn=sqlite3.connect('testdb.sqlite3')
cur=conn.cursor()
qry="""INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME, AGE, SEX, INCOME)
VALUES (?, ?, ?, ?, ?)"""
try:
cur.execute(qry, ('Makrand', 'Mohan', 21, 'M', 5000))
conn.commit()
print ('Record inserted successfully')
except Exception as e:
conn.rollback()
print ('error in INSERT operation')
conn.close()
READ Operation
READ Operation on any database means to fetch some useful
information from the database.
Once the database connection is established, you are ready to make a
query into this database. You can use either fetchone() method to fetch
a single record or fetchall() method to fetch multiple values from a
database table.
fetchone() − It fetches the next row of a query result set. A
result set is an object that is returned when a cursor object is
used to query a table.
fetchall() − It fetches all the rows in a result set. If some
rows have already been extracted from the result set, then it
retrieves the remaining rows from the result set.
rowcount − This is a read-only attribute and returns the
number of rows that were affected by an execute() method.
Example
In the following code, the cursor object executes SELECT * FROM
EMPLOYEE query. The resultset is obtained with the fetchall() method.
We print all the records in the resultset with a for loop.
import sqlite3
conn=sqlite3.connect('testdb.sqlite3')
cur=conn.cursor()
qry="SELECT * FROM EMPLOYEE"
try:
# Execute the SQL command
cur.execute(qry)
# Fetch all the rows in a list of lists.
results = cur.fetchall()
for row in results:
fname = row[1]
lname = row[2]
age = row[3]
sex = row[4]
income = row[5]
# Now print fetched result
print ("fname={},lname={},age={},sex={},income=
{}".format(fname, lname, age, sex, income ))
except Exception as e:
print (e)
print ("Error: unable to fetch data")
conn.close()
It will produce the following output −
fname=Mac,lname=Mohan,age=20,sex=M,income=2000.0
fname=Makrand,lname=Mohan,age=21,sex=M,income=5000.0
Update Operation
UPDATE Operation on any database means to update one or more
records, which are already available in the database.
The following procedure updates all the records having income=2000.
Here, we increase the income by 1000.
import sqlite3
conn=sqlite3.connect('testdb.sqlite3')
cur=conn.cursor()
qry="UPDATE EMPLOYEE SET INCOME = INCOME+1000 WHERE
INCOME=?"
try:
# Execute the SQL command
cur.execute(qry, (1000,))
# Fetch all the rows in a list of lists.
conn.commit()
print ("Records updated")
except Exception as e:
print ("Error: unable to update data")
conn.close()
DELETE Operation
DELETE operation is required when you want to delete some records
from your database. Following is the procedure to delete all the records
from EMPLOYEE where INCOME is less than 2000.
import sqlite3
conn=sqlite3.connect('testdb.sqlite3')
cur=conn.cursor()
qry="DELETE FROM EMPLOYEE WHERE INCOME<?"
try:
# Execute the SQL command
cur.execute(qry, (2000,))
# Fetch all the rows in a list of lists.
conn.commit()
print ("Records deleted")
except Exception as e:
print ("Error: unable to delete data")
conn.close()
Performing Transactions
Transactions are a mechanism that ensures data consistency.
Transactions have the following four properties −
Atomicity − Either a transaction completes or nothing
happens at all.
Consistency − A transaction must start in a consistent state
and leave the system in a consistent state.
Isolation − Intermediate results of a transaction are not
visible outside the current transaction.
Durability − Once a transaction is committed, the effects are
persistent, even after a system failure.
Example
You already know how to implement transactions. Here is a similar
example −
# Prepare SQL query to DELETE required records
sql = "DELETE FROM EMPLOYEE WHERE AGE > ?"
try:
# Execute the SQL command
cursor.execute(sql, (20,))
# Commit your changes in the database
db.commit()
except:
# Rollback in case there is any error
db.rollback()
COMMIT Operation
Commit is an operation, which gives a green signal to the database to
finalise the changes, and after this operation, no change can be
reverted back.
Here is a simple example to call the commit method.
db.commit()
ROLLBACK Operation
If you are not satisfied with one or more of the changes and you want
to revert back those changes completely, then use the rollback()
method.
Here is a simple example to call the rollback() method.
db.rollback()
Installing PyMySQL
Before proceeding further, you make sure you have PyMySQL installed
on your machine. Just type the following in your Python script and
execute it −
import PyMySQL
The last stable release is available on PyPI and can be installed with pip
−
pip install PyMySQL
Note − Make sure you have root privilege to install the above module.
Example
To use MySQL database instead of SQLite database in earlier examples,
we need to change the connect() function as follows −
import PyMySQL
# Open database connection
db = PyMySQL.connect("localhost","testuser","test123","TESTDB" )
Handling Errors
There are many sources of errors. A few examples are a syntax error in
an executed SQL statement, a connection failure, or calling the fetch
method for an already cancelled or finished statement handle.
The DB API defines a number of errors that must exist in each database
module. The following table lists these exceptions.
Sr. Exception & Description
No.
1 Warning
Used for non-fatal issues. Must subclass StandardError.
2 Error
Base class for errors. Must subclass StandardError.
3 InterfaceError
Used for errors in the database module, not the database
itself. Must subclass Error.
4 DatabaseError
Used for errors in the database. Must subclass Error.
5 DataError
Subclass of DatabaseError that refers to errors in the data.
6 OperationalError
Subclass of DatabaseError that refers to errors such as the loss
of a connection to the database. These errors are generally
outside of the control of the Python scripter.
7 IntegrityError
Subclass of DatabaseError for situations that would damage
the relational integrity, such as uniqueness constraints or
foreign keys.
8 InternalError
Subclass of DatabaseError that refers to errors internal to the
database module, such as a cursor no longer being active.
9 ProgrammingError
Subclass of DatabaseError that refers to errors such as a bad
table name and other things that can safely be blamed on
you.
10 NotSupportedError
Subclass of DatabaseError that refers to trying to call
unsupported functionality.
Weak References
Python uses reference counting mechanism while implementing
garbage collection policy. Whenever an object in the memory is
referred, the count is incremented by one. On the other hand, when the
reference is removed, the count is decremented by 1. If the garbage
collector running in the background finds any object with count as 0, it
is removed and the memory occupied is reclaimed.
Weak reference is a reference that does not protect the object from
getting garbage collected. It proves important when you need to
implement caches for large objects, as well as in a situation where
reduction of Pain from circular references is desired.
To create weak references, Python has provided us with a module
named weakref.
The ref class in this module manages the weak reference to an object.
When called, it retrieves the original object.
To create a weak reference −
weakref.ref(class())
Example
Open Compiler
import weakref
class Myclass:
def __del__(self):
print('(Deleting {})'.format(self))
obj = Myclass()
r = weakref.ref(obj)
print('object:', obj)
print('reference:', r)
print('call r():', r())
print('deleting obj')
del obj
print('r():', r())
Calling the reference object after deleting the referent returns None.
It will produce the following output −
object: <__main__.Myclass object at 0x00000209D7173290>
reference: <weakref at 0x00000209D7175940; to 'Myclass' at
0x00000209D7173290>
call r(): <__main__.Myclass object at 0x00000209D7173290>
deleting obj
(Deleting <__main__.Myclass object at 0x00000209D7173290>)
r(): None
WeakKeyDictionary
Mapping class that references keys weakly. Entries in the dictionary will
be discarded when there is no longer a strong reference to the key.
An instance of WeakKeyDictionary class is created with an existing
dictionary or without any argumentThe functionality is the same as a
normal dictionary to add and remove mapping entries to it.
In the code given below three Person instances are created. It then
creates an instance of WeakKeyDictionary with a dictionary where the
key is the Person instance and the value is the Person's name.
We call the keyrefs() method to retrieve weak references. When the
reference to Peron1 is deleted, dictionary keys are printed again. A new
Person instance is added to a dictionary with weakly referenced keys.
At last, we are printing dictionary keys again.
Example
Open Compiler
import weakref
class Person:
def __init__(self, person_id, name, age):
self.emp_id = person_id
self.name = name
self.age = age
def __repr__(self):
return "{} : {} : {}".format(self.person_id, self.name, self.age)
Person1 = Person(101, "Jeevan", 30)
Person2 = Person(102, "Ramanna", 35)
Person3 = Person(103, "Simran", 28)
weak_dict = weakref.WeakKeyDictionary({Person1: Person1.name,
Person2: Person2.name, Person3: Person3.name})
print("Weak Key Dictionary : {}\n".format(weak_dict.data))
print("Dictionary Keys : {}\n".format([key().name for key in
weak_dict.keyrefs()]))
del Person1
print("Dictionary Keys : {}\n".format([key().name for key in
weak_dict.keyrefs()]))
Person4 = Person(104, "Partho", 32)
weak_dict.update({Persona 4: Person4.name})
print("Dictionary Keys : {}\n".format([key().name for key in
weak_dict.keyrefs()]))
It will produce the following output −
Weak Key Dictionary : {<weakref at 0x7f542b6d4180; to 'Person' at
0x7f542b8bbfd0>: 'Jeevan', <weakref at 0x7f542b6d5530; to 'Person'
at 0x7f542b8bbeb0>: 'Ramanna', <weakref at 0x7f542b6d55d0; to
'Person' at 0x7f542b8bb7c0>: 'Simran'}
Dictionary Keys : ['Jeevan', 'Ramanna', 'Simran']
Dictionary Keys : ['Ramanna', 'Simran']
Dictionary Keys : ['Ramanna', 'Simran', 'Partho']
WeakValueDictionary
Mapping class that references values weakly. Entries in the dictionary
will be discarded when no strong reference to the value exists any
more.
We shall demonstrate how to create a dictionary with weakly
referenced values using WeakValueDictionary.
The code is similar to previous example but this time we are using
Person name as key and Person instance as values. We are using the
value refs() method to retrieve weakly referenced values of the
dictionary.
Example
Open Compiler
import weakref
class Person:
def __init__(self, person_id, name, age):
self.emp_id = person_id
self.name = name
self.age = age
def __repr__(self):
return "{} : {} : {}".format(self.person_id, self.name, self.age)
Person1 = Person(101, "Jeevan", 30)
Person2 = Person(102, "Ramanna", 35)
Person3 = Person(103, "Simran", 28)
weak_dict = weakref.WeakValueDictionary({Person1.name:Person1,
Person2.name:Person2, Person3.name:Person3})
print("Weak Value Dictionary : {}\n".format(weak_dict.data))
print("Dictionary Values : {}\n".format([value().name for value in
weak_dict.valuerefs()]))
del Person1
print("Dictionary Values : {}\n".format([value().name for value in
weak_dict.valuerefs()]))
Person4 = Person(104, "Partho", 32)
weak_dict.update({Person4.name: Person4})
print("Dictionary Values : {}\n".format([value().name for value in
weak_dict.valuerefs()]))
Serialisation
Serialisation in Python
Serialisation refers to the process of converting an object into a format
that can be easily stored, transmitted, or reconstructed later. In Python,
this involves converting complex data structures, such as objects or
dictionaries, into a byte stream.
Serialising an Object
We can serialise an object using the dump() function and write it to a
file. The file must be opened in binary write mode ('wb').
Example
In the following example, a dictionary is serialised and written to a file
named "data.pkl" −
Open Compiler
import pickle
data = {'name': 'Alice', 'age': 30, 'city': 'New York'}
# Open a file in binary write mode
with open('data.pkl', 'wb') as file:
# Serialise the data and write it to the file
pickle.dump(data, file)
print ("File created!!")
Deserializing an Object
To deserialize or unpickle the object, you can use the load() function.
The file must be opened in binary read mode ('rb') as shown below −
import pickle
# Open the file in binary read mode
with open('data.pkl', 'rb') as file:
# Deserialize the data
data = pickle.load(file)
print(data)
This will read the byte stream from "data.pkl" and convert it back into
the original dictionary as shown below −
{'name': 'Alice', 'age': 30, 'city': 'New York'}
Pickle Protocols
Protocols are the conventions used in constructing and deconstructing
Python objects to/from binary data.
The pickle module supports different serialisation protocols, with
higher protocols generally offering more features and better
performance. Currently pickle module defines 6 different protocols as
listed below −
1 Protocol version 0
Original "human-readable" protocol backwards compatible
with earlier versions.
2 Protocol version 1
Old binary format is also compatible with earlier versions of
Python.
3 Protocol version 2
Introduced in Python 2.3 provides efficient pickling of new-
style classes.
4 Protocol version 3
Added in Python 3.0. recommended when compatibility with
other Python 3 versions is required.
5 Protocol version 4
Introduced in Python 3.4. It adds support for very large
objects.
6 Protocol version 5
Introduced in Python 3.8. It adds support for out-of-band data.
Example
In this example, an instance of the "Person" class is serialised and then
deserialized, maintaining the state of the object −
Open Compiler
import pickle
class Person:
def __init__(self, name, age, city):
self.name = name
self.age = age
self.city = city
# Create an instance of the Person class
person = Person('Alice', 30, 'New York')
# Serialise the person object
with open('person.pkl', 'wb') as file:
pickle.dump(person, file)
# Deserialize the person object
with open('person.pkl', 'rb') as file:
person = pickle.load(file)
print(person.name, person.age, person.city)
Serialisation
Serialisation is the process of converting a Python object into a JSON
string or writing it to a file.
Example: Serialize Data to a JSON String
In the example below, we use the json.dumps() function to convert a
Python dictionary to a JSON string −
Open Compiler
import json
# Create a dictionary
data = {"name": "Alice", "age": 25, "city": "San Francisco"}
# Serialise the dictionary to a JSON string
json_string = json.dumps(data)
print(json_string)
Deserialization
Deserialization is the process of converting a JSON string back into a
Python object or reading it from a file.
Example: Deserialize a JSON String
In the following example, we use the json.loads() function to convert a
JSON string back into a Python dictionary −
Open Compiler
import json
# JSON string
json_string = '{"name": "Alice", "age": 25, "city": "San Francisco"}'
# Deserialize the JSON string into a Python dictionary
loaded_data = json.loads(json_string)
print(loaded_data)
Templating
Templating in Python
Templating in Python is a technique used in web development to
dynamically generate static HTML pages using templates and data.
In this tutorial, we will explore the basics of templating in Python,
including installation, creating templates, and rendering templates with
data, with a focus on the Jinja2 templating engine.
String Templates in Python
String templates in Python is a simple way to perform string
substitutions. Python's string module includes the Template class,
which provides an easy way to replace placeholders in a string with
actual values.
The Template class in the string module is useful for dynamically
forming a string object through a substitution technique described in
PEP 292. Its simpler syntax and functionality make it easier to translate
for internationalisation purposes compared to other built-in string
formatting facilities in Python.
Template strings use the $ symbol for substitution, immediately
followed by an identifier that follows the rules of forming a valid Python
identifier.
Creating a Template
To create a template, you instantiate the Template class with a string
that contains placeholders prefixed with $ as shown below −
from string import Template
template = Template("Hello, $name!")
Substituting Values
You can substitute values into the template using the substitute()
method, which takes a dictionary of key-value pairs.
The substitute() method replaces the placeholders (identifiers) in the
template with actual values. You can provide these values using
keyword arguments or a dictionary. The method then returns a new
string with the placeholders filled in.
Example: Using Keyword Arguments
Following code substitute identifiers in a template string using keyword
arguments −
Open Compiler
from string import Template
tempStr = Template('Hello. My name is $name and my age is $age')
newStr = tempStr.substitute(name = 'Pushpa', age = 26)
print (newStr)
It will produce the following output −
Hello. My name is Pushpa and my age is 26
Installing Jinja2
To use Jinja2 for templating in Python, you first need to install the
library. Jinja2 is a powerful templating engine that is widely used in web
development for rendering HTML. It can be installed easily using pip,
Python's package installer −
pip install jinja2
Example
In here, we are rendering Jinja2 template −
from jinja2 import Template, FileSystemLoader, Environment
# Loading a template from a file (template.html)
file_loader = FileSystemLoader('.')
env = Environment(loader=file_loader)
template = env.get_template('template.html')
# Rendering the template with data
output = template.render(name='Alice')
# Output the rendered template
print(output)
Template Inheritance
Jinja2 supports template inheritance, allowing you to create a base
template with common elements (like headers, footers, navigation
bars) and extend or override specific blocks in child templates. This
promotes code reuse and maintainability in large projects.
Example
This HTML template file named "base.html" defines a basic structure for
a web page using Jinja2 templating syntax.
It includes blocks "{% block title %}" and "{% block content %}" that
can be overridden in derived templates to customise the title and main
content of the page, respectively −
<!-- base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}Default Title{% endblock %}</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
Loops
Jinja2 allows you to iterate over lists or other iterable objects using {%
for %} loops. Following is an example of how you can use a loop to
generate an unordered list (<ul>) in HTML −
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
Conditionals
Conditional statements in Jinja2 ({% if %} and {% else %}) are used
to control the flow of your templates based on conditions. Here is an
example where "Jinja2" checks if user exists and displays a
personalised greeting if true; otherwise, it prompts to log in −
{% if user %}
<p>Welcome, {{ user }}!</p>
{% else %}
<p>Please log in.</p>
{% endif %}
Custom Filters
Custom filters in Jinja2 are used to define your own filters to manipulate
data before displaying it in the template.
In the following example, a custom filter reverse is defined in Jinja2 to
reverse the string "hello", resulting in "olleh" when applied in the
template −
# Define a custom filter function
def reverse_string(s):
return s[::-1]
# Register the filter with the Jinja2 environment
env.filters['reverse'] = reverse_string
In your template, you can then apply the "reverse" filter to any string −
{{ "hello" | reverse }}
Output Formatting
Syntax
The general syntax of format() method is as follows −
str.format(var1, var2,...)
Return Value
The method returns a formatted string.
The string itself contains placeholders {} in which values of variables
are successively inserted.
Example
Open Compiler
name="Rajesh"
age=23
print ("my name is {} and my age is {} years".format(name, age))
Using F-Strings
F-strings, or formatted string literals, are a way to format strings in
Python that is simple, fast, and easy to read. You create an f-string by
adding an f before the opening quotation mark of a string.
Inside the string, you can include placeholders for variables, which are
enclosed in curly braces {}. The values of these variables will be
inserted into the string at those places.
Example
In this example, the variables "name" and "age" are inserted into the
string where their placeholders "{name}" and "{age}" are located. F-
strings make it easy to include variable values in strings without having
to use the format() method or string concatenation −
Open Compiler
name = 'Rajesh'
age = 23
fstring = My name is {name} and I am {age} years old'
print (fstring)
Template Strings
The Template class in string module provides an alternative method
to format the strings dynamically. One of the benefits of Template class
is to be able to customise the formatting rules.
A valid template string, or placeholder, consists of two parts: The $
symbol followed by a valid Python identifier.
You need to create an object of the Template class and use the
template string as an argument to the constructor. Next, call the
substitute() method of the Template class. It puts the values provided
as the parameters in place of template strings.
Example
Open Compiler
from string import Template
temp_str = "My name is $name and I am $age years old"
tempobj = Template(temp_str)
ret = tempobj.substitute(name='Rajesh', age=23)
print (ret)
textwrap.wrap(text, width=70)
The textwrap.wrap() function wraps the single paragraph in text (a
string) so every line is at most width characters long. Returns a list of
output lines, without final newlines. Optional keyword arguments
correspond to the instance attributes of TextWrapper. width defaults to
70.
textwrap.fill(text, width=70)
The textwrap.fill() function wraps the single paragraph in text, and
returns a single string containing the wrapped paragraph.
Both methods internally create an object of the TextWrapper class and
call a single method on it. Since the instance is not reused, it will be
more efficient for you to create your own TextWrapper object.
Example
Open Compiler
import textwrap
text = '''
Python is a high-level, general-purpose programming language. Its
design philosophy emphasises code readability with the use of
significant indentation via the off-side rule.
Python is dynamically typed and garbage-collected. It supports multiple
programming paradigms, including structured (particularly procedural),
object-oriented and functional programming. It is often described as a
"batteries included" language due to its comprehensive standard
library.
'''
wrapper = textwrap.TextWrapper(width=40)
wrapped = wrapper.wrap(text = text)
# Print output
for element in wrapped:
print(element)
It will produce the following output −
Python is a high-level, general-purpose
programming language. Its design
philosophy emphasises code readability
with the use of significant indentation
via the off-side rule. Python is
dynamically typed and garbage-collected.
It supports multiple programming
paradigms, including structured
(particularly procedural), object oriented and functional programming.
It
is often described as a "batteries
included" language due to its
comprehensive standard library.
Example
Open Compiler
import textwrap
python_desc = """Python is a general-purpose interpreted, interactive,
object-oriented, and high-level programming language. It was created
by Guido van Rossum during 1985- 1990. Like Perl, Python source code
is also available under the GNU General Public License (GPL). This
tutorial gives enough understanding on Python programming
language."""
my_wrap = textwrap.TextWrapper(width = 40)
short_text = text wrap.shorten(text = python_desc, width=150)
print('\n\n' + my_wrap.fill(text = short_text))
PrettyPrinter Class
The pprint module contains the definition of PrettyPrinter class. Its
constructor takes following format −
Syntax
pprint.PrettyPrinter(indent, width, depth, stream, compact)
Parameters
1. indent − defines indentation added on each recursive level.
Default is 1.
2. width − by default is 80. Desired output is restricted by this
value. If the length is greater than width, it is broken in
multiple lines.
3. depth − controls number of levels to be printed.
4. stream − is by default std.out − the default output device. It
can take any stream object such as a file.
5. compact − id set to False by default. If true, only the data
adjustable within width will be displayed.
pprint() method
The pprint() method prints the formatted representation of a
PrettyPrinter object.
pformat() method
The pformat() method returns the formatted representation of the
object, based on parameters to the constructor.
Example
The following example demonstrates a simple use of PrettyPrinter class
−
Open Compiler
import pprint
students={"Dilip":["English", "Maths", "Science"],"Raju":
{"English":50,"Maths":60, "Science":70},"Kalpana":(50,60,70)}
pp=pprint.PrettyPrinter()
print ("normal print output")
print (students)
print ("----")
print ("pprint output")
pp.pprint(students)
Pretty printer can also be used with custom classes. Inside the class
__repr__() method is overridden. The __repr__() method is called when
repr() function is used. It is the official string representation of a Python
object. When we use an object as a parameter to the print() function it
prints the return value of the repr() function.
Example
In this example, the __repr__() method returns the string representation
of player object −
Open Compiler
import pprint
class player:
def __init__(self, name, formats=[], runs=[]):
self.name=name
self.formats=formats
self.runs=runs
def __repr__(self):
dct={}
dct[self.name]=dict(zip(self.formats,self.runs))
return (repr(dct))
l1=['Tests','ODI','T20']
l2=[[140, 45, 39],[15,122,36,67, 100, 49],[78,44, 12, 0, 23, 75]]
p1=player("virat",l1,l2)
pp=pprint.PrettyPrinter()
pp.pprint(p1)
Performance Measurement
A given problem may be solved by more than one alternative
algorithm. Hence, we need to optimise the performance of the solution.
Python's timeit module is a useful tool to measure the performance of
a Python application.
The timit() function in this module measures execution time of your
Python code.
Syntax
timeit.timeit(stmt, setup, timer, number)
Parameters
stmt − code snippet for measurement of performance.
setup − setup details arguments to be passed or variables.
timer − uses the default timer, so it may be skipped.
number − the code will be executed this number of times.
The default is 1000000.
Example
The following statement uses list comprehension to return a list of
multiple of 2 for each number in the range upto 100.
>>> [n*2 for n in range(100)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34,
36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68,
70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100,
102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126,
128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152,
154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178,
180, 182, 184, 186, 188, 190, 192, 194, 196, 198]
Now we shall find their respective execution time with timeit() function.
import timeit
setup1="""
from __main__ import fact
x = 10
"""
setup2="""
from __main__ import rfact
x = 10
"""
print ("Performance of factorial function with loop")
print(timeit.timeit(stmt = "fact(x)", setup=setup1, number=10000))
print ("Performance of factorial function with Recursion")
print(timeit.timeit(stmt = "rfact(x)", setup=setup2, number=10000))
Output
Performance of factorial function with loop
0.00330029999895487
Performance of factorial function with Recursion
0.006506800003990065
Data Compression
1 zlib
Compression compatible with gzip.
2 gzip
Support for gzip files.
3 bz2
Support for bz2 compression.
4 lzma
Compression using the LZMA
algorithm.
5 zipfile
Work with ZIP archives.
6 tarfilev
Read and write tar archive files.
CGI Programming
The Common Gateway Interface, or CGI, is a set of standards that
define how information is exchanged between the web server and a
custom script. The CGI specs are currently maintained by the NCSA.
What is CGI?
1. The Common Gateway Interface, or CGI, is a standard for
external gateway programs to interface with information
servers such as HTTP servers.
2. The current version is CGI/1.1 and CGI/1.2 is under progress.
Web Browsing
To understand the concept of CGI, let us see what happens when we
click a hyperlink to browse a particular web page or URL.
1. Your browser contacts the HTTP web server and demands for
the URL, i.e., filename.
2. Web Server parses the URL and looks for the filename. If it
finds that file then sends it back to the browser, otherwise
sends an error message indicating that you requested a wrong
file.
3. Web browser takes response from web server and displays
either the received file or error message.
The following line should also be added for apache server to treat .py
file as cgi script.
AddHandler cgi-script .py
Note − First line in the script must be the path to the Python
executable. It appears as a comment in a Python program, but it is
called shebang line.
In Linux, it should be #!/usr/bin/python3.
In Windows, it should be #!c:/python311/python.exd.
Enter the following URL in your browser −
http://localhost/cgi-bin/hello.py
Hello Word! This is my first CGI program
This hello.py script is a simple Python script, which writes its output on
STDOUT file, i.e., screen. There is one important and extra feature
available which is the first line to be printed Content-
type:text/html\r\n\r\n. This line is sent back to the browser and it
specifies the content type to be displayed on the browser screen.
By now you must have understood the basic concept of CGI and you
can write many complicated CGI programs using Python. This script can
interact with any other external system also to exchange information
such as RDBMS.
HTTP Header
The line Content-type:text/html\r\n\r\n is part of the HTTP header
which is sent to the browser to understand the content. All the HTTP
header will be in the following form −
HTTP Field Name: Field Content
For Example
Content-type: text/html\r\n\r\n
There are few other important HTTP headers, which you will use
frequently in your CGI Programming.
1 Content-type:
A MIME string defining the format of the file being returned.
Example is Content-type:text/html
2 Expires: Date
The date the information becomes invalid. It is used by the
browser to decide when a page needs to be refreshed. A valid
date string is in the format 01 Jan 1998 12:00:00 GMT.
3 Location: URL
The URL that is returned instead of the URL requested. You can
use this field to redirect a request to any file.
4 Last-modified: Date
The date of last modification of the resource.
5 Content-length: N
The length, in bytes, of the data being returned. The browser
uses this value to report the estimated download time for a
file.
6 Set-Cookie: String
Set the cookie passed through the string
1 CONTENT_TYPE
The data type of the content. Used when the client is sending
attached content to the server. For example, file upload.
2 CONTENT_LENGTH
The length of the query information. It is available only for
POST requests.
3 HTTP_COOKIE
Returns the set cookies in the form of key & value pair.
4 HTTP_USER_AGENT
The User-Agent request-header field contains information
about the user agent originating the request. It is the name of
the web browser.
5 PATH_INFO
The path for the CGI script.
6 QUERY_STRING
The URL-encoded information that is sent with the GET
method request.
7 REMOTE_ADDR
The IP address of the remote host making the request. This is
useful logging or for authentication.
8 REMOTE_HOST
The fully qualified name of the host making the request. If this
information is not available, then REMOTE_ADDR can be used
to get an IR address.
9 REQUEST_METHOD
The method used to make the request. The most common
methods are GET and POST.
10 SCRIPT_FILENAME
The full path to the CGI script.
11 SCRIPT_NAME
The name of the CGI script.
12 SERVER_NAME
The server's hostname or IP Address
13 SERVER_SOFTWARE
The name and version of the software the server is running.
Here is a small CGI program to list out all the CGI variables. Click this
link to see the result Get Environment
import os
print ("Content-type: text/html\r\n\r\n");
print ("<font size=+1>Environment</font><\br>");
for param in os.environ.keys():
print ("<b>%20s</b>: %s<\br>" % (param, os.environ[param]))
You can pass information by simply concatenating key and value pairs
along with any URL or you can use HTML <FORM> tags to pass
information using the GET method.
Given below is the hello_get.py script to handle the input given by the
web browser. We are going to use the cgi module, which makes it very
easy to access the passed information −
# Import modules for CGI handling
import cgi, cgitb
# Create instance of FieldStorage
form = cgi.FieldStorage()
# Get data from fields
first_name = form.getvalue('first_name')
last_name = form.getvalue('last_name')
print ("Content-type:text/html")
print()
print ("<html>")
print ('<head>')
print ("<title>Hello - Second CGI Program</title>")
print ('</head>')
print ('<body>')
print ("<h2>Hello %s %s</h2>" % (first_name, last_name))
print ('</body>')
print ('</html>')
Here is the actual output of the above form, you enter First and Last
Name and then click the submit button to see the result.
First Name:
Last Name:
Let us take again the same example as above which passes two values
using HTML FORM and submit button. We use the same CGI script
hello_get.py to handle this input.
<form action = "/cgi-bin/hello_get.py" method = "post">
First Name: <input type = "text" name = "first_name"><br />
Last Name: <input type = "text" name = "last_name" />
<input type = "submit" value = "Submit" />
</form>
Here is the actual output of the above form. You enter First and Last
Name and then click the submit button to see the result.
First Name:
Last Name:
Setting up Cookies
It is very easy to send cookies to the browser. These cookies are sent
along with the HTTP Header before to the Content-type field. Assuming
you want to set UserID and Password as cookies. Setting the cookies is
done as follows −
print "Set-Cookie:UserID = XYZ;\r\n"
print "Set-Cookie:Password = XYZ123;\r\n"
print "Set-Cookie:Expires = Tuesday, 31-Dec-2007 23:12:40 GMT;\r\n"
print "Set-Cookie:Domain = www.tutorialspoint.com;\r\n"
print "Set-Cookie:Path = /perl;\n"
print "Content-type:text/html\r\n\r\n"
...........Rest of the HTML Content....
From this example, you must have understood how to set cookies. We
use the Set-Cookie HTTP header to set cookies.
It is optional to set cookie attributes like Expires, Domain, and Path. It is
notable that cookies are set before sending the magic line "Content-
type:text/html\r\n\r\n.
Retrieving Cookies
It is very easy to retrieve all the set cookies. Cookies are stored in CGI
environment variable HTTP_COOKIE and they will have following form −
key1 = value1;key2 = value2;key3 = value3....
This produces the following result for the cookies set by above script −
User ID = XYZ
Password = XYZ123
else:
message = 'No file was uploaded'
print """\
Content-Type: text/html\n
<html>
<body>
<p>%s</p>
</body>
</html>
""" % (message,)
If you run the above script on Unix/Linux, then you need to take care of
replacing the file separator as follows, otherwise on your windows
machine the above open() statement should work fine.
fn = os.path.basename(fileitem.filename.replace("\\", "/" ))
XML Processing
What is XML?
The Extensible Markup Language (XML) is a markup language much like
HTML or SGML. This is recommended by the World Wide Web
Consortium and available as an open standard.
XML is extremely useful for keeping track of small to medium amounts
of data without requiring an SQL- based backbone.
The two most basic and broadly used APIs to XML data are the SAX and
DOM interfaces.
1. Simple API for XML (SAX) − Here, you register callbacks for
events of interest and then let the parser proceed through the
document. This is useful when your documents are large or
you have memory limitations, it parses the file as it reads it
from the disk and the entire file is never stored in the memory.
2. Document Object Model (DOM) − This is a World Wide Web
Consortium recommendation wherein the entire file is read
into the memory and stored in a hierarchical (tree-based) form
to represent all the features of an XML document.
Example
import xml.sax
class MovieHandler( xml.sax.ContentHandler ):
def __init__(self):
self.CurrentData = ""
self.type = ""
self.format = ""
self.year = ""
self.rating = ""
self.stars = ""
self.description = ""
# Call when an element starts
def startElement(self, tag, attributes):
self.CurrentData = tag
if tag == "movie":
print ("*****Movie*****")
title = attributes["title"]
print ("Title:", title)
# Call when an elements ends
def endElement(self, tag):
if self.CurrentData == "type":
print ("Type:", self.type)
elif self.CurrentData == "format":
print ("Format:", self.format)
elif self.CurrentData == "year":
print ("Year:", self.year)
elif self.CurrentData == "rating":
print ("Rating:", self.rating)
elif self.CurrentData == "stars":
print ("Stars:", self.stars)
elif self.CurrentData == "description":
print ("Description:", self.description)
self.CurrentData = ""
# Call when a character is read
def characters(self, content):
if self.CurrentData == "type":
self.type = content
elif self.CurrentData == "format":
self.format = content
elif self.CurrentData == "year":
self.year = content
elif self.CurrentData == "rating":
self.rating = content
elif self.CurrentData == "stars":
self.stars = content
elif self.CurrentData == "description":
self.description = content
if ( __name__ == "__main__"):
# create an XMLReader
parser = xml.sax.make_parser()
parser.parse("movies.xml")
You may now set up one or more child elements to be added under the
root element. Each child may have one or more sub elements. Add
them using the SubElement() function and define its text attribute.
child=xml.Element("employee")
nm = xml.SubElement(child, "name")
nm.text = student.get('name')
age = xml.SubElement(child, "salary")
age.text = str(student.get('salary'))
Example
In this example, a tree is constructed out of a list of dictionary items.
Each dictionary item holds key-value pairs describing a student data
structure. The tree so constructed is written to 'myfile.xml'
import xml.etree.ElementTree as et
employees=[{'name':'aaa','age':21,'sal':5000},
{'name':xyz,'age':22,'sal':6000}]
root = et.Element("employees")
for employee in employees:
child=xml.Element("employee")
root.append(child)
nm = xml.SubElement(child, "name")
nm.text = student.get('name')
age = xml.SubElement(child, "age")
age.text = str(student.get('age'))
sal=xml.SubElement(child, "sal")
sal.text=str(student.get('sal'))
tree = et.ElementTree(root)
with open('employees.xml', "wb") as fh:
tree.write(fh)
You can obtain the list of sub-elements one level below of an element.
children = list(root)
Example
Open Compiler
import xml.etree.ElementTree as et
tree = et.ElementTree(file='employees.xml')
root = tree.getroot()
employees=[]
children = list(root)
for child in children:
employee={}
pairs = list(child)
for pair in pairs:
employee[pair.tag]=pair.text
employees.append(employee)
print (employees)
GUI Programming
Python provides various options for developing graphical user
interfaces (GUIs). The most important features are listed below.
1. Tkinter − Tkinter is the Python interface to the Tk GUI toolkit
shipped with Python. We would look at this option in this
chapter.
2. wxPython − This is an open-source Python interface for
wxWidgets GUI toolkit. You can find a complete tutorial on
WxPython here.
3. PyQt − This is also a Python interface for a popular cross-
platform Qt GUI library. TutorialsPoint has a very good tutorial
on PyQt5 here.
4. PyGTK − PyGTK is a set of wrappers written in Python and C
for the GTK + GUI library. The complete PyGTK tutorial is
available here.
5. PySimpleGUI − PySimpleGui is an open source, cross-
platform GUI library for Python. It aims to provide a uniform
API for creating desktop GUIs based on Python's Tkinter,
PySide and WxPython toolkits. For a detaileD SimpleGUI
tutorial, click here.
6. Pygame − Pygame is a popular Python library used for
developing video games. It is a free, open source and cross-
platform wrapper around Simple DirectMedia Library (SDL).
For a comprehensive tutorial on Pygame, visit this link.
7. Jython − Jython is a Python port for Java, which gives Python
scripts seamless access to the Java class libraries on the local
machine http: //www.jython.org.
There are many other interfaces available, which you can find on the
net.
Tkinter Programming
Tkinter is the standard GUI library for Python. Python when combined
with Tkinter provides a fast and easy way to create GUI applications.
Tkinter provides a powerful object-oriented interface to the Tk GUI
toolkit.
The tkinter package includes following modules −
1. Tkinter − Main Tkinter module.
2. tkinter.color chooser − Dialog to let the user choose a
colour.
3. tkinter.commondialog − Base class for the dialogs defined
in the other modules listed here.
4. tkinter.filedialog − Common dialogs to allow the user to
specify a file to open or save.
5. tkinter.font − Utilities to help work with fonts.
6. tkinter.messagebox − Access to standard Tk dialog boxes.
7. tkinter.scrolledtext − Text widget with a vertical scroll bar
built in.
8. tkinter.simpledialog − Basic dialogs and convenience
functions.
9. tkinter.ttk − Themed widget set introduced in Tk 8.5,
providing modern alternatives for many of the classic widgets
in the main tkinter module.
Creating a GUI application using Tkinter is an easy task. All you need to
do is perform the following steps.
1. Import the Tkinter module.
2. Create the GUI application main window.
3. Add one or more of the above-mentioned widgets to the GUI
application.
4. Enter the main event loop to take action against each event
triggered by the user.
Example
# note that module name has changed from Tkinter in Python 2
# to tkinter in Python 3
import tkinter
top = tkinter.Tk()
# Code to add widgets will go here...
top.mainloop()
Tkinter Widgets
Tkinter provides various controls, such as buttons, labels and text
boxes used in a GUI application. These controls are commonly called
widgets.
There are currently 15 types of widgets in Tkinter. We present these
widgets as well as a brief description in the following table −
1 Button
The Button widget is used to display the buttons in your
application.
2 Canvas
The Canvas widget is used to draw shapes, such as lines,
ovals, polygons and rectangles, in your application.
3 Checkbutton
The Checkbutton widget is used to display a number of
options as checkboxes. The user can select multiple options at
a time.
4 Entry
The Entry widget is used to display a single-line text field for
accepting values from a user.
5 Frame
The Frame widget is used as a container widget to organise
other widgets.
6 Label
The Label widget is used to provide a single-line caption for
other widgets. It can also contain images.
7 Listbox
The Listbox widget is used to provide a list of options to a user.
8 Menubutton
The Menu Button widget is used to display menus in your
application.
9 Menu
The Menu widget is used to provide various commands to a
user. These commands are contained inside Menubutton.
10 Message
The Message widget is used to display multiline text fields for
accepting values from a user.
11 Radiobutton
The Radio Button widget is used to display a number of
options as radio buttons. The user can select only one option
at a time.
12 Scale
The Scale widget is used to provide a slider widget.
13 Scrollbar
The Scrollbar widget is used to add scrolling capability to
various widgets, such as list boxes.
14 Text
The Text widget is used to display text in multiple lines.
15 Toplevel
The Toplevel widget is used to provide a separate window
container.
16 Spinbox
The Spinbox widget is a variant of the standard Tkinter Entry
widget, which can be used to select from a fixed number of
values.
17 PanedWindow
A PanedWindow is a container widget that may contain any
number of panes, arranged horizontally or vertically.
18 LabelFrame
A labelframe is a simple container widget. Its primary purpose
is to act as a spacer or container for complex window layouts.
19 tkMessageBox
This module is used to display message boxes in your
applications.
Standard Attributes
Let us look at how some of the common attributes, such as sizes,
colours and fonts are specified.
1. Dimensions
2. Colours
3. Fonts
4. Anchors
5. Relief styles
6. Bitmaps
7. Cursors
Geometry Management
All Tkinter widgets have access to the specific geometry management
methods, which have the purpose of organising widgets throughout the
parent widget area. Tkinter exposes the following geometry manager
classes: pack, grid, and place.
1. The pack() Method − This geometry manager organises
widgets in blocks before placing them in the parent widget.
2. The grid() Method − This geometry manager organises
widgets in a table-like structure in the parent widget.
3. The place() Method − This geometry manager organises
widgets by placing them in a specific position in the parent
widget.
SimpleDialog
The simpledialog module in the tkinter package includes a dialog class
and convenience functions for accepting user input through a modal
dialog. It consists of a label, an entry widget and two buttons Ok and
Cancel. These functions are −
1. askfloat(title, prompt, **kw) − Accepts a floating point
number.
2. askinteger(title, prompt, **kw) − Accepts an integer
input.
3. askstring(title, prompt, **kw) − Accepts a text input from
the user.
The above three functions provide dialogs that prompt the user to enter
a value of the desired type. If Ok is pressed, the input is returned, if
Cancel is pressed, None is returned.
askinteger
from tkinter.simpledialog import askinteger
from tkinter import *
from tkinter import messagebox
top = Tk()
top.geometry("100x100")
def show():
num = askinteger("Input", "Input an Integer")
print(num)
askfloat
from tkinter.simpledialog import askfloat
from tkinter import *
top = Tk()
top.geometry("100x100")
def show():
num = askfloat("Input", "Input a floating point number")
print(num)
askstring
from tkinter.simpledialog import askstring
from tkinter import *
top = Tk()
top.geometry("100x100")
def show():
name = askstring("Input", "Enter you name")
print(name)
askopenfile
This function lets the user choose a desired file from the filesystem.
The file dialog window has Open and Cancel buttons. The file name
along with its path is returned when Ok is pressed, None if Cancel is
pressed.
from tkinter.filedialog import askopenfile
from tkinter import *
top = Tk()
top.geometry("100x100")
def show():
filename = askopenfile()
print(filename)
ttk module
The term ttk stands for Tk Themed widgets. The ttk module was
introduced with Tk 8.5 onwards. It provides additional benefits
including anti-aliased font rendering under X11 and window
transparency. It provides styling and styling support for Tkinter.
The ttk module comes bundled with 18 widgets, out of which 12 are
already present in Tkinter. Importing ttk over-writes these widgets with
new ones which are designed to have a better and more modern look
across all platforms.
The 6 new widgets in ttk are, the Combobox, Separator, Sizegrip,
Treeview, Notebook and ProgressBar.
To override the basic Tk widgets, the import should follow the Tk import
−
from tkinter import *
from tkinter.ttk import *
Combobox Widget
The Python ttk Combobox presents a drop down list of options and
displays them one at a time. It is a subclass of the widget Entry. Hence
it inherits many options and methods from the Entry class.
Syntax
from tkinter import ttk
Combo = ttk.Combobox(master, values.......)
Example
from tkinter import *
from tkinter import ttk
top = Tk()
top.geometry("200x150")
frame = Frame(top)
frame.pack()
langs = ["C", "C++", "Java",
"Python", "PHP"]
Progressbar
The ttk ProgressBar widget, and how it can be used to create loading
screens or show the progress of a current task.
Syntax
ttk.Progressbar(parent, orient, length, mode)
Parameters
1. Parent − The container in which the ProgressBar is to be
placed, such as root or a Tkinter frame.
2. Orient − Defines the orientation of the ProgressBar, which
can be either vertical or horizontal.
3. Length − Defines the width of the ProgressBar by taking in
an integer value.
4. Mode − There are two options for this parameter,
determinate and indeterminate.
Example
The code given below creates a progressbar with three buttons which
are linked to three different functions.
The first function increments the "value" or "progress" in the
progressbar by 20. This is done with the step() function which takes an
integer value to change the progress amount. (Default is 1.0)
The second function decrements the "value" or "progress" in the
progressbar by 20.
The third function prints out the current progress level in the
progressbar.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
frame= ttk.Frame(root)
def increment():
progressBar.step(20)
define decrement():
progressBar.step(-20)
def display():
print(progressBar["value"])
progressBar= ttk.Progressbar(frame, mode='determinate')
progressBar.pack(padx = 10, pady = 10)
button= ttk.Button(frame, text= "Increase", command= increment)
button.pack(padx = 10, pady = 10, side = to.LEFT)
button= ttk.Button(frame, text= "Decrease", command= decrement)
button.pack(padx = 10, pady = 10, side = to.LEFT)
button= ttk.Button(frame, text= "Display", command= display)
button.pack(padx = 10, pady = 10, side = to.LEFT)
frame.pack(padx = 5, pady = 5)
root.mainloop()
Syntax
notebook = ttk.Notebook(master, *options)
Example
In this example, add 3 windows to our Notebook widget in two different
ways. The first method involves the add() function, which simply
appends a new tab to the end. The other method is the insert() function
which can be used to add a tab to a specific position.
The add() function takes one mandatory parameter which is the
container widget to be added, and the rest are optional parameters
such as text (text to be displayed as tab title), image and compound.
The insert() function requires a tab_id, which defines the location where
it should be inserted. The tab_id can be either an index value or it can
be a string literal like "end", which will append it to the end.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
nb = ttk.Notebook(root)
# Frame 1 and 2
frame1 = ttk.Frame(nb)
frame2 = ttk.Frame(nb)
label1 = ttk.Label(frame1, text = "This is Window One")
label1.pack(pady = 50, padx = 20)
label2 = ttk.Label(frame2, text = "This is Window Two")
label2.pack(pady = 50, padx = 20)
frame1.pack(fill= tk.BOTH, expand=True)
frame2.pack(fill= tk.BOTH, expand=True)
nb.add(frame1, text = "Window 1")
nb.add(frame2, text = "Window 2")
frame3 = ttk.Frame(nb)
label3 = ttk.Label(frame3, text = "This is Window Three")
label3.pack(pady = 50, padx = 20)
frame3.pack(fill= tk.BOTH, expand=True)
nb.insert("end", frame3, text = "Window 3")
nb.pack(padx = 5, pady = 5, expand = True)
root.mainloop()
Treeview
The Treeview widget is used to display items in a tabular or hierarchical
manner. It has support for features like creating rows and columns for
items, as well as allowing items to have children as well, leading to a
hierarchical format.
Syntax
tree = ttk.Treeview(container, **options)
Options
Sr. Option & Description
No.
1 columns
A list of column names
2 displaycolumns
A list of column identifiers (either symbolic or integer indices)
specifying which data columns are displayed and the order in
which they appear, or the string "#all".
3 height
The number of rows visible.
4 padding
Specifies the internal padding for the widget. Can be either an
integer or a list of 4 values.
5 selectmode
One of "extended", "browse" or "none". If set to "extended"
(default), multiple items can be selected. If you "browse", only
a single item can be selected at a time. If "none", the selection
cannot be changed by the user.
6 show
A list containing zero or more of the following values,
specifying which elements of the tree to display. The default is
"tree headings", i.e., to show all elements.
Example
In this example we will create a simple Treeview ttk Widget and fill in
some data into it. We have some data already stored in a list which will
be read and added to the Treeview widget in our read_data() function.
We first need to define a list/tuple of column names. We have left out
the column "Name" because there already exists a (default) column
with a blank name.
We then assign that list/tuple to the columns option in Treeview,
followed by defining the "headings", where the column is the actual
column, whereas the heading is just the title of the column that
appears when the widget is displayed. We give each column a name.
"#0" is the name of the default column.
The tree.insert() function has the following parameters −
Parent − which is left as an empty string if there is none.
Position − where we want to add the new item. To append,
use tk.END
Iid − which is the item ID used to later track the item in
question.
Text − to which we will assign the first value in the list (the
name).
Syntax
sizegrip = ttk.Sizegrip(parent, **options)
Example
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
root.geometry("100x100")
frame = ttk.Frame(root)
label = ttk.Label(root, text = "Hello World")
label.pack(padx = 5, pady = 5)
sizegrip = ttk.Sizegrip(frame)
sizegrip.pack(expand = True, fill = tk.BOTH, anchor = tk.SE)
frame.pack(padx = 10, pady = 10, expand = True, fill = tk.BOTH)
root.mainloop()
Syntax
separator = ttk.Separator(parent, **options)
Example
Here we have created two Label widgets, and then created a Horizontal
Separator between them.
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
root.geometry("200x150")
frame = ttk.Frame(root)
label = ttk.Label(frame, text = "Hello World")
label.pack(padx = 5)
separator = ttk.Separator(frame,orient= tk.HORIZONTAL)
separator.pack(expand = True, fill = tk.X)
label = ttk.Label(frame, text = "Welcome To TutorialsPoint")
label.pack(padx = 5)
frame.pack(padx = 10, pady = 50, expand = True, fill = tk.BOTH)
root.mainloop()
Command-Line Arguments
Python Command Line Arguments
Python Command Line Arguments provides a convenient way to accept
some information at the command line while running the program. We
usually pass these values along with the name of the Python script.
To run a Python program, we execute the following command in the
command prompt terminal of the operating system. For example, in
Windows, the following command is entered in the Windows command
prompt terminal.
$ python script.py arg1 arg2 arg3
Here Python script name is script.py and rest of the three arguments -
arg1 arg2 arg3 are command line arguments for the program.
If the program needs to accept input from the user, Python's input()
function is used. When the program is executed from the command
line, user input is accepted from the command terminal.
Example
name = input("Enter your name: ")
print ("Hello {}. How are you?".format(name))
Here ren or mv are the commands which need the old and new file
names. Since they are put in line with the command, they are called
command-line arguments.
You can pass values to a Python program from the command line.
Python collects the arguments in a list object. Python's sys module
provides access to any command-line arguments via the sys.argv
variable. sys.argv is the list of command-line arguments and
sys.argv[0] is the program i.e. the script name.
Example
The hello.py script uses the input() function to accept user input after
the script is run. Let us change it to accept input from the command
line.
import sys
print ('argument list', sys.argv)
name = sys.argv[1]
print ("Hello {}. How are you?".format(name))
Example
In the following example, two numbers are entered as command-line
arguments. Inside the program, we use the int() function to parse them
as integer variables.
import sys
print ('argument list', sys.argv)
first = int(sys.argv[1])
second = int(sys.argv[2])
print ("sum = {}".format(first+second))
It will produce the following output −
C:\Python311>python hello.py 10 20
argument list ['hello.py', '10', '20']
sum = 30
getopt.getopt() method
This method parses the command line options and parameter list.
Following is a simple syntax for this method −
getopt.getopt(args, options, [long_options])
Exception getopt.GetoptError
This is raised when an unrecognised option is found in the argument list
or when an option requiring an argument is given none.
The argument to the exception is a string indicating the cause of the
error. The attributes msg and opt give the error message and related
option.
Example
Suppose we want to pass two file names through the command line
and we also want to give an option to check the usage of the script.
Usage of the script is as follows −
usage: test.py -i <input file> -o <output file>
The second command line usage gives the −help option which
produces a help message as shown. The −help parameter is available
by default.
Now let us define an argument which is mandatory for the script to run
and if not given, the script should throw an error. Here we define the
argument 'user' by the add_argument() method.
import argparse
parser=argparse.ArgumentParser(description="sample argument
parser")
parser.add_argument("user")
args=parser.parse_args()
if args.user=="Admin":
print ("Hello Admin")
else:
print ("Hello Guest")
This script's help now shows one positional argument in the form of
'user'. The program checks if its value is 'Admin' or not and prints the
corresponding message.
C:\Python311>python parser2.py --help
usage: parser2.py [-h] user
sample argument parser
positional arguments:
user
options:
-h, --help show this help message and exit
Note that if the value of the parameter is not from the list, invalid
choice error is displayed.
C:\Python311>python parser3.py Physics
My subject is Physics
C:\Python311>python parser3.py History
usage: parser3.py [-h] {Physics,Maths,Biology}
parser3.py: error: argument sub: invalid choice: 'History' (choose from
'Physics', 'Maths', 'Biology')
Command-Line Arguments
Python Command Line Arguments
Python Command Line Arguments provides a convenient way to accept
some information at the command line while running the program. We
usually pass these values along with the name of the Python script.
To run a Python program, we execute the following command in the
command prompt terminal of the operating system. For example, in
Windows, the following command is entered in the Windows command
prompt terminal.
$ python script.py arg1 arg2 arg3
Here Python script name is script.py and rest of the three arguments -
arg1 arg2 arg3 are command line arguments for the program.
If the program needs to accept input from the user, Python's input()
function is used. When the program is executed from the command
line, user input is accepted from the command terminal.
Example
name = input("Enter your name: ")
print ("Hello {}. How are you?".format(name))
Here ren or mv are the commands which need the old and new file
names. Since they are put in line with the command, they are called
command-line arguments.
You can pass values to a Python program from the command line.
Python collects the arguments in a list object. Python's sys module
provides access to any command-line arguments via the sys.argv
variable. sys.argv is the list of command-line arguments and
sys.argv[0] is the program i.e. the script name.
Example
The hello.py script uses the input() function to accept user input after
the script is run. Let us change it to accept input from the command
line.
import sys
print ('argument list', sys.argv)
name = sys.argv[1]
print ("Hello {}. How are you?".format(name))
Example
In the following example, two numbers are entered as command-line
arguments. Inside the program, we use the int() function to parse them
as integer variables.
import sys
print ('argument list', sys.argv)
first = int(sys.argv[1])
second = int(sys.argv[2])
print ("sum = {}".format(first+second))
getopt.getopt() method
This method parses the command line options and parameter list.
Following is a simple syntax for this method −
getopt.getopt(args, options, [long_options])
Exception getopt.GetoptError
This is raised when an unrecognised option is found in the argument list
or when an option requiring an argument is given none.
The argument to the exception is a string indicating the cause of the
error. The attributes msg and opt give the error message and related
option.
Example
Suppose we want to pass two file names through the command line
and we also want to give an option to check the usage of the script.
Usage of the script is as follows −
usage: test.py -i <input file> -o <output file>
The second command line usage gives the −help option which
produces a help message as shown. The −help parameter is available
by default.
Now let us define an argument which is mandatory for the script to run
and if not given, the script should throw an error. Here we define the
argument 'user' by the add_argument() method.
import argparse
parser=argparse.ArgumentParser(description="sample argument
parser")
parser.add_argument("user")
args=parser.parse_args()
if args.user=="Admin":
print ("Hello Admin")
else:
print ("Hello Guest")
This script's help now shows one positional argument in the form of
'user'. The program checks if its value is 'Admin' or not and prints the
corresponding message.
C:\Python311>python parser2.py --help
usage: parser2.py [-h] user
sample argument parser
positional arguments:
user
options:
-h, --help show this help message and exit
Note that if the value of the parameter is not from the list, invalid
choice error is displayed.
C:\Python311>python parser3.py Physics
My subject is Physics
C:\Python311>python parser3.py History
usage: parser3.py [-h] {Physics,Maths,Biology}
parser3.py: error: argument sub: invalid choice: 'History' (choose from
'Physics', 'Maths', 'Biology')
Docstrings
Docstrings in Python
In Python, docstrings are a way of documenting modules, classes,
functions, and methods. They are written within triple quotes (""" """)
and can span multiple lines.
Docstrings serve as a convenient way of associating documentation
with Python code. They are accessible through the __doc__ attribute of
the respective Python objects they document. Below are the different
ways to write docstrings −
Single-Line Docstrings
Single-line docstrings are used for brief and simple documentation.
They provide a concise description of what the function or method
does. Single-line docstrings should fit on one line within triple quotes
and end with a period.
Example
In the following example, we are using a single line docstring to write a
text −
Open Compiler
def add(a, b):
"""Return the sum of two numbers."""
return a + b
result = add(5, 3)
print("Sum:", result)
Multi-Line Docstrings
Multi-line docstrings are used for more detailed documentation. They
provide a more comprehensive description, including the parameters,
return values, and other relevant details. Multi-line docstrings start and
end with triple quotes and include a summary line followed by a blank
line and a more detailed description.
Example
The following example uses multi-line docstrings as an explanation of
the code −
Open Compiler
def multiply(a, b):
"""
Multiply two numbers and return the result.
Parameters:
a (int or float): The first number.
b (int or float): The second number.
Returns:
int or float: The result of multiplying a and b.
"""
return a * b
result = multiply(5, 3)
print("Product:", result)
Example
In this example, we demonstrate the use of docstrings for modules in
Python −
Open Compiler
import os
"""
This module provides Utility functions for file handling operations.
Functions:
- 'read_file(filepath)': Reads and returns the contents of the file.
- 'write_file(filepath, content)': Writes content to the specified file.
Classes:
- 'FileNotFoundError': Raised when a file is not found.
Example usage:
>>> import file_utils
>>> content = file_utils.read_file("example.txt")
>>> print(content)
'Hello, world!'
>>> file_utils.write_file("output.txt", "This is a test.")
"""
print("This is os module")
Accessing Docstrings
Docstrings in Python are accessed using the __doc__ attribute of the
object they document. This attribute contains the documentation string
(docstring) associated with the object, providing a way to access and
display information about the purpose and usage of functions, classes,
modules, or methods.
Example
In the following example, we are defining two functions, "add" and
"multiply", each with a docstring describing their parameters and
return values. We then use the "__doc__" attribute to access and print
these docstrings −
Open Compiler
# Define a function with a docstring
def add(a, b):
"""
Add two numbers together.
Parameters:
a (int): The first number.
b (int): The second number.
Returns:
int: The sum of a and b.
"""
return a + b
result = add(5, 3)
print("Sum:", result)
# Define another function with a docstring
def multiply(x, y):
"""
Multiplies two numbers together.
Parameters:
x (int): The first number.
y (int): The second number.
Returns:
int: The product of x and y.
"""
return x * y
result = multiply(4, 7)
print("Product:", result)
# Accessing the docstrings
print(add.__doc__)
print(multiply.__doc__)
Best Practices for Writing Docstrings
Following are the best practices for writing docstrings in Python −
1. Be Clear and Concise − Ensure the docstring clearly
explains the purpose and usage of the code, avoiding
unnecessary details.
2. Use Proper Grammar and Spelling − Ensure the docstring
is well-written with correct grammar and spelling.
3. Follow Conventions − Use the standard conventions for
formatting docstrings, such as the Google style, NumPy style,
or Sphinx style.
4. Include Examples − Provide examples where applicable to
illustrate how to use the documented code.
Example
Following is an example of a function with a Google style docstring −
Open Compiler
def divide(dividend, divisor):
"""
Divide two numbers and return the result.
Args:
dividend (float): The number to be divided.
divisor (float): The number to divide by.
Returns:
float: The result of the division.
Raises:
ValueError: If `divisor` is zero.
"""
if divisor == 0:
raise ValueError("Cannot divide by zero")
return dividend / divisor
result = divide(4, 7)
print("Division:", result)
Example
Following is an example of a function with a NumPy/SciPy style
docstring −
Open Compiler
def fibonacci(n):
"""
Compute the nth Fibonacci number.
Parameters
----------
n : int
The index of the Fibonacci number to compute.
Returns
-------
int
The nth Fibonacci number.
Examples
--------
>>> fibonacci(0)
0
>>> fibonacci(5)
5
>>> fibonacci(10)
55
"""
if n == 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
result = fibonacci(4)
print("Result:", result)
Example
Following is an example of a function with a Sphinx style docstring −
Open Compiler
def divide(dividend, divisor):
"""
Divide two numbers and return the result.
Args:
dividend (float): The number to be divided.
divisor (float): The number to divide by.
Returns:
float: The result of the division.
Raises:
ValueError: If `divisor` is zero.
"""
if divisor == 0:
raise ValueError("Cannot divide by zero")
return dividend / divisor
result = divide(76, 37)
print("Result:", result)
Docstring vs Comment
Following are the differences highlighted between Python docstrings
and comments, focusing on their purposes, formats, usages, and
accessibility respectively −
Docstring Comment
Written within triple quotes (""" Start with the # symbol and are
""" or ''' ''') and placed placed on the same line as the
immediately after the object's annotated code.
definition.
JSON
JSON in Python
JSON in Python is a popular data format used for data exchange
between systems. The json module provides functions to work with
JSON data, allowing you to serialise Python objects into JSON strings
and deserialize JSON strings back into Python objects.
JSON (JavaScript Object Notation) is a lightweight data interchange
format that is easy for humans to read and write, and easy for
machines to parse and generate. It is mainly used to transmit data
between a server and web application as text.
JSON Serialization
JSON serialisation is the process of converting a Python object into a
JSON format. This is useful for saving data in a format that can be easily
transmitted or stored, and later reconstructed back into its original
form.
Python provides the json module to handle JSON serialisation and
deserialization. We can use the json.dumps() method for serialisation in
this module.
You can serialise the following Python object types into JSON strings −
1. dict
2. list
3. tuple
4. str
5. int
6. float
7. bool
8. None
Example
Following a basic example of how to serialise a Python dictionary into a
JSON string −
Open Compiler
import json
# Python dictionary
data = {"name": "Alice", "age": 30, "city": "New York"}
# Serialise to JSON string
json_string = json.dumps(data)
print(json_string)
JSON Deserialization
JSON deserialization is the process of converting a JSON string back into
a Python object. This is essential for reading and processing data that
has been transmitted or stored in JSON format.
In Python, we can use the json.loads() method to deserialize JSON data
from a string, and the json.load() method to deserialize JSON data
from a file.
Example
In the example below, we are demonstrating the usage of custom
object serialisation −
Open Compiler
import json
from datetime import datetime
# Custom deserialization function
def custom_deserializer(dct):
if 'joined' in dct:
dct['joined'] = datetime.from isoformat(dct['joined'])
return dct
# JSON string with datetime
json_string = '{"name": "John", "joined": "2021-05-17T10:15:00"}'
# Deserialize with custom function
python_obj = json.loads(json_string, object_hook=custom_deserializer)
print(python_obj)
JSONEncoder Class
The JSONEncoder class in Python is used to encode Python data
structures into JSON format. Each Python data type is converted into its
corresponding JSON type, as shown in the following table −
Python JSON
Dict object
Str string
int, float, int- & float-derived numb
Enums er
True true
False false
None null
Example
In the following example, we are encoding a Python list object. We use
the iterencode() method to display each part of the encoded string −
Open Compiler
import json
data = ['Rakesh', {'marks': (50, 60, 70)}]
e = json.JSONEncoder()
# Using iterencode() method
for obj in e.iterencode(data):
print(obj)
JSONDecoder class
The JSONDecoder class is used to decode a JSON string back into a
Python data structure. The main method in this class is decode().
Example
In this example, the "JSONEncoder" is used to encode a Python list into
a JSON string, and the "JSONDecoder" is then used to decode the JSON
string back into a Python list −
Open Compiler
import json
data = ['Rakesh', {'marks': (50, 60, 70)}]
e = json.JSONEncoder()
s = e.encode(data)
d = json.JSONDecoder()
obj = d.decode(s)
print(obj, type(obj))
Sending Email
Sending Email in Python
You can send email in Python by using several libraries, but the most
common ones are smtplib and email.
The "smtplib" module in Python defines an SMTP client session object
that can be used to send mail to any Internet machine with an SMTP or
ESMTP listener daemon. The email "package" is a library for managing
email messages, including MIME and other RFC 2822-based message
documents.
An application that handles and delivers e-mail over the Internet is
called a "mail server". Simple Mail Transfer Protocol (SMTP) is a
protocol, which handles sending an e-mail and routing email between
mail servers. It is an Internet standard for email transmission.
Example
The following script connects to the SMTP server at
"smtp.example.com" on port 25, optionally identifies and secures the
connection, logs in (if required), sends an email, and then quits the
session −
import smtplib
# Create an SMTP object and establish a connection to the SMTP server
smtpObj = smtplib.SMTP('smtp.example.com', 25)
# Identify yourself to an ESMTP server using EHLO
smtpObj.ehlo()
# Secure the SMTP connection
smtpObj.starttls()
# Login to the server (if required)
smtpObj.login('username', 'password')
# Send an email
from_address = '[email protected]'
to_address = '[email protected]'
message = """\
Subject: Test Email
This is a test email message.
"""
smtpObj.sendmail(from_address, to_address, message)
# Quit the SMTP session
smtpObj.quit()
Example
The following example demonstrates how to send a dummy email using
the smtplib functionality along with the local SMTP debugging server −
import smtplib
def prompt(prompt):
return input(prompt).strip()
The sendmail() method of "smtplib" sends the email using the specified
sender, recipient(s), and message content to the local SMTP debugging
server running on "localhost" at port "1025".
Output
When you run the program, the console outputs the communication
between the program and the SMTP server. Meanwhile, the terminal
running the SMTPD server displays the incoming message content,
helping you debug and verify the email sending process.
python example.py
From: [email protected]
To: [email protected]
Enter message, end with ^D (Unix) or ^Z (Windows):
Hello World
^Z
Example
Following is an example script that demonstrates how to send an email
using Gmail's SMTP server −
import smtplib
# Email content
content = "Hello World"
# Set up SMTP connection to Gmail's SMTP server
mail = smtplib.SMTP('smtp.gmail.com', 587)
# Identify yourself to the SMTP server
mail.ehlo()
# Start TLS encryption for the connection
mail.starttls()
# Gmail account credentials
sender = '[email protected]'
password = 'your_password'
# Login to Gmail's SMTP server
mail.login(sender, password)
# Email details
recipient = '[email protected]'
subject = 'Test Email'
# Construct email message with headers
header = phoTo: {recipient}\nFrom: {sender}\nSubject: {subject}\n'
content = header + content
# Send email
mail.sendmail(sender, recipient, content)
# Close SMTP connection
mail.quit()
Before running the above script, the sender's gmail account must be
configured to allow access for 'less secure apps'. Visit the following link.
https://myaccount.google.com/lesssecureapps Set the shown toggle
button to ON.
If everything goes well, execute the above script. The message should
be delivered to the recipient's inbox.
Further Extensions
Any code that you write using any compiled language like C, C++, or
Java can be integrated or imported into another Python script. This
code is considered as an "extension."
A Python extension module is nothing more than a normal C library. On
Unix machines, these libraries usually end in .so (for shared objects).
On Windows machines, you typically see .dll (for dynamically linked
library).
The C Functions
The signatures of the C implementation of your functions always takes
one of the following three forms −
static PyObject *MyFunction(PyObject *self, PyObject *args);
static PyObject *MyFunction With Keywords(PyObject *self,
PyObject *args,
PyObject *kw);
static PyObject *MyFunction With No Args(PyObject *self);
This is a Python function called func inside the module module. You will
be putting pointers to your C functions into the method table for the
module that usually comes next in your source code.
Example
For the above-defined function, we have the following method mapping
table −
static PyMethodDef module_methods[] = {
{ "func", (PyCFunction)module_func, METH_NOARGS, NULL },
{ NULL, NULL, 0, NULL }
};
Example
A simple example that makes use of all the above concepts −
#include <Python.h>
static PyObject* helloworld(PyObject* self)
{
return Py_BuildValue("s", "Hello, Python extensions!!");
}
static char helloworld_docs[] =
"helloworld( ): Any message you want to put here!!\n";
static PyMethodDef helloworld_funcs[] = {
{"helloworld", (PyCFunction)helloworld,
METH_NOARGS, helloworld_docs},
{NULL}
};
void init hello world(void)
{
Py_InitModule3("helloworld", helloworld_funcs,
"Extension module example!");
}
Now, use the following command, which would perform all needed
compilation and linking steps, with the right compiler and linker
commands and flags, and copies the resulting dynamic library into an
appropriate directory −
$ python setup.py install
On Unix-based systems, you will most likely need to run this command
as root in order to have permissions to write to the site-packages
directory. This usually is not a problem on Windows.
Importing Extensions
Once you install your extensions, you would be able to import and call
that extension in your Python script as follows −
import helloworld
print helloworld.helloworld()
The method table containing an entry for the new function would look
like this −
static PyMethodDef module_methods[] = {
{ "func", (PyCFunction)module_func, METH_NOARGS, NULL },
{ "func", module_func, METH_VARARGS, NULL },
{ NULL, NULL, 0, NULL }
};
You can use the API PyArg_ParseTuple function to extract the arguments
from the one PyObject pointer passed into your C function.
The first argument to PyArg_ParseTuple is the args argument. This is
the object you will be parsing. The second argument is a format string
describing the arguments as you expect them to appear. Each
argument is represented by one or more characters in the format string
as follows.
static PyObject *module_func(PyObject *self, PyObject *args) {
int i;
double d;
char *s;
if (!PyArg_ParseTuple(args, "ids", &i, &d, &s)) {
return NULL;
}
/* Do something interesting here. */
Py_RETURN_NONE;
}
Compiling the new version of your module and importing it enables you
to invoke the new function with any number of arguments of any type
−
module.func(1, s="three", d=2.0)
module.func(i=1, d=2.0, s="three")
module.func(s="three", d=2.0, i=1)
This function returns 0 for errors, and a value not equal to 0 for
success. Tuple is the PyObject* That was the C function's second
argument. Here format is a C string that describes mandatory and
optional arguments.
Here is a list of format codes for the PyArg_ParseTuple function −
Co C type Meaning
de
Returning Values
Py_BuildValue takes in a format string much like PyArg_ParseTuple does.
Instead of passing in the addresses of the values you are building, you
pass in the actual values. Here is an example showing how to
implement an add function.
static PyObject *foo_add(PyObject *self, PyObject *args) {
int a;
int b;
if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
return NULL;
}
return Py_BuildValue("i", a + b);
}
You can return two values from your function as follows. This would be
captured using a list in Python.
static PyObject *foo_add_subtract(PyObject *self, PyObject *args) {
int a;
int b;
if (!PyArg_ParseTuple(args, "ii", &a, &b)) {
return NULL;
}
return Py_BuildValue("ii", a + b, a - b);
}
Here format is a C string that describes the Python object to build. The
following arguments of Py_BuildValue are C values from which the
result is built. ThePyObject* The result is a new reference.
The following table lists the commonly used code strings, of which zero
or more are joined into a string format.
Co C type Meaning
de
Tools/Utilities
The standard library comes with a number of modules that can be used
both as modules and as command-line utilities.
Example
import dis
def sum():
vara = 10
carb = 20
sum = vara + varb
print ("vara + varb = %d" % sum)
# Call dis function for the function.
dis.dis(sum)
Example
Before you try to run pdb.py, set your path properly to the Python lib
directory. So let us try with above example sum.py −
$pdb.py sum.py
> /test/sum.py(3)<module>()
-> import dis
(Pdb) n
> /test/sum.py(5)<module>()
-> def sum():
(Pdb) n
>/test/sum.py(14)<module>()
-> dis.dis(sum)
(Pdb) n
6 0 LOAD_CONST 1 (10)
3 STORE_FAST 0 (vara)
7 6 LOAD_CONST 2 (20)
9 STORE_FAST 1 (varb)
9 12 LOAD_FAST 0 (vara)
15 LOAD_FAST 1 (varb)
18 BINARY_ADD
19 STORE_FAST 2 (sum)
10 22 LOAD_CONST 3 ('vara + varb = %d')
25 LOAD_FAST 2 (sum)
28 BINARY_MODULO
29 PRINT_ITEM
30 PRINT_NEWLINE
31 LOAD_CONST 0 (None)
34 RETURN_VALUE
--Return--
> /test/sum.py(14)<module>()->None
-v dis.dis(sum)
(Pdb) n
--Return--
> <string>(1)<module>()->None
(Pdb)
Example
Let us try to profile the following program −
vara = 10
varb = 20
sum = vara + varb
print "vara + varb = %d" % sum
Example
Let us try to profile the following program −
vara = 10
varb = 20
sum = vara + varb
print "vara + varb = %d" % sum
If you would try a correct file with tabnanny.py, then it won't complain
as follows −
$tabnanny.py -v sum.py
'sum.py': Clean bill of health.
GUIs
In this chapter, you will learn about some popular Python IDEs
(Integrated Development Environment), and how to use IDE for
program development.
To use the scripted mode of Python, you need to save the sequence of
Python instructions in a text file and save it with the .py extension. You
can use any text editor available on the operating system. Whenever
the interpreter encounters errors, the source code needs to be edited
and run again and again. To avoid this tedious method, IDE is used. An
IDE is a one stop solution for typing, editing the source code, detecting
the errors and executing the program.
IDLE
Python's standard library contains the IDLE module. IDLE stands for
Integrated Development and Learning Environment. As the name
suggests, it is useful when one is in the learning stage. It includes a
Python interactive shell and a code editor, customised to the needs of
Python language structure. Some of its important features include
syntax highlighting, auto-completion, customizable interface etc.
To write a Python script, open a new text editor window from the File
menu.
A new editor window opens in which you can enter the Python code.
Save it and run it with the Run menu.
Jupyter Notebook
Initially developed as a web interface for IPython, Jupyter Notebook
supports multiple languages. The name itself derives from the
alphabets from the names of the supported languages − Julia, PYThon
and R. Jupyter notebook is a client server application. The server is
launched at the localhost, and the browser acts as its client.
Install Jupyter notebook with PIP −
pip3 install jupyter
Open a new Python notebook. It shows an IPython style input cell. Enter
Python instructions and run the cell.
Jupyter notebook is a versatile tool, used very extensively by data
scientists to display inline data visualisations. The notebook can be
conveniently converted and distributed in PDF, HTML or Markdown
format.
VS Code
Microsoft has developed a source code editor called VS Code (Visual
Studio Code) that supports multiple languages including C++, Java,
Python and others. It provides features such as syntax highlighting,
autocomplete, debugger and version control.
VS Code is freeware. It is available for download and install from
https://code.visualstudio.com/.
Launch VS Code from the start menu (in Windows).
You can also launch VS Code from command line −
C:\test>code .
After activating the Python extension, you need to set the Python
interpreter. Press Ctrl+Shift+P and select Python interpreter.
Open a new text file, enter Python code and save the file.
To execute the program, choose from the Run menu or use Shift+F10
shortcut.
Enforcing Implementation
When a class inherits from an Abstract Base Class (ABC) it must
implement all abstract methods. If it doesn't then Python will raise a
TypeError. Here is the example of enforcing implementation of the
Abstract Base Class in Python −
class Rectangle(Shape):
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
def perimeter(self):
return 2 * (self.width + self.height)
# This will work
rect = Rectangle(5, 10)
# This will raise TypeError
class IncompleteShape(Shape):
pass
Output
On executing the above code we will get the following output −
I am a shape.
Area: 50
Perimeter: 30
--------------------
I am a shape.
Area: 153.93804002589985
Perimeter: 43.982297150257104
--------------------
Can't instantiate abstract class IncompleteShape with abstract methods
area, perimeter
Print Page
Custom Exceptions
What are Custom Exceptions in Python?
Python custom exceptions are user-defined error classes that extend
the base Exception class. Developers can define and handle specific
error conditions that are unique to their application. Developers can
improve their code by creating custom exceptions. This allows for more
meaningful error messages and facilitates the debugging process by
indicating what kind of error occurred and where it originated.
To define a unique exception we have to typically create a new class
that takes its name from Python's built-in Exception class or one of its
subclasses. A corresponding except block can be used to raise this
custom class and catch it.
Developers can control the flow of the program when specific errors
occur and take appropriate actions such as logging the error, retrying
operations or gracefully shutting down the application. Custom
exceptions can carry additional context or data about the error by
overriding the __init__ method and storing extra information as
instance attributes.
Using custom exceptions improves the clarity of error handling in
complex programs. It helps to distinguish between different types of
errors that may require different handling strategies. For example when
a file parsing library might define exceptions like FileFormatError,
MissingFieldError or InvalidFieldError to handle various issues that can
arise during file processing. This level of granularity allows the client
code to catch and address specific issues more effectively by improving
the robustness and user experience of the software. Python's custom
exceptions are a great tool for handling errors and writing better with
more expressive code.
Output
On executing the above code we will get the following output −
Caught an exception: Value cannot be negative!
Example
Let's observe the following example for creating a higher order function
in Python. In this example, the multiplier function takes one
argument, a, and returns another function multiply, which calculates
the value a * b
Open Compiler
def multiplier(a):
# Nested function with second number
def multiply(b):
# Multiplication of two numbers
return a * b
return multiply
# Assigning nested multiply function to a variable
multiply_second_number = multiplier(5)
# Using variable as high order function
Result = multiply_second_number(10)
# Printing result
print("Multiplication of Two numbers is: ", Result)
Output
On executing the above program, you will get the following results −
Multiplication of Two numbers is: 50
Example
Here is another approach to creating higher-order functions is using
callable objects.
Open Compiler
class Multiplier:
def __init__(self, factor):
self.factor = factor
def __call__(self, x):
return self.factor * x
# Create an instance of the Multiplier class
multiply_second_number = Multiplier(2)
# Call the Multiplier object to computes factor * x
Result = multiply_second_number(100)
# Printing result
print("Multiplication of Two numbers is: ", Result)
Output
On executing the above program, you will get the following results −
Multiplication of Two numbers is: 200
Output
On executing the above program, you will get the following results −
Calling invite
Welcome to Tutorialspoint!
Output
On executing the above program, you will get the following results −
100
Output
On executing the above program, you will get the following results −
Factorial of 4: 24
Object Internals
Object Identity
Object Identity is the identity of an object which is an unique integer
that represents its memory address. It remains constant during the
object's lifetime. Every object in Python has a unique identifier obtained
using the id() function.
Example
Following is the example code of getting the Object Identity −
Open Compiler
a = "Tutorialspoint"
print(id(a)) # Example of getting the id of an string object
Note: The memory address will change on every execution of the code.
Object Type
Object Type is the type of an object that defines the operations that
can be performed on it. For example integers, strings and lists have
distinct types. It is defined by its class and can be accessed using the
type() function.
Example
Here is the example of it −
Open Compiler
a = "Tutorialspoint"
print(type(a))
Object Value
Object Value of an object is the actual data it holds. This can be a
primitive value like an integer or string, or it can be more complex data
structures like lists or dictionaries.
Example
Following is the example of the object value −
Open Compiler
b = "Welcome to Tutorialspoint"
print(b)
Memory Management
Memory management in Python is a critical aspect of the language's
design by ensuring efficient use of resources while handling object
lifetimes and garbage collection. Here are the key components of
memory management in Python −
1. Reference Counting: Python uses reference counting to
manage memory. Each object keeps track of how many
references point to it. When this count drops to zero then the
memory can be freed.
2. Garbage Collection: In addition to reference counting the
Python employs a garbage collector to identify and clean up
reference cycles.
Example
Following is the example of the getting the reference counting in
memory management −
Open Compiler
import sys
c = [1, 2, 3]
print(sys.getrefcount(c)) # Shows the reference count
Example
Open Compiler
class MyClass:
def __init__(self, value):
self.value = value
def display(self):
print(self.value)
obj = MyClass(10)
obj.display()
Memory Management
In Python, memory management is automatic, it involves handling a
private heap that contains all Python objects and data structures. The
Python memory manager internally ensures the efficient allocation and
deallocation of this memory. This tutorial will explore Python's memory
management mechanisms, including garbage collection, reference
counting, and how variables are stored on the stack and heap.
On executing the above program, you will get the following output −
(5, True, 'Hello')
Traceback (most recent call last):
File "/home/cg/root/71937/main.py", line 8, in <module>
print(x, y, z)
NameError: name 'x' is not defined
Output
On executing the above program, you will get the following results −
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Reference Counting
Python's primary garbage collection mechanism is reference counting.
Every object in Python maintains a reference count that tracks how
many aliases (or references) point to it. When an object's reference
count drops to zero, the garbage collector deallocates the object.
Working of the reference counting as follows −
Increasing Reference Count− It happens when a new
reference to an object is created, the reference count
increases.
Decreasing Reference Count− When a reference to an
object is removed or goes out of scope, the reference count
decreases.
Example
Here is an example that demonstrates the working of reference
counting in Python.
Open Compiler
import sys
# Create a string object
name = "Tutorialspoint"
print("Initial reference count:", sys.getrefcount(name))
# Assign the same string to another variable
other_name = "Tutorialspoint"
print("Reference count after assignment:", sys.getrefcount(name))
# Concatenate the string with another string
string_sum = name + ' Python'
print("Reference count after concatenation:", sys.getrefcount(name))
# Put the name inside a list multiple times
list_of_names = [name, name, name]
print("Reference count after creating a list with 'name' 3 times:",
sys.getrefcount(name))
# Deleting one more reference to 'name'
del other_name
print("Reference count after deleting 'other_name':",
sys.getrefcount(name))
# Deleting the list reference
del list_of_names
print("Reference count after deleting the list:", sys.getrefcount(name))
Output
On executing the above program, you will get the following results −
Initial reference count: 4
Reference count after assignment: 5
Reference count after concatenation: 5
Reference count after creating a list with 'name' 3 times: 8
Reference count after deleting 'other_name': 7
Reference count after deleting the list: 4
Metaclasses
Example
Let's observe the result of creating a class object without specifying
specific bases or a metaclass
Open Compiler
class Demo:
pass
obj = Demo()
print(obj)
Output
On executing the above program, you will get the following results −
<__main__.Demo object at 0x7fe78f43fe80>
Example
In this example, DemoClass will be created using the type() function,
and an instance of this class is also created and displayed.
Open Compiler
# Creating a class dynamically using type()
DemoClass = type('DemoClass', (), {})
obj = DemoClass()
print(obj)
Output
Upon executing the above program, you will get the following results −
<__main__.DemoClass object at 0x7f9ff6af3ee0>
Example
Here is another example of creating a Metaclass with inheritance
which can be done by inheriting one from another class using type()
function.
Open Compiler
class Demo:
pass
Demo2 = type('Demo2', (Demo,), dict(attribute=10))
obj = Demo2()
print(obj.attribute)
print(obj.__class__)
print(obj.__class__.__bases__)
Output
Following is the output −
10
<class '__main__.Demo2'>
(<class '__main__.Demo'>,)
Example
Let's see the example of demonstrating how we can customise class
creation using the __new__ method of a metaclass in python.
Open Compiler
# Define a custom metaclass
class MyMetaClass(type):
def __new__(cls, name, bases, dct):
dct['version'] = 1.0
# Modify the class name
name = 'Custom' + name
return super().__new__(cls, name, bases, dct)
# MetaClass acts as a template for the custom metaclass
class Demo(metaclass=MyMetaClass):
pass
# Instantiate the class
obj = Demo()
# Print the class name and version attribute
print("Class Name:", type(obj).__name__)
print("Version:", obj.version)
Output
While executing above code, you will get the following results −
Class Name: CustomDemo
Version: 1.0
Example
Here is another example that demonstrates how to customise the
metaclass using the __init__ in Python.
Open Compiler
# Define a custom metaclass
class 2yCreating MetaClass(type):
def __init__(cls, name, bases, dct):
print('Initializing class', name)
# Add a class-level attribute
cls.version= 10
super().__init__(name, bases, dct)
# Define a class using the custom metaclass
class MyClass(metaclass=MyMetaClass):
def __init__(self, value):
self.value = value
def display(self):
print(f"Value: {self.value}, Version: {self.__class__.version}")
# Instantiate the class and demonstrate its usage
obj = MyClass(42)
obj.display()
Output
While executing above code, you will get the following results −
Initializing class MyClass
Value: 42, Version: 10
Metaprogramming with
Metaclasses
Defining Metaclasses
Metaprogramming with metaclasses in Python offer advanced features
of enabling advanced capabilities to your program. One such feature is
the __prepare__() method, which allows customization of the
namespace where a class body will be executed.
This method is called before any class body code is executed, providing
a way to initialise the class namespace with additional attributes or
methods. The __prepare__() method should be implemented as a
classmethod.
Example
Here is an example of creating a metaclass with advanced features
using the __prepare__() method.
Open Compiler
class MyMetaClass(type):
@classmethod
def __prepare__(cls, name, bases, **kwargs):
print(Preparing namespace for {name}')
# Customise the namespace preparation here
custom_namespace = super().__prepare__(name, bases, **kwargs)
custom_namespace['CONSTANT_VALUE'] = 100
return custom_namespace
# Define a class using the custom metaclass
class MyClass(metaclass=MyMetaClass):
def __init__(self, value):
self.value = value
def display(self):
print(f"Value: {self.value}, Constant:
{self.__class__.CONSTANT_VALUE}")
# Instantiate the class
obj = MyClass(42)
obj.display()
Output
While executing above code, you will get the following results −
Preparing namespace for MyClass
Value: 42, Constant: 100
Example
This example demonstrates how metaclasses in Python
metaprogramming can be used for dynamic code generation.
Open Compiler
class MyMeta(type):
def __new__(cls, name, bases, attrs):
print(f"Defining class: {name}")
# Dynamic attribute to the class
attrs['dynamic_attribute'] = 'Added dynamically'
# Dynamic method to the class
def dynamic_method(self):
return f"This is a dynamically added method for {name}"
attrs['dynamic_method'] = dynamic_method
return super().__new__(cls, name, bases, attrs)
# Define a class using the metaclass
class MyClass(metaclass=MyMeta):
pass
obj = MyClass()
print(obj.dynamic_attribute)
print(obj.dynamic_method())
Output
On executing above code, you will get the following results −
Defining class: MyClass
Added dynamically
This is a dynamically added method for MyClass
Example
In this example, the MyMeta metaclass inspects and prints the
attributes of the MyClass during its creation, demonstrating how
metaclasses can introspect and modify class definitions dynamically.
Open Compiler
class MyMeta(type):
def __new__(cls, name, bases, dct):
# Inspect class attributes and print them
print(f"Class attributes for {name}: {dct}")
return super().__new__(cls, name, bases, dct)
class MyClass(metaclass=MyMeta):
data = "example"
Output
On executing above code, you will get the following results −
Class attributes for MyClass: {'__module__': '__main__', '__qualname__':
'MyClass', 'data': 'example'}
Print Page
Python Mocking
Mocking is a testing technique in which mock objects are created to
simulate the behaviour of real objects.
This is useful when testing a piece of code that interacts with complex,
unpredictable or slow components such as databases, web services or
hardware devices.
The primary purpose of mocking is to isolate the code under test and
ensure that its behaviour is evaluated independently of its
dependencies.
Output
{'name': 'Prasad', 'age': 30}
Python Stubbing
Stubbing is a related testing technique where certain methods or
functions are replaced with "stubs" that return fixed, predetermined
responses.
Stubbing is simpler than mocking because it typically does not involve
recording or verifying interactions. Instead, stubbing focuses on
providing controlled inputs to the code under test by ensuring
consistent and repeatable results.
Output
{'name': 'Prasad', 'age': 25}
Monkey Patching
Monkey patching in Python refers to the practice of dynamically
modifying or extending code at runtime typically replacing or adding
new functionalities to existing modules, classes or methods without
altering their original source code. This technique is often used for
quick fixes, debugging or adding temporary features.
The term "monkey patching" originates from the idea of making
changes in a way that is ad-hoc or temporary, akin to how a monkey
might patch something up using whatever materials are at hand.
Signal Handling
Signal handling in Python allows you to define custom handlers for
managing asynchronous events such as interrupts or termination
requests from keyboard, alarms, and even system signals. You can
control how your program responds to various signals by defining
custom handlers. The signal module in Python provides mechanisms to
set and manage signal handlers.
A signal handler is a function that gets executed when a specific
signal is received. The signal.signal() function allows defining custom
handlers for signals. The signal module offers a way to define custom
handlers that will be executed when a specific signal is received. Some
default handlers are already installed in Python, which are −
SIGPIPE is ignored.
SIGINT is translated into a KeyboardInterrupt exception.
Example
Here is an example of setting a signal handler using the
signal.signal() function with the SIGINT handler.
import signal
import time
def handle_signal(signum, frame):
print(f"Signal {signum} received")
# Setting the handler for SIGINT
signal.signal(signal.SIGINT, handle_signal)
print("Press Ctrl+C to trigger SIGINT")
while True:
time.sleep(1)
Output
On executing the above program, you will get the following results −
Press Ctrl+C to trigger SIGINT
Signal 2 received
Signal 2 received
Signal 2 received
Signal 2 received
Example
Let's observe the following example of handling alarms.
import signal
import time
def handler(signum, stack):
print('Alarm: ', time.ctime())
signal.signal(signal.SIGALRM, handler)
signal.alarm(2)
time.sleep(5)
for i in range(5):
signal.alarm(2)
time.sleep(5)
print("interrupted #%d" % i)
Output
On executing the above program, you will get the following results −
Alarm: Wed Jul 17 17:30:11 2024
Alarm: Wed Jul 17 17:30:16 2024
interrupted #0
Alarm: Wed Jul 17 17:30:21 2024
interrupted #1
Alarm: Wed Jul 17 17:30:26 2024
interrupted #2
Alarm: Wed Jul 17 17:30:31 2024
interrupted #3
Alarm: Wed Jul 17 17:30:36 2024
interrupted #4
Example
This example creates a dictionary where the keys are signal numbers
and the values are the corresponding signal names. This is useful for
dynamically resolving signal names from their numeric values.
Open Compiler
import signal
sig_items = reversed(sorted(signal.__dict__.items()))
final = dict((k, v) for v, k in sig_items if v.startswith('SIG') and not
v.startswith('SIG_'))
print(final)
Output
On executing the above program, you will get the following results −
{<Signals.SIGXFSZ: 25>: 'SIGXFSZ', <Signals.SIGXCPU: 24>:
'SIGXCPU', <Signals.SIGWINCH: 28>: 'SIGWINCH', <Signals.SIGVTALRM:
26>: 'SIGVTALRM', <Signals.SIGUSR2: 12>: 'SIGUSR2',
<Signals.SIGUSR1: 10>: 'SIGUSR1', <Signals.SIGURG: 23>: 'SIGURG',
<Signals.SIGTTOU: 22>: 'SIGTTOU', <Signals.SIGTTIN: 21>: 'SIGTTIN',
<Signals.SIGTSTP: 20>: 'SIGTSTP', <Signals.SIGTRAP: 5>: 'SIGTRAP',
<Signals.SIGTERM: 15>: 'SIGTERM', <Signals.SIGSYS: 31>: 'SIGSYS',
<Signals.SIGSTOP: 19>: 'SIGSTOP', <Signals.SIGSEGV: 11>: 'SIGSEGV',
<Signals.SIGRTMIN: 34>: 'SIGRTMIN', <Signals.SIGRTMAX: 64>:
'SIGRTMAX', <Signals.SIGQUIT: 3>: 'SIGQUIT', <Signals.SIGPWR: 30>:
'SIGPWR', <Signals.SIGPROF: 27>: 'SIGPROF', <Signals.SIGIO: 29>:
'SIGIO', <Signals.SIGPIPE: 13>: 'SIGPIPE', <Signals.SIGKILL: 9>:
'SIGKILL', <Signals.SIGABRT: 6>: 'SIGABRT', <Signals.SIGINT: 2>:
'SIGINT', <Signals.SIGILL: 4>: 'SIGILL', <Signals.SIGHUP: 1>: 'SIGHUP',
<Signals.SIGFPE: 8>: 'SIGFPE', <Signals.SIGCONT: 18>: 'SIGCONT',
<Signals.SIGCHLD: 17>: 'SIGCHLD', <Signals.SIGBUS: 7>: 'SIGBUS',
<Signals.SIGALRM: 14>: 'SIGALRM'}
Type Hints
Python type hints were introduced in PEP 484 to bring the benefits of
static typing to a dynamically typed language. Although type hints do
not enforce type checking at runtime, they provide a way to specify the
expected types of variables, function parameters, and return values,
which can be checked by static analysis tools such as mypy . This
enhances code readability, facilitates debugging, and improves the
overall maintainability of the code.
Type hints in Python use annotations for function parameters, return
values and variable assignments.
Python's type hints can be used to specify a wide variety of types
such as basic data types, collections, complex types and custom user-
defined types. The typing module provides many built-in types to
represent these various types −
1. Basic Data Types
2. Collections Types
3. Optional Types
4. Union Types
5. Any Type
6. Type Aliases
7. Generic Types
8. Callable Types
9. Literal Types
10. NewType
Example
Following is the example of using the basic data types such as integer,
float, string etc −
Open Compiler
from typing import Optional
# Integer type
def calculate_square_area(side_length: int) -> int:
return side_length ** 2
# Float type
def calculate_circle_area(radius: float) -> float:
return 3.14 * radius * radius
# String type
def greet(name: str) -> str:
return f"Hello, {name}"
# Boolean type
def is_adult(age: int) -> bool:
return age >= 18
# None type
def no_return_example() -> None:
print("This function does not return anything")
# Optional type (Union of int or None)
def safe_divide(x: int, y: Optional[int]) -> Optional[float]:
if y is None or y == 0:
return None
else:
return x / y
# Example usage
print(calculate_square_area(5))
print(calculate_circle_area(3.0))
print(greet("Alice"))
print(is_adult(22))
no_return_example()
print(safe_divide(10, 2))
print(safe_divide(10, 0))
print(safe_divide(10, None))
Collections Types
In Python when dealing with collections such as lists, tuples,
dictionaries, etc. in type hints we typically use the typing module to
specify the collection types.
Example
Below is the example of the Collections using in type hints −
Open Compiler
from typing import List, Tuple, Dict, Set, Iterable, Generator
# List of integers
def process_numbers(numbers: List[int]) -> List[int]:
return [num * 2 for num in numbers]
# Tuple of floats
def coordinates() -> Tuple[float, float]:
return (3.0, 4.0)
# Dictionary with string keys and integer values
def frequency_count(items: List[str]) -> Dict[str, int]:
freq = {}
for item in items:
freq[item] = freq.get(item, 0) + 1
return freq
# Set of unique characters in a string
def unique_characters(word: str) -> Set[str]:
return set(word)
# Iterable of integers
def print_items(items: Iterable[int]) -> None:
for item in items:
print(item)
# Generator yielding squares of integers up to n
def squares(n: int) -> Generator[int, None, None]:
for i in range(n):
yield i * i
# Example usage
numbers = [1, 2, 3, 4, 5]
print(process_numbers(numbers))
print(coordinates())
items = ["apple", "banana", "apple", "orange"]
print(frequency_count(items))
word = "hello"
print(unique_characters(word))
print_items(range(5))
gen = squares(5)
print(list(gen))
Optional Types
In Python, Optional types are used to indicate that a variable can
either be of a specified type or None. This is particularly useful when a
function may not always return a value or when a parameter can
accept a value or be left unspecified.
Example
Here is the example of using the optional types in type hints −
Open Compiler
from typing import Optional
def divide(a: float, b: float) -> Optional[float]:
if b == 0:
return None
else:
return a / b
result1: Optional[float] = divide(10.0, 2.0) # result1 will be 5.0
result2: Optional[float] = divide(10.0, 0.0) # result2 will be None
print(result1)
print(result2)
Union Types
Python uses Union types to allow a variable to accept values of
different types. This is useful when a function or data structure can
work with various types of inputs or produce different types of outputs.
Example
Below is the example of this −
Open Compiler
from typing import Union
def square_root_or_none(number: Union[int, float]) -> Union[float,
None]:
if number >= 0:
return number ** 0.5
else:
return None
result1: Union[float, None] = square_root_or_none(50)
result2: Union[float, None] = square_root_or_none(-50)
print(result1)
print(result2)
On executing the above code we will get the following output −
7.0710678118654755
None
Any Type
In Python, Any type is a special type hint that indicates that a variable
can be of any type. It essentially disables type checking for that
particular variable or expression. This can be useful in situations where
the type of a value is not known beforehand or when dealing with
dynamic data.
Example
Following is the example of using Any type in Type hint −
Open Compiler
from typing import Any
def print_value(value: Any) -> None:
print(value)
print_value(10)
print_value("hello")
print_value(True)
print_value([1, 2, 3])
print_value({'key': 'value'})
Type Aliases
Type aliases in Python are used to give alternative names to existing
types. They can make code easier to read by giving clear names to
complicated type annotations or combinations of types. This is
especially helpful when working with nested structures or long-type
hints.
Example
Below is the example of using the Type Aliases in the Type hints −
Open Compiler
from typing import List, Tuple
# Define a type alias for a list of integers
Vector = List[int]
# Define a type alias for a tuple of coordinates
Coordinates = Tuple[float, float]
# Function using the type aliases
def scale_vector(vector: Vector, factor: float) -> Vector:
return [int(num * factor) for num in vector]
def calculate_distance(coord1: Coordinates, coord2: Coordinates) ->
float:
x1, y1 = coord1
x2, y2 = coord2
return ((x2 - x1) ** 2 + (y2 - y1) ** 2) ** 0.5
# Using the type aliases
v: Vector = [1, 2, 3, 4]
scaled_v: Vector = scale_vector(v, 2.5)
print(scaled_v)
c1: Coordinates = (3.0, 4.0)
c2: Coordinates = (6.0, 8.0)
distance: float = calculate_distance(c1, c2)
print(distance)
Generic Types
Generic types create functions, classes or data structures that can
handle any type while maintaining type safety. The typing module's
TypeVar and Generic constructs make this possible. They are helpful for
making reusable components that can work with various types without
compromising type checking.
Example
Here is the example of it −
Open Compiler
from typing import TypeVar, List
# Define a type variable T
T = TypeVar('T')
# Generic function that returns the first element of a list
def first_element(items: List[T]) -> T:
return items[0]
# Example usage
int_list = [1, 2, 3, 4, 5]
str_list = ["apple", "banana", "cherry"]
first_int = first_element(int_list) # first_int will be of type int
first_str = first_element(str_list) # first_str will be of type str
print(first_int)
print(first_str)
Callable Types
Python's Callable type is used to show that a type is a function or a
callable object. It is found in the typing module and lets you define the
types of the arguments and the return type of a function. This is handy
for higher-order functions.
Example
Following is the example of using Callable type in type hint −
Open Compiler
from typing import Callable
# Define a function that takes another function as an argument
def apply_operation(x: int, y: int, operation: Callable[[int, int], int]) ->
int:
return operation(x, y)
# Example functions to be passed as arguments
def add(a: int, b: int) -> int:
return a + b
def multiply(a: int, b: int) -> int:
return a * b
# Using the apply_operation function with different operations
result1 = apply_operation(5, 3, add) # result1 will be 8
result2 = apply_operation(5, 3, multiply) # result2 will be 15
print(result1)
print(result2)
Literal Types
The Literal type is used to specify that a value must be exactly one of a
set of predefined values.
Example
Below is the example −
Open Compiler
from typing import Literal
def move(direction: Literal["left", "right", "up", "down"]) -> None:
print(f"Moving {direction}")
move("left") # Valid
move("up") # Valid
NewType
NewType is a function in the typing module that allows us to create
distinct types derived from existing ones. This can be useful for adding
type safety to our code by distinguishing between different uses of the
same underlying type. For example we might want to differentiate
between user IDs and product IDs even though both are represented as
integers.
Example
Below is the example −
Open Compiler
from typing import NewType
# Create new types
UserId = NewType('UserId', int)
ProductId = NewType('ProductId', int)
# Define functions that use the new types
def get_user_name(user_id: UserId) -> str:
return f"User with ID {user_id}"
def get_product_name(product_id: ProductId) -> str:
return f"Product with ID {product_id}"
# Example usage
user_id = UserId(42)
product_id = ProductId(101)
print(get_user_name(user_id)) # Output: User with ID 42
print(get_product_name(product_id)) # Output: Product with ID
101
In this tutorial you will learn about the various aspects of automation
using Python, from scheduling tasks with schedule module, web
scraping with BeautifulSoup, and GUI automation with
BeautifulSoup.
Here we are providing practical examples and please ensure that you
have the necessary modules installed before executing the provided
codes in your local system using the below commands in your
command prompt −
pip install schedule
pip install beautifulsoup4
pip install pyautogui
Example
This example demonstrates the application of Python for automating
routine tasks such as scheduling weekly meetings, setting alarms, and
more, using Python's schedule module.
import schedule
import time
# Function definitions for scheduled tasks
def alarm():
print("Time to restart the server ")
def job():
print("Starting daily tasks ")
def meet():
print('Weekly standup meeting ')
# Schedule tasks
schedule.every(5).seconds.do(alarm) # Run every 5 seconds
schedule.every().day.at("10:30").do(job) # Run daily at 10:30 AM
schedule.every().monday.at("12:15").do(meet) # Run every Monday at
12:15 PM
# Main loop to execute scheduled tasks
while True:
schedule.run_pending()
time.sleep(0.5)
Output
On executing the above code we will get the following output −
Time to restart the server
Time to restart the server
Time to restart the server
...
Example
This example demonstrates how to use BeautifulSoup and the
urllib.request module to scrape a webpage for URLs containing the
keyword "python".
from bs4 import BeautifulSoup
from urllib.request import urlopen
import re
html = urlopen("https://www.tutorialspoint.com/python/index.htm")
content = html.read()
soup = BeautifulSoup(content, "html.parser")
for a in soup.findAll('a',href=True):
if re.findall('python', a['href']):
print("Python URL:", a['href'])
Output
On executing the above code we will get the following output −
Python URL: /machine_learning_with_python/index.htm
Python URL: /python_pandas/index.htm
Python URL: /python/index.htm
Python URL: /python/index.htm
Python URL: /python_pandas/index.htm
Python URL: /python_pillow/index.htm
Python URL: /machine_learning_with_python/index.htm
Python URL: /python_technologies_tutorials.htm
Python URL: /python/index.htm
....
Example
This example demonstrates how Python's pyautogui module can be
used to automate mouse movements in a square pattern.
import pyautogui
# Move the mouse in a larger square pattern
for i in range(5):
pyautogui.moveTo(300, 100, duration=0.25)
pyautogui.move(300, 0, duration=0.25)
pyautogui.move(0, 300, duration=0.25)
pyautogui.move(-300, 0, duration=0.25)
pyautogui.move(0, -300, duration=0.25)
Output
On executing the above code we will get the following output −
Example
This example demonstrates how to use the unittest module in Python
to perform automated testing on string methods. Each test case
method begins with the prefix test_, which is recognized by the
unittest framework as a method to run.
Open Compiler
# importing unittest module
import unittest
class TestingStringMethods(unittest.TestCase):
# string equal
def test_string_equality(self):
# if both arguments are then it's succes
self.assertEqual('ttp' * 5, 'taptaptaptaptap')
# comparing the two strings
def test_string_case(self):
# if both arguments are then it's succes
self.assertEqual('Tutorialspoint'.upper(), 'TUTORIALSPOINT')
# checking whether a string is upper or not
def test_is_string_upper(self):
# used to check whether the statement is True or False
self.assertTrue('TUTORIALSPOINT'.isupper())
self.assertFalse('TUTORIALSpoint'.isupper())
def test_string_startswith(self):
# Used the startswith() to identify the start of the string
self.assertTrue('tutorialspoint'.startswith('putor'))
self.assertFalse('tutorialspoint'.startswith('point'))
# running the tests
unittest.main(verbosity=2)
Output
On executing the above code we will get the following output −
test_is_string_upper (__main__.TestingStringMethods) ... ok
test_string_case (__main__.TestingStringMethods) ... ok
test_string_equality (__main__.TestingStringMethods) ... ok
test_string_startswith (__main__.TestingStringMethods) ... FAIL
===========================================
===========================
FAIL: test_string_startswith (__main__.TestingStringMethods)
----------------------------------------------------------------------
Traceback (most recent call last):
File "main.py", line 23, in test_string_startswith
self.assertTrue('tutorialspoint'.startswith('putor'))
AssertionError: False is not true
----------------------------------------------------------------------
Ran 4 tests in 0.000s
FAILED (failures=1)
Humanize Package
The Humanize Package in Python is a library which is specifically
designed to convert numerical values, dates, times and file sizes into
formats that are more easily understood by humans.
1. This package is essential for creating user-friendly interfaces
and readable reports where data interpretation needs to be
quick and intuitive.
2. The primary goal of the Humanize Package is to bridge the
gap between raw data and human understanding.
Number Utilities
The Humanize package in Python provides several utilities that
enhance the readability and comprehension of numerical data. These
utilities convert numbers into formats that are more natural and
understandable for humans.
Integer Formatting
The Integer Formatting utility converts large integers into strings with
commas for improved readability. Following is the example of applying
the integer formatting utility −
import humanise
print(humanize.intcomma(123456))
Output
123,456
Ordinal Numbers
The Ordinal numbers convert integers into their ordinal form. For
example 1 will be given as 1st and 2 as 2nd. Below is the example
converting 3 as 3rd −
import humanise
print(humanize.ordinal(3))
Output
3rd
AP Numbers
This converts the integers into their corresponding words. Here is the
example of it −
import humanise
print(humanize.number(9))
Output
nine
Fractional Units
This converts decimal numbers into fractions for more intuitive
representation. Following is the example of it −
import humanise
print(humanize.fractional(0.5))
Output
1/2
Parameter
Below are the parameters of the naturalsize() function of the python
humanise package −
1. value: The file size in bytes.
2. binary: A boolean flag to indicate whether to use binary
units. The default value is False.
3. gnu: A boolean flag to indicate whether to use GNU-style
output and the default value is False.
4. format: A string to specify the output format. The default
value is "%.1f".
Example
Following is the example of using the naturalsize() of humanise
package in python −
import humanise
# Default usage with decimal units
file_size = 123456789
print(f"File size: {humanize.naturalsize(file_size)}")
# Using binary units
print(f"File size (binary): {humanize.naturalsize(file_size,
binary=True)}")
# Using GNU-style prefixes
print(f"File size (GNU): {humanize.naturalsize(file_size, gnu=True)}")
# Custom format
print(f"File size (custom format): {humanize.naturalsize(file_size,
format='%.2f')}")
Natural Time
The Natural Time converts date-time objects into human-readable
relative times such as 2 days ago, 3 hours ago. Following is the
example of natural time −
import humanise
from datetime import datetime, timedelta
past_date = datetime.now() - timedelta(days=2)
print(humanize.naturaltime(past_date))
Output
2 days ago
Natural Date
The Natural Date formats specific dates into a readable format like
"July 11, 2024". Here is the example −
import humanise
from datetime import datetime
some_date = datetime(2022, 7, 8)
print(humanize.natural time(some_date))
Output
Jul 08 2022
Natural Day
The Natural Day provides a human-readable representation of a date
by considering today's date for contextual relevance, for example
"today", "tomorrow", "yesterday" etc. Below is the example of it −
import humanise
from datetime import datetime, timedelta
today = datetime.now()
tomorrow = today + timedelta(days=1)
print(humanize.naturalday(today))
print(humanize.naturalday(tomorrow))
Output
today
tomorrow
Precise Delta
The Precise Delta converts time duration into human-readable strings
by breaking them down into days, hours, minutes and seconds. Here is
the example of it −
import humanise
from datetime import timedelta
duration = timedelta(days=2, hours=3, minutes=30)
print(humanize.precise delta(duration))
Output
2 days, 3 hours and 30 minutes
Duration Utilities
The humanise package in Python also includes the Duration Utilities
for converting duration (time intervals) into human-readable formats.
These utilities help to present duration in a way that is understandable
and meaningful to users. Here's an overview of the duration utilities
provided by humanise package −
Output
Time duration: 3 days from now
Future duration: in 5 hours
Past duration: a day ago
Context Managers
Context managers in Python provide a powerful way to manage
resources efficiently and safely. A context manager in Python is an
object that defines a runtime context for use with the with statement.
It ensures that setup and cleanup operations are performed
automatically.
For instance, when working with file operations, context managers
handle the opening and closing of files, ensuring that resources are
managed correctly.
Example
Here's a simple example demonstrating how a context manager works
with file operations in Python.
with open('example.txt', 'w') as file:
file.write('Hello, Tutorialspoint!')
On executing the above code you will get the following output −
Entering the context
body
Exiting the context
While executing the above code you will get the following output −
Entering the context
body
Exiting the context
An exception occurred
On executing the above code you will get the following output −
Entering the async context class
Inside the async context
Exiting the async context class
Exception occurred
On executing the above code you will get the following output −
Entering the context manager method
Inside the context
Exiting the context manager method
On executing the above code you will get the following output −
Entering the async context
Inside the async context
Exiting the async context
Coroutines
Python Coroutines are a fundamental concept in programming that
extend the capabilities of traditional functions. They are particularly
useful for asynchronous programming and complex data processing
pipelines.
Coroutines are an extension of the concept of functions and
generators. They are designed to perform cooperative multitasking and
manage asynchronous operations.
In traditional functions i.e. subroutines which have a single entry and
exit point whereas coroutines can pause and resume their execution at
various points by making them highly flexible.
Execution of Coroutines
Coroutines are initiated with the __next__() method which starts the
coroutine and advances execution to the first yield statement. The
coroutine then waits for a value to be sent to it. The send() method is
used to send values to the coroutine which can then process these
values and potentially yield results.
Output
Searching prefix: Welcome to
Welcome to Tutorialspoint
Closing a Coroutine
Coroutines can run indefinitely so it's important to close them
properly when they are no longer needed. The close() method
terminates the coroutine and handles cleanup. If we attempt to send
data to a closed coroutine it will raise a StopIteration exception.
Example
Following is the example of closing a coroutine in python −
Open Compiler
def print_name(prefix):
print(f"Searching prefix: {prefix}")
try:
while True:
name = (yield)
if prefix in name:
print(name)
except GeneratorExit:
print("Closing coroutine!!")
# Instantiate and start the coroutine
corou = print_name("Come")
corou.__next__()
# Send values to the coroutine
corou.send("Come back Thank You")
corou.send("Thank you")
# Close the coroutine
corou.close()
Output
Searching prefix: Come
Come back Thank You
Closing coroutine!!
Example
Below is the example which shows chaining coroutines for pipelines −
Open Compiler
def producer(sentence, next_coroutine):
'''
Splits the input sentence into tokens and sends them to the next
coroutine.
'''
tokens = sentence.split(" ")
for token in tokens:
next_coroutine.send(token)
next_coroutine.close()
def pattern_filter(pattern="ing", next_coroutine=None):
'''
Filters tokens based on the specified pattern and sends matching
tokens to the next coroutine.
'''
print(f"Searching for {pattern}")
try:
while True:
token = (yield)
if pattern in token:
next_coroutine.send(token)
except GeneratorExit:
print("Done with filtering!!")
next_coroutine.close()
def print_token():
'''
Receives tokens and prints them.
'''
print("I'm the sink, I'll print tokens")
try:
while True:
token = (yield)
print(token)
except GeneratorExit:
print("Done with printing!")
# Setting up the pipeline
pt = print_token()
pt.__next__()
pf = pattern_filter(next_coroutine=pt)
pf.__next__()
sentence = "Tutorialspoint is welcoming you to learn and succeed in
Career!!!"
producer(sentence, pf)
Output
I'm the sink, I'll print tokens
Searching for ing
welcoming
Done with filtering!!
Done with printing!
Descriptors
Python Descriptors
Python Descriptors are a way to customise the access, assignment
and deletion of object attributes. They provide a powerful mechanism
for managing the behaviour of attributes by defining methods that get,
set and delete their values. Descriptors are often used to implement
properties, methods and attribute validation.
A descriptor is any object that implements at least one of the
methods such as __get__, __set__ and __delete__. These methods
control how an attribute's value is accessed and modified.
Descriptor Methods
Python Descriptors involve three main methods namely __get__(),
__set__() and __delete__(). As we already discussed above these
methods control the behaviour of attribute access, assignment and
deletion, respectively.
Syntax
The following is the syntax of Python Descriptor __get__ method −
def __get__(self, instance, owner):
"""
instance: the instance that the attribute is accessed through, or None
when accessed through the owner class.
owner: the owner class where the descriptor is defined.
"""
Parameters
Below are the parameters of this method −
self: The descriptor instance.
instance: The instance of the class where the attribute is
accessed. It is None when the attribute is accessed through
the class rather than an instance.
owner: The class that owns the descriptor.
Example
Following is the basic example of __get__() method in which it returns
the stored value _value when obj.attr is accessed −
Open Compiler
class Descriptor:
def __get__(self, instance, owner):
if instance is None:return self
return instance._value
class MyClass:
attr = Descriptor()
def __init__(self, value):
self._value = value
obj = MyClass(42)
print(obj.attr)
Output
42
Syntax
The following is the syntax of Python Descriptor __set__() method −
def __set__(self, instance, value):
"""
instance: the instance of the class where the attribute is being set.
value: the value to assign to the attribute.
"""
Parameters
Below are the parameters of this method −
self: The descriptor instance.
instance: The instance of the class where the attribute is
being set.
value: The value being assigned to the attribute.
Example
Following is the basic example of __set__() method in which ensures
that the value assigned to attr is an integer −
Open Compiler
class Descriptor:
def __set__(self, instance, value):
if not isinstance(value, int):
raise TypeError("Value must be an integer")
instance._value = value
class MyClass:
attr = Descriptor()
def __init__(self, value):
self.attr = value
obj = MyClass(42)
print(obj.attr)
obj.attr = 100
print(obj.attr)
Output
<__main__.Descriptor object at 0x000001E5423ED3D0>
<__main__.Descriptor object at 0x000001E5423ED3D0>
Syntax
The following is the syntax of Python Descriptor __delete__()
method −
def __delete__(self, instance):
"""
instance: the instance of the class from which the attribute is being
deleted.
"""
Parameters
Below are the parameters of this method −
self: The descriptor instance.
instance: The instance of the class where the attribute is
being deleted.
Example
Following is the basic example of __set__() method in which ensures
that the value assigned to attr is an integer −
Open Compiler
class LoggedDescriptor:
def __init__(self, name):
self.name = name
def __get__(self, instance, owner):
return instance.__dict__.get(self.name)
def __set__(self, instance, value):
instance.__dict__[self.name] = value
def __delete__(self, instance):
if self.name in instance.__dict__:
print(f"Deleting {self.name} from {instance}")
del instance.__dict__[self.name]
else:
raise AttributeError(f"{self.name} not found")
class Person:
name = LoggedDescriptor("name")
age = LoggedDescriptor("age")
def __init__(self, name, age):
self.name = name
self.age = age
# Example usage
p = Person("Tutorialspoint", 30)
print(p.name)
print(p.age)
del p.name
print(p.name)
del p.age
print(p.age)
Output
Tutorialspoint
30
Deleting name from <__main__.Person object at
0x0000021A1A67E2D0>
None
Deleting age from <__main__.Person object at 0x0000021A1A67E2D0>
None
Let's see about the two types of python descriptors in detail for our
better understanding.
1. Data Descriptors
Data descriptors are a type of descriptor in Python that define both
__get__()and __set__() methods. These descriptors have precedence
over instance attributes which means that the descriptor’s
__get__()and __set__() methods are always called, even if an instance
attribute with the same name exists.
Example
Below is the example of a data descriptor that ensures an attribute is
always an integer and logs access and modification operations −
Open Compiler
class Integer:
def __get__(self, instance, owner):
print("Getting value")
return instance._value
def __set__(self, instance, value):
print("Setting value")
if not isinstance(value, int):
raise TypeError("Value must be an integer")
instance._value = value
def __delete__(self, instance):
print("Deleting value")
del instance._value
class MyClass:
attr = Integer()
# Usage
obj = MyClass()
obj.attr = 42
print(obj.attr)
obj.attr = 100
print(obj.attr)
del obj.attr
Output
Setting value
Getting value
42
Setting value
Getting value
100
Deleting value
2. Non-data Descriptors
Non-data descriptors are a type of descriptor in Python that define
only the __get__() method. Unlike data descriptors, non-data
descriptors can be overridden by instance attributes. This means that if
an instance attribute with the same name exists then it will take
precedence over the non-data descriptor.
Example
Following is an example of a non-data descriptor that provides a default
value if the attribute is not set on the instance −
Open Compiler
class Default:
def __init__(self, default):
self.default = default
def __get__(self, instance, owner):
return getattr(instance, '_value', self.default)
class MyClass:
attr = Default("default_value")
# Usage
obj = MyClass()
print(obj.attr)
obj._value = "Tutorialspoint"
print(obj.attr)
Output
default_value
Tutorialspoint
Data Descriptors Vs. Non-data Descriptors
Understanding the differences between Data Descriptors and Non-
data Descriptors of python Descriptors is crucial for leveraging their
capabilities effectively.
1. Unreleased References
When objects are no longer needed but still referenced somewhere in
the code then they are not deallocated which leads to memory leaks.
Here is the example of it −
def create_list():
my_list = [1] * (10**6)
return my_list
my_list = create_list()
# If my_list is not cleared or reassigned, it continues to consume
memory.
print(my_list)
Output
[1, 1, 1, 1,
............
............
1, 1, 1, 1]
2. Circular References
Circular references in Python can lead to memory leaks if not managed
properly but Python's cyclic garbage collector can handle many cases
automatically.
For understanding how to detect and break circular references we can
use the tools such as the gc and weakref modules. These tools are
crucial for efficient memory management in complex Python
applications. Following is the example of circular references −
class Node:
def __init__(self, value):
self.value = value
self.next = None
a = Node(1)
b = Node(2)
a.next = b
b.next = a
# 'a' and 'b' reference each other, creating a circular reference.
3. Global Variables
Variables declared at the global scope persist for the lifetime of the
program which potentially causes memory leaks if not managed
properly. Below is the example of it −
large_data = [1] * (10**6)
def process_data():
global large_data
# Use large_data
pass
# large_data remains in memory as long as the program runs.
4. Long-Lived Objects
Objects that persist for the lifetime of the application can cause
memory issues if they accumulate over time. Here is the example −
cache = {}
def cache_data(key, value):
cache[key] = value
# Cached data remains in memory until explicitly cleared.
Output
Unreachable objects: 51
Number of tracked objects: 6117
2. Using "tracemalloc"
The tracemalloc module is used to trace memory allocations in
Python. It is helpful for tracking memory usage and identifying where
memory is being allocated. Following is the example of diagnosing the
memory leaks using the tracemalloc module −
import tracemalloc
# Start tracing memory allocations
tracemalloc.start()
# our code here
a = 10
b = 20
c = a+b
# Take a snapshot of current memory usage
snapshot = tracemalloc.take_snapshot()
# Display the top 10 memory-consuming lines
top_stats = snapshot.statistics('lineno')
for stat in top_stats[:10]:
print(stat)
Output
C:\Users\Niharikaa\Desktop\sample.py:7: size=400 B, count=1,
average=400 B
3. Using "memory_profiler"
The memory_profiler is a module for monitoring memory usage of a
Python program. It provides a decorator to profile functions and a
command-line tool for line-by-line memory usage analysis. In the below
example we are diagnosing the memory leaks using the
memory_profiler module −
from memory_profiler import profile
@profile
def my_function():
# our code here
a = 10
b = 20
c = a+b
if __name__ == "__main__":
my_function()
Output
Line # Mem usage Increment Occurrences Line
===========================================
===========================
3 49.1 MiB 49.1 MiB 1 @profile
4 def my_function():
5 # Your code here
6 49.1 MiB 0.0 MiB 1 a = 10
7 49.1 MiB 0.0 MiB 1 b = 20
8 49.1 MiB 0.0 MiB 1 c = a+b
Creating Tuples
Tuples are created using parentheses '()' and elements separated by
commas ','. Even tuples with a single element require a trailing comma
to distinguish them from grouped expressions.
Following is the example of creating a tuple by assigning parentheses
'()' to a variable −
Open Compiler
empty_tuple = ()
single_element_tuple = (5,) # Note the comma after the single
element
print("Single element tuple:", single_element_tuple)
multi_element_tuple = (1, 2, 'Tutorialspoint', 3.14)
print("Multi elements tuple:", multi_element_tuple)
nested_tuple = (1, (2, 3), 'Learning')
print("Nested tuple:", nested_tuple)
Strings
Strings in Python are sequences of characters which are used to
represent and manipulate textual data. They are enclosed within either
single quotes ' or double quotes " with the option to use triple quotes"
"" for multi-line strings.
Key characteristics include immutability which means once created
those strings cannot be changed, ordered indexing where characters
are accessed by position and support for various operations such as
concatenation, slicing and iteration.
Strings are fundamental in Python for tasks such as text processing,
input/output operations and data representation in applications offering
a versatile toolset with built-in methods for efficient manipulation and
formatting of textual information.
Creating Strings
Each type of string creation method i.e. ', ", """ has its own use case
depending on whether we need to include quotes within the string,
handle multi-line text or other specific formatting requirements in our
Python code.
Following is the example of creating the string with the help of three
types of quotes ', ", """ −
Open Compiler
# Single line string
single_quoted_string = 'Hello, Welcome to Tutorialspoint'
# Double quoted string
double_quoted_string = "Python Programming"
# Triple quoted string for multi-line strings
multi_line_string = """This is a
multi-line
string"""
print(single_quoted_string)
print(double_quoted_string)
print(multi_line_string)
Frozen Sets
A frozen set in Python is an immutable version of a set. Once created
its elements cannot be changed, added or removed. Frozen sets are
particularly useful in situations where we need a set that remains
constant throughout the execution of a program, especially when we
want to use it as a key in a dictionary or as an element in another set.
Named Tuples
A Named tuple in Python is a lightweight data structure available in the
collections module that behaves the same as a tuple but allows us to
access its elements using named attributes as well as indices.
It combines the advantages of tuples such as immutable, memory-
efficient with the ability to refer to elements by name, enhancing
readability and maintainability of code.
Thank You