Python Handnote 1
Python Handnote 1
Python is a high-level programming language known for its simplicity and readability. This note
covers Python syntax and comments to help you in your studies.
1. Python Syntax
a. Basic Rules
1. Case Sensitivity: Python is case-sensitive, meaning Variable and variable are treated
as different identifiers.
name = "Alice"
Name = "Bob"
print(name) # Outputs: Alice
print(Name) # Outputs: Bob
2. No Semicolons: Statements in Python do not need a semicolon (;). New lines separate
the statements.
print("Hello") # Correct
print("Hello"); # Also works but not recommended
3. Indentation: Python uses indentation to define code blocks (like loops or functions),
instead of curly braces {}.
if True:
print("This is indented") # Indented code block
x = 5 # Integer
y = "Hello" # String
b. Writing Statements
total = 5 + 6 + 7 + \8 + 9
print(total)
Grouping Statements: Use parentheses (), brackets [], or braces {} to write multi-line
statements without a backslash.
print("Hello, World!")
2. Comments in Python
Comments are non-executable lines in a program used to explain code or make notes.
a. Types of Comments
2. Multi-line Comments (Docstrings): Use triple quotes (""" or ''') for multi-line
comments.
"""
This is a multi-line comment.
It can span several lines.
"""
print("Hello, World!")
b. Uses of Comments
def greet(name):
"""
This function greets a person by their name.
"""
print(f"Hello, {name}!")
Good Practices
These notes provide a foundation for understanding Python syntax and comments. Practice
writing Python code and comments to develop fluency!
Variables in Python are used to store data values. A variable acts as a container for information
that can be referenced and manipulated in a program.
1. Dynamic Typing:
o Python variables do not require explicit type declaration.
o The data type is determined based on the assigned value.
x = 10 # Integer
y = 3.14 # Float
z = "Hello" # String
2. Case Sensitivity:
o Variables are case-sensitive.
o For example, age and Age are different variables.
age = 25
Age = 30
print(age) # Outputs: 25
print(Age) # Outputs: 30
name = "Alice"
print(name) # Outputs: Alice
x = 10 # Integer
x = "Text" # Now a String
print(x) # Outputs: Text
_value = 10
name = "John"
2. Cannot Start with a Number:
o Variable names cannot begin with a digit.
user_name = "Alice"
user123 = "Bob"
5. Be Descriptive:
o Use meaningful names for better readability.
score = 95 # Clear
x = 95 # Ambiguous
3. Variable Assignment
1. Single Assignment:
o Assign a single value to a variable.
x = 5
2. Multiple Assignment:
o Assign the same value to multiple variables.
a = b = c = 10
print(a, b, c) # Outputs: 10 10 10
x, y, z = 1, 2, 3
print(x, y, z) # Outputs: 1 2 3
4. Variable Types
Python variables can store values of different data types. Some commonly used types are:
1. Integer:
age = 25
2. Float:
pi = 3.14159
3. String:
name = "Alice"
4. Boolean:
is_active = True
5. List:
numbers = [1, 2, 3, 4, 5]
6. Tuple:
7. Dictionary:
5. Variable Scope
1. Local Scope:
o Variables declared inside a function are local to that function.
def my_function():
x = 10 # Local variable
print(x)
my_function()
# print(x) # Raises NameError, x is not accessible outside the
function
2. Global Scope:
o Variables declared outside functions are global and accessible throughout the
program.
x = 10 # Global variable
def my_function():
print(x)
my_function() # Outputs: 10
6. Constants
In Python, constants are variables whose values should not change. By convention, they are
written in uppercase.
PI = 3.14159
GRAVITY = 9.8
Although Python does not enforce immutability, treating such variables as constants is a good
practice.
These notes provide a comprehensive guide to understanding Python variables. Practice using
variables in different contexts to strengthen your programming skills!
Mutability refers to whether or not an object’s value can be changed after it is created. In
Python, objects are categorized as mutable or immutable.
a.Mutable Objects
Example:
python
Copy code
my_list = [1, 2, 3]
my_list[0] = 10 # Modifies the first element
print(my_list) # Output: [10, 2, 3]
b.Immutable Objects
Example:
python
Copy code
my_string = "Hello"
new_string = my_string + " World" # Creates a new string
print(my_string) # Output: "Hello"
print(new_string) # Output: "Hello World"
Built-in Data Types
In programming, data type is an important concept.
Variables can store data of different types, and different types can do different
things.
Python has the following data types built-in by default, in these categories:
Example
print("Hello")
print('Hello')
Example
print("It's alright")
print("He is called 'Johnny'")
print('He is called "Johnny"')
Example
a = "Hello"
print(a)
Multiline Strings
You can assign a multiline string to a variable by using three quotes:
Example
You can use three double quotes:
Example
a = '''Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.'''
print(a)
Note: in the result, the line breaks are inserted at the same position as in the
code.
However, Python does not have a character data type, a single character is
simply a string with a length of 1.
a = "Hello, World!"
print(a[1])
Example
Loop through the letters in the word "banana":
for x in "banana":
print(x)
String Length
To get the length of a string, use the len() function.
Example
The len() function returns the length of a string:
a = "Hello, World!"
print(len(a))
Check String
To check if a certain phrase or character is present in a string, we can use the
keyword in.
Example
Check if "free" is present in the following text:
txt = "The best things in life are free!"
print("free" in txt)
Use it in an if statement:
Example
Print only if "free" is present:
Check if NOT
To check if a certain phrase or character is NOT present in a string, we can use
the keyword not in.
Example
Check if "expensive" is NOT present in the following text:
Use it in an if statement:
Example
print only if "expensive" is NOT present:
Specify the start index and the end index, separated by a colon, to return a part
of the string.
Example :
b = "Hello, World!"
print(b[2:5])
Example
Get the characters from the start to position 5 (not included):
b = "Hello, World!"
print(b[:5])
By leaving out the end index, the range will go to the end:
Example
Get the characters from position 2, and all the way to the end:
b = "Hello, World!"
print(b[2:])
Negative Indexing
Use negative indexes to start the slice from the end of the string:
Example
Get the characters:
b = "Hello, World!"
print(b[-5:-2])
a.Upper Case
a = "Hello, World!"
print(a.upper())
b.Lower Case
a = "Hello, World!"
print(a.lower())
c.Remove Whitespace
Whitespace is the space before and/or after the actual text, and very often you
want to remove this space.
The strip() method removes any whitespace from the beginning or the end:
d.Replace String
a = "Hello, World!"
print(a.replace("H", "J"))
e.Split String
The split() method returns a list where the text between the specified separator
becomes the list items.
The split() method splits the string into substrings if it finds instances of the
separator:
a = "Hello, World!"
print(a.split(",")) # returns ['Hello', ' World!']
a = "Hello"
b = "World"
c = a + b
print(c)
To add a space between them, add a " ":
a = "Hello"
b = "World"
c = a + " " + b
print(c)
This is the classic method of formatting strings in Python, commonly known as the percent
formatting.
1.1 Syntax
python
CopyEdit
"string with %s" % value
1.2 Examples
python
CopyEdit
name = "Alice"
age = 25
height = 5.6
# Formatting with %
formatted_string = "Name: %s, Age: %d, Height: %.1f" % (name, age, height)
print(formatted_string)
Output:
yaml
CopyEdit
Name: Alice, Age: 25, Height: 5.6
Here, %s is replaced with the string Alice, %d is replaced with the integer 25, and %.1f is used to
format the floating-point number 5.6 with one decimal place.
The str.format() method is more versatile and easier to read than the older % formatting. It
uses curly braces {} as placeholders and allows you to pass values into the string via the
format() method.
python
CopyEdit
"string with {}".format(value)
2.2 Examples
python
CopyEdit
name = "Bob"
age = 30
height = 6.2
# Basic usage
formatted_string = "Name: {}, Age: {}, Height: {}".format(name, age, height)
print(formatted_string)
Output:
yaml
CopyEdit
Name: Bob, Age: 30, Height: 6.2
python
CopyEdit
# Positional
formatted_string = "Name: {}, Age: {}, Height: {}".format(name, age, height)
print(formatted_string)
# Keyword arguments
formatted_string = "Name: {0}, Age: {1}, Height: {2}".format(name, age,
height)
print(formatted_string)
# Using named placeholders
formatted_string = "Name: {name}, Age: {age}, Height:
{height}".format(name="Charlie", age=28, height=5.9)
print(formatted_string)
Output:
yaml
CopyEdit
Name: Bob, Age: 30, Height: 6.2
Name: Bob, Age: 30, Height: 6.2
Name: Charlie, Age: 28, Height: 5.9
F-strings are the most modern and preferred method for string formatting in Python. They
provide a way to embed expressions inside string literals using {} and the f prefix before the
string.
3.1 Syntax
python
CopyEdit
f"string with {expression}"
3.2 Examples
python
CopyEdit
name = "David"
age = 40
height = 5.8
# Using f-strings
formatted_string = f"Name: {name}, Age: {age}, Height: {height}"
print(formatted_string)
Output:
yaml
CopyEdit
Name: David, Age: 40, Height: 5.8
You can also perform operations directly within the curly braces.
python
CopyEdit
x = 5
y = 10
formatted_string = f"The sum of {x} and {y} is {x + y}"
print(formatted_string)
Output:
python
CopyEdit
The sum of 5 and 10 is 15
F-strings also support advanced formatting for numbers, such as controlling the number of
decimal places.
python
CopyEdit
pi = 3.1415926535
formatted_string = f"Pi to 2 decimal places: {pi:.2f}"
print(formatted_string)
Output:
vbnet
CopyEdit
Pi to 2 decimal places: 3.14
:.2f ensures that the number is formatted as a float with 2 decimal places.
Python provides powerful options for controlling the width, alignment, and padding of string
elements in a formatted string.
python
CopyEdit
name = "Alice"
formatted_string = f"{name:10}" # Right-aligned, width of 10
print(f"'{formatted_string}'")
Output:
arduino
CopyEdit
'Alice '
python
CopyEdit
# Left align
formatted_string = f"{name:<10}"
print(f"'{formatted_string}'")
# Center align
formatted_string = f"{name:^10}"
print(f"'{formatted_string}'")
Output:
arduino
CopyEdit
'Alice '
' Alice '
python
CopyEdit
formatted_string = f"{name:.^10}" # Centered, with dot padding
print(f"'{formatted_string}'")
Output:
arduino
CopyEdit
'..Alice...'
python
CopyEdit
large_number = 1000000
formatted_string = f"{large_number:,}"
print(formatted_string)
Output:
CopyEdit
1,000,000
Key Points
Practice Questions:
5.String methods
In Python, string methods are built-in functions associated with string objects that allow you to
perform various operations on strings. These methods help manipulate and analyze strings
efficiently, such as modifying case, finding substrings, splitting strings, or replacing parts of a
string.
str.join()
Joins a list of strings into ",".join(['a', 'b', 'c']) 'a,b,c'
a single string.
Checks if the string
str.startswith() starts with a specified "hello".startswith("he") True
prefix.
str.endswith()
Checks if the string ends "hello".endswith("lo") True
with a specified suffix.
str.isdigit()
Checks if all characters "12345".isdigit() True
are digits.
str.isalpha()
Checks if all characters "hello".isalpha() True
are alphabetic.
str.isalnum()
Checks if all characters "hello123".isalnum() True
are alphanumeric.
Method Description Example Output
str.isspace()
Checks if all characters " ".isspace() True
are whitespace.
Swaps uppercase to
str.swapcase() lowercase and vice "Hello".swapcase() 'hELLO'
versa.
str.zfill(width)
Pads the string with "42".zfill(5) '00042'
zeros on the left.
str.center(width)
Centers the string within "hello".center(10) ' hello '
the specified width.
str.count()
Counts occurrences of a "banana".count("a") 3
substring.
Start with the most frequently used methods, which are helpful in day-to-day coding:
int (Integers)
float
complex
Variables of numeric types are created when you assign a value to them:
Example
x = 1 # int
y = 2.8 # float
z = 1j # complex
To verify the type of any object in Python, use the type() function:
Example
print(type(x))
print(type(y))
print(type(z))
a.Int
Int, or integer, is a whole number, positive or negative, without decimals, of
unlimited length.
Example
Integers:
x = 1
y = 35656222554887711
z = -3255522
print(type(x))
print(type(y))
print(type(z))
b.Float
Float, or "floating point number" is a number, positive or negative, containing
one or more decimals.
Example
Floats:
x = 1.10
y = 1.0
z = -35.59
print(type(x))
print(type(y))
print(type(z))
Float can also be scientific numbers with an "e" to indicate the power of 10.
Example
Floats:
x = 35e3
y = 12E4
z = -87.7e100
print(type(x))
print(type(y))
print(type(z))
c.Complex
Complex numbers are written with a "j" as the imaginary part:
Example
Complex:
x = 3+5j
y = 5j
z = -5j
print(type(x))
print(type(y))
print(type(z))
1.Type Conversion
You can convert from one type to another with the int(), float(),
and complex() methods:
Example
Convert from one type to another:
x = 1 # int
y = 2.8 # float
z = 1j # complex
print(a)
print(b)
print(c)
print(type(a))
print(type(b))
print(type(c))
Note: You cannot convert complex numbers into another number type.
2.Random Number
Python does not have a random() function to make a random number, but Python
has a built-in module called random that can be used to make random numbers:
Example
Import the random module, and display a random number between 1 and 9:
import random
print(random.randrange(1, 10))
In our Random Module Reference you will learn more about the Random
module.
Booleans represent one of two values: True or False.
You can evaluate any expression in Python, and get one of two
answers, True or False.
When you compare two values, the expression is evaluated and Python returns
the Boolean answer:
Example
print(10 > 9) #output: True
print(10 == 9) #output: False
print(10 < 9) #Output: False
Example
Print a message based on whether the condition is True or False:
a = 200
b = 33
if b > a:
print("b is greater than a")
else:
print("b is not greater than a")
#Output: b is not greater than a
Example
Evaluate two variables:
x = "Hello"
y = 15
Any list, tuple, set, and dictionary are True, except empty ones.
Example
The following will return True:
bool("abc")
bool(123)
bool(["apple", "cherry", "banana"])
Some Values are False
In fact, there are not many values that evaluate to False, except empty values,
such as (), [], {}, "", the number 0, and the value None. And of course the
value False evaluates to False.
Example
The following will return False:
bool(False)
bool(None)
bool(0)
bool("")
bool(())
bool([])
bool({})
One more value, or object in this case, evaluates to False, and that is if you
have an object that is made from a class with a __len__ function that
returns 0 or False:
Example
class myclass():
def __len__(self):
return 0
myobj = myclass()
print(bool(myobj))
Example
Print the answer of a function:
def myFunction() :
return True
print(myFunction())
Example
Print "YES!" if the function returns True, otherwise print "NO!":
def myFunction() :
return True
if myFunction():
print("YES!")
else:
print("NO!")
#output:Yes!
Note: Python also has many built-in functions that return a boolean value, like
the isinstance() function, which can be used to determine if an object is of a
certain data type:
Example
Check if an object is an integer or not:
x = 200
print(isinstance(x, int))
Lists are used to store multiple items in a single variable.
Lists are one of 4 built-in data types in Python used to store collections of data,
the other 3 are Tuple, Set, and Dictionary, all with different qualities and usage.
Example
Create a List:
List Items
List items are ordered, changeable, and allow duplicate values.
List items are indexed, the first item has index [0], the second item has
index [1] etc.
Ordered
When we say that lists are ordered, it means that the items have a defined
order, and that order will not change.
If you add new items to a list, the new items will be placed at the end of the
list.
Note: There are some list methods that will change the order, but in general:
the order of the items will not change.
Mutable
The list is changeable, meaning that we can change, add, and remove items in
a list after it has been created.
Allow Duplicates
Since lists are indexed, lists can have items with the same value:
Example
Lists allow duplicate values:
List Length
To determine how many items a list has, use the len() function:
Example
Print the number of items in the list:
Example
String, int and boolean data types:
list1 = ["apple", "banana", "cherry"]
list2 = [1, 5, 7, 9, 3]
list3 = [True, False, False]
Example
A list with strings, integers and boolean values:
type()
From Python's perspective, lists are defined as objects with the data type 'list':
<class 'list'>
Example
What is the data type of a list?
Example
Using the list() constructor to make a List:
*Set items are unchangeable, but you can remove and/or add items whenever
you like.
**As of Python version 3.7, dictionaries are ordered. In Python 3.6 and earlier,
dictionaries are unordered.
1.Access Items
List items are indexed and you can access them by referring to the index
number:
Example
Print the second item of the list:
Negative Indexing
Negative indexing means start from the end
-1 refers to the last item, -2 refers to the second last item etc.
Example
Print the last item of the list:
Range of Indexes
You can specify a range of indexes by specifying where to start and where to
end the range.
When specifying a range, the return value will be a new list with the specified
items.
Example
Return the third, fourth, and fifth item:
thislist =
["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
print(thislist[2:5])
#output: ['cherry', 'orange', 'kiwi']
Note: The search will start at index 2 (included) and end at index 5 (not
included).
Example
This example returns the items from the beginning to, but NOT including,
"kiwi":
thislist =
["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
print(thislist[:4])
#output: ['apple', 'banana', 'cherry', 'orange']
By leaving out the end value, the range will go on to the end of the list:
Example
This example returns the items from "cherry" to the end:
thislist =
["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
print(thislist[2:])
#output: ['cherry', 'orange', 'kiwi', 'melon', 'mango']
Example
This example returns the items from "orange" (-4) to, but NOT including
"mango" (-1):
thislist =
["apple", "banana", "cherry", "orange", "kiwi", "melon", "mango"]
print(thislist[-4:-1])
#output: ['orange', 'kiwi', 'melon']
Check if Item Exists
To determine if a specified item is present in a list use the in keyword:
Example
Check if "apple" is present in the list:
Example
Change the second item:
Example
Change the values "banana" and "cherry" with the values "blackcurrant" and
"watermelon":
thislist = ["apple", "banana", "cherry", "orange", "kiwi", "mango"]
thislist[1:3] = ["blackcurrant", "watermelon"]
print(thislist)
#output: ['apple', 'blackcurrant', 'watermelon', 'orange', 'kiwi',
'mango']
If you insert more items than you replace, the new items will be inserted where
you specified, and the remaining items will move accordingly:
Example
Change the second value by replacing it with two new values:
Note: The length of the list will change when the number of items inserted does
not match the number of items replaced.
If you insert less items than you replace, the new items will be inserted where
you specified, and the remaining items will move accordingly:
Example
Change the second and third value by replacing it with one value:
Insert Items
To insert a new list item, without replacing any of the existing values, we can
use the insert() method.
Example
Insert "watermelon" as the third item:
Append Items
To add an item to the end of the list, use the append() method:
Insert Items
To insert a list item at a specified index, use the insert() method.
Example
Insert an item as the second position:
Extend List
To append elements from another list to the current list, use
the extend() method.
Example
Add the elements of tropical to thislist:
Example
Add elements of a tuple to a list:
Syntax:
list.remove(element)
Example:
Syntax:
list.pop([index])
Example:
Syntax:
del list[index]
Example:
# Delete a slice
fruits = ["apple", "banana", "cherry", "date"]
del fruits[1:3]
print(fruits) # Output: ["apple", "date"]
Syntax:
list.clear()
Example:
Example:
Comparison of Methods
Key Points
1. Use remove() if you know the value to delete but not its index.
2. Use pop() or del to remove by index.
3. Use clear() to empty the entire list.
4. Use list comprehension for advanced filtering needs.
The for loop is the most commonly used method to iterate over each item in a list.
Syntax:
Example:
Output:
apple
banana
cherry
2. Using for Loop with range()
You can loop through the list using its index by combining the for loop with the range()
function.
Syntax:
for i in range(len(list)):
# Code to execute using list[i]
Example:
Output:
apple
banana
cherry
A while loop can also be used to iterate through a list by maintaining an index variable.
Syntax:
index = 0
while index < len(list):
# Code to execute using list[index]
index += 1
Example:
Output:
apple
banana
cherry
4. Using List Comprehension
List comprehension is a concise way to loop through a list and perform operations on its
elements.
Syntax:
Example:
Output:
5. Using enumerate()
The enumerate() function allows you to loop through a list and access both the index and the
value of each item.
Syntax:
Example:
Output:
Key Points
1. Creating a List
2. Filtering a List
3. Applying a Transformation
List comprehension is more concise and readable compared to traditional loops. Here is an
example of both approaches:
Using a Loop:
squares = []
for x in range(1, 6):
squares.append(x**2)
print(squares) # Output: [1, 4, 9, 16, 25]
Key Points
Would you like examples of more advanced list comprehension techniques or exercises?
6.Sorting Lists in Python
Sorting lists in Python is an essential operation for organizing data. Python provides multiple
ways to sort lists, both in ascending and descending order, and even with custom sorting criteria.
The sort() method sorts the list in place, modifying the original list.
By default, it sorts in ascending order.
Syntax:
list.sort(key=None, reverse=False)
Example:
Ascending Order:
numbers = [5, 2, 9, 1, 5]
numbers.sort()
print(numbers) # Output: [1, 2, 5, 5, 9]
Descending Order:
numbers = [5, 2, 9, 1, 5]
numbers.sort(reverse=True)
print(numbers) # Output: [9, 5, 5, 2, 1]
The sorted() function returns a new sorted list, leaving the original list unchanged.
By default, it sorts in ascending order.
Syntax:
Example:
Ascending Order:
numbers = [5, 2, 9, 1, 5]
sorted_numbers = sorted(numbers)
print(sorted_numbers) # Output: [1, 2, 5, 5, 9]
print(numbers) # Output: [5, 2, 9, 1, 5]
Descending Order:
numbers = [5, 2, 9, 1, 5]
sorted_numbers = sorted(numbers, reverse=True)
print(sorted_numbers) # Output: [9, 5, 5, 2, 1]
You can sort lists containing complex data types like tuples or dictionaries by specifying a
custom key.
Key Points
7.Copy a List
You cannot copy a list simply by typing list2 = list1, because: list2 will only be
a reference to list1, and changes made in list1 will automatically also be made
in list2.
Example
Make a copy of a list with the list() method:
Example
Make a copy of a list with the : operator:
Another way to join two lists is by appending all the items from list2 into list1,
one by one:
Example
Append list2 into list1:
for x in list2:
list1.append(x)
print(list1)
Or you can use the extend() method, where the purpose is to add elements from
one list to another list:
Example
Use the extend() method to add list2 at the end of list1:
list1.extend(list2)
print(list1)
1. append()
Syntax:
list.append(element)
Example:
2. extend()
Syntax:
list.extend(iterable)
Example:
3. insert()
Syntax:
list.insert(index, element)
Example:
4. remove()
Syntax:
list.remove(element)
Example:
5. pop()
Removes and returns the element at a specified index. If no index is provided, removes the last
element.
Syntax:
list.pop([index])
Example:
6. clear()
Syntax:
list.clear()
Example:
7. index()
Syntax:
Example:
8. count()
Syntax:
list.count(element)
Example:
fruits = ["apple", "banana", "apple"]
count = fruits.count("apple")
print(count) # Output: 2
9. sort()
Sorts the list in ascending order by default. Use reverse=True for descending order.
Syntax:
list.sort(key=None, reverse=False)
Example:
numbers = [3, 1, 4, 1, 5]
numbers.sort()
print(numbers) # Output: [1, 1, 3, 4, 5]
10. reverse()
Syntax:
list.reverse()
Example:
11. copy()
Syntax:
list.copy()
Example:
Key Points
Allows
Data type Type Ordered Mutable
Duplicates
List Yes Yes Yes
Tuple Yes No Yes
Set No No No
Dictionary Yes Yes No
Tuple is a collection which is ordered and unchangeable. Allows duplicate
members.
Tuple is one of 4 built-in data types in Python used to store collections of data,
the other 3 are List, Set, and Dictionary, all with different qualities and usage.
Tuple Items
Tuple items are ordered, unchangeable, and allow duplicate values.
Tuple items are indexed, the first item has index [0], the second item has
index [1] etc.
Ordered
When we say that tuples are ordered, it means that the items have a defined
order, and that order will not change.
Unchangeable
Tuples are unchangeable, meaning that we cannot change, add or remove items
after the tuple has been created.
Allow Duplicates
Since tuples are indexed, they can have items with the same value:
Example
Tuples allow duplicate values:
Tuple Length
To determine how many items a tuple has, use the len() function:
Example
Print the number of items in the tuple:
Example
One item tuple, remember the comma:
thistuple = ("apple",)
print(type(thistuple))
#NOT a tuple
thistuple = ("apple")
print(type(thistuple))
Example
String, int and boolean data types:
Example
A tuple with strings, integers and boolean values:
<class 'tuple'>
Example
What is the data type of a tuple?
Example
Using the tuple() method to make a tuple:
**As of Python version 3.7, dictionaries are ordered. In Python 3.6 and earlier,
dictionaries are unordered.
Example
Print the second item in the tuple:
Negative Indexing
Negative indexing means start from the end.
-1 refers to the last item, -2 refers to the second last item etc.
Example
Print the last item of the tuple:
Range of Indexes
You can specify a range of indexes by specifying where to start and where to
end the range.
When specifying a range, the return value will be a new tuple with the specified
items.
Example
Return the third, fourth, and fifth item:
thistuple =
("apple", "banana", "cherry", "orange", "kiwi", "melon", "mango")
print(thistuple[2:5])
Note: The search will start at index 2 (included) and end at index 5 (not
included).
By leaving out the start value, the range will start at the first item:
Example
This example returns the items from the beginning to, but NOT included, "kiwi":
thistuple =
("apple", "banana", "cherry", "orange", "kiwi", "melon", "mango")
print(thistuple[:4])
By leaving out the end value, the range will go on to the end of the tuple:
Example
This example returns the items from "cherry" and to the end:
thistuple =
("apple", "banana", "cherry", "orange", "kiwi", "melon", "mango")
print(thistuple[2:])
Example
This example returns the items from index -4 (included) to index -1 (excluded)
thistuple =
("apple", "banana", "cherry", "orange", "kiwi", "melon", "mango")
print(thistuple[-4:-1])
Example
Check if "apple" is present in the tuple:
2.Update Tuples
Tuples are unchangeable, meaning that you cannot change, add, or remove
items once the tuple is created.
But there are some workarounds.
But there is a workaround. You can convert the tuple into a list, change the list,
and convert the list back into a tuple.
Example:
Convert the tuple into a list to be able to change it:
print(x)
3.Add Items
Since tuples are immutable, they do not have a built-in append() method, but
there are other ways to add items to a tuple.
1. Convert into a list: Just like the workaround for changing a tuple, you can
convert it into a list, add your item(s), and convert it back into a tuple.
Example
Convert the tuple into a list, add "orange", and convert it back into a tuple:
Example
Create a new tuple with the value "orange", and add that tuple:
print(thistuple)
Note: When creating a tuple with only one item, remember to include a comma
after the item, otherwise it will not be identified as a tuple.
4.Remove Items
Note: You cannot remove items in a tuple.
Tuples are unchangeable, so you cannot remove items from it, but you can
use the same workaround as we used for changing and adding tuple items:
Example
Convert the tuple into a list, remove "apple", and convert it back into a tuple:
Example
The del keyword can delete the tuple completely:
5.Unpacking a Tuple
When we create a tuple, we normally assign values to it. This is called "packing"
a tuple:
Example:
Packing a tuple:
But, in Python, we are also allowed to extract the values back into variables.
This is called "unpacking":
Example
Unpacking a tuple:
print(green)
print(yellow)
print(red)
Note: The number of variables must match the number of values in the tuple, if
not, you must use an asterisk to collect the remaining values as a list.
Using Asterisk(*)
If the number of variables is less than the number of values, you can add
an * to the variable name and the values will be assigned to the variable as a
list:
Example
Assign the rest of the values as a list called "red":
print(green)
print(yellow)
print(red)
If the asterisk is added to another variable name than the last, Python will
assign values to the variable until the number of values left matches the
number of variables left.
Example
Add a list of values the "tropic" variable:
print(green)
print(tropic)
print(red)
Example:
Iterate through the items and print the values:
Learn more about for loops in our Python For Loops Chapter.
Loop Through the Index Numbers
You can also loop through the tuple items by referring to their index number.
Example
Print all items by referring to their index number:
Use the len() function to determine the length of the tuple, then start at 0 and
loop your way through the tuple items by referring to their indexes.
Example:
Print all items, using a while loop to go through all the index numbers:
8.Multiply Tuples
If you want to multiply the content of a tuple a given number of times, you can
use the * operator:
Example
Multiply the fruits tuple by 2:
print(mytuple)
1. count()
tuple.count(value)
Example:
2. index()
Returns the index of the first occurrence of a specified value. Raises a ValueError if the value is
not found.
Syntax:
tuple.index(value)
Example:
Note:
Since tuples are immutable, methods like append(), remove(), or pop() are not available for
tuples.
Tuples are often used for storing fixed collections of data where immutability is required.
Sets are used to store multiple items in a single variable.
Set is one of 4 built-in data types in Python used to store collections of data,
the other 3 are List, Tuple, and Dictionary, all with different qualities and usage.
* Note: Set items are unchangeable, but you can remove items and add new
items.
Example:
Create a Set:
Note: Sets are unordered, so you cannot be sure in which order the items will
appear.
a.Unordered
Unordered means that the items in a set do not have a defined order.
Set items can appear in a different order every time you use them, and cannot
be referred to by index or key.
b.Unchangeable/Immutable
Set items are unchangeable, meaning that we cannot change the items after
the set has been created.
Once a set is created, you cannot change its items, but you can remove items
and add new items.
Example
Duplicate values will be ignored:
print(thisset)
Note: The values True and 1 are considered the same value in sets, and are
treated as duplicates:
Example
True and 1 is considered the same value:
print(thisset)
Note: The values False and 0 are considered the same value in sets, and are
treated as duplicates:
Example
thisset = {"apple", "banana", "cherry", False, True, 0}
print(thisset)
4.Unindexed:
Set items cannot be accessed using indices.
Example
Get the number of items in a set:
print(len(thisset))
Example
String, int and boolean data types:
Example
A set with strings, integers and boolean values:
<class 'set'>
Example
What is the data type of a set?
Example
Using the set() constructor to make a set:
1.Access Items
You cannot access items in a set by referring to an index or a key.
But you can loop through the set items using a for loop, or ask if a specified
value is present in a set, by using the in keyword.
Example
Loop through the set, and print the values:
for x in thisset:
print(x)
Example
Check if "banana" is present in the set:
print("banana" in thisset)
Example
Check if "banana" is NOT present in the set:
2.Add Items
Once a set is created, you cannot change its items, but you can add new items.
thisset.add("orange")
print(thisset)
Add Sets
To add items from another set into the current set, use the update() method.
Example
Add elements from tropical into thisset:
thisset.update(tropical)
print(thisset)
Example
Add elements of a list to at set:
thisset.update(mylist)
print(thisset)
3.Remove Item
To remove an item in a set, use the remove(), or the discard() method.
Example
Remove "banana" by using the remove() method:
thisset = {"apple", "banana", "cherry"}
thisset.remove("banana")
print(thisset)
Note: If the item to remove does not exist, remove() will raise an error.
Example
Remove "banana" by using the discard() method:
thisset.discard("banana")
print(thisset)
Note: If the item to remove does not exist, discard() will NOT raise an error.
You can also use the pop() method to remove an item, but this method will
remove a random item, so you cannot be sure what item that gets removed.
Example
Remove a random item by using the pop() method:
x = thisset.pop()
print(x)
print(thisset)
Note: Sets are unordered, so when using the pop() method, you do not know
which item that gets removed.
The clear() method empties the set:
thisset.clear()
print(thisset)
Example
The del keyword will delete the set completely:
del thisset
print(thisset)
4.Loop Items
You can loop through the set items by using a for loop:
Example
Loop through the set, and print the values:
for x in thisset:
print(x)
5.Join Sets
There are several ways to join two or more sets in Python.
The union() and update() methods joins all items from both sets.
a.Union
The union() method returns a new set with all items from both sets.
Example:
Join set1 and set2 into a new set:
You can use the | operator instead of the union() method, and you will get the
same result.
Example
Use | to join two sets:
When using a method, just add more sets in the parentheses, separated by
commas:
Example
Join multiple sets with the union() method:
When using the | operator, separate the sets with more | operators:
Example
Use | to join two sets:
Example
Join a set with a tuple:
x = {"a", "b", "c"}
y = (1, 2, 3)
z = x.union(y)
print(z)
#output: {'b', 1, 2, 3, 'c', 'a'}
Note: The | operator only allows you to join sets with sets, and not with other
data types like you can with the union() method.
d.Update
The update() method inserts all items from one set into another.
The update() changes the original set, and does not return a new set.
Example
The update() method inserts the items in set2 into set1:
set1.update(set2)
print(set1)
#output: {1, 'c', 2, 3, 'a', 'b'}
Note: Both union() and update() will exclude any duplicate items.
e.Intersection
Keep ONLY the duplicates
The intersection() method will return a new set, that only contains the items
that are present in both sets.
Example
Join set1 and set2, but keep only the duplicates:
set3 = set1.intersection(set2)
print(set3)
#output: {'apple'}
You can use the & operator instead of the intersection() method, and you will
get the same result.
Example
Use & to join two sets:
Note: The & operator only allows you to join sets with sets, and not with other
data types like you can with the intersection() method.
The intersection_update() method will also keep ONLY the duplicates, but it will
change the original set instead of returning a new set.
Example
Keep the items that exist in both set1, and set2:
set1 = {"apple", "banana", "cherry"}
set2 = {"google", "microsoft", "apple"}
set1.intersection_update(set2)
print(set1)
#output: {'apple'}
The values True and 1 are considered the same value. The same goes
for False and 0.
Example
Join sets that contains the values True, False, 1, and 0, and see what is
considered as duplicates:
set3 = set1.intersection(set2)
print(set3)
f.Difference
The difference() method will return a new set that will contain only the items
from the first set that are not present in the other set.
Example
Keep all items from set1 that are not in set2:
set3 = set1.difference(set2)
print(set3)
#output: {'banana', 'cherry'}
You can use the - operator instead of the difference() method, and you will get
the same result.
Example
Use - to join two sets:
Note: The - operator only allows you to join sets with sets, and not with other
data types like you can with the difference() method.
The difference_update() method will also keep the items from the first set that
are not in the other set, but it will change the original set instead of returning a
new set.
Example
Use the difference_update() method to keep the items that are not present in
both sets:
set1.difference_update(set2)
print(set1)
#output: {'banana', 'cherry'}
g.Symmetric Differences
The symmetric_difference() method will keep only the elements that are NOT
present in both sets.
Example
Keep the items that are not present in both sets:
set3 = set1.symmetric_difference(set2)
print(set3)
#output: {'banana', 'cherry', 'google', 'microsoft'}
You can use the ^ operator instead of the symmetric_difference() method, and you
will get the same result.
Example
Use ^ to join two sets:
Note: The ^ operator only allows you to join sets with sets, and not with other
data types like you can with the symmetric_difference() method.
The symmetric_difference_update() method will also keep all but the duplicates, but
it will change the original set instead of returning a new set.
Example
Use the symmetric_difference_update() method to keep the items that are not
present in both sets:
set1.symmetric_difference_update(set2)
print(set1)
#output: {'banana', 'microsoft', 'cherry', 'google'}
1. add()
Adds a single element to the set. If the element already exists, the set remains unchanged.
Syntax:
set.add(element)
Example:
my_set = {1, 2, 3}
my_set.add(4)
print(my_set) # Output: {1, 2, 3, 4}
2. remove()
Removes a specified element from the set. Raises a KeyError if the element is not found.
Syntax:
set.remove(element)
Example:
my_set = {1, 2, 3}
my_set.remove(2)
print(my_set) # Output: {1, 3}
3. discard()
Removes a specified element from the set but does NOT raise an error if the element is not
found.
Syntax:
set.discard(element)
Example:
my_set = {1, 2, 3}
my_set.discard(4) # No error
print(my_set) # Output: {1, 2, 3}
4. clear()
Syntax:
set.clear()
Example:
my_set = {1, 2, 3}
my_set.clear()
print(my_set) # Output: set()
5. union()
Syntax:
Example:
set1 = {1, 2, 3}
set2 = {3, 4, 5}
result = set1.union(set2)
print(result) # Output: {1, 2, 3, 4, 5}
6. intersection()
Returns a set containing only the elements that are common to all sets.
Syntax:
Example:
set1 = {1, 2, 3}
set2 = {2, 3, 4}
result = set1.intersection(set2)
print(result) # Output: {2, 3}
7. difference()
Returns a set containing elements that are in the first set but not in the others.
Syntax:
Example:
set1 = {1, 2, 3}
set2 = {2, 3, 4}
result = set1.difference(set2)
print(result) # Output: {1}
8. symmetric_difference()
Returns a set containing elements that are in either of the sets, but not in both.
Syntax:
set.symmetric_difference(other_set)
Example:
set1 = {1, 2, 3}
set2 = {2, 3, 4}
result = set1.symmetric_difference(set2)
print(result) # Output: {1, 4}
Summary of Methods
Method Description
discard() Removes a specified element (does not raise an error if not found).
difference() Finds elements present in one set but not in the others.
Immutable: Once created, the elements of a frozenset cannot be changed (no add, remove, or
update operations).
Hashable: Can be used as keys in dictionaries or as elements in other sets.
Unordered: Like regular sets, frozensets do not maintain order.
Duplicates not allowed: Duplicate elements are automatically removed.
The frozenset() function is used to create a frozenset. You can pass any iterable (e.g., list,
tuple, set) to the frozenset() constructor.
Syntax:
frozenset(iterable)
Example:
Although frozensets are immutable, they support a few methods for analysis and operations.
These methods do not modify the frozenset but return new sets or values.
Method Description
union() Returns a new set containing all unique elements from both sets.
Method Description
difference() Returns a set containing elements in the frozenset but not in others.
symmetric_difference() Returns a set containing elements in either set but not in both.
isdisjoint() Checks if the frozenset has no common elements with another set.
# Union
print(fs1.union(fs2)) # Output: frozenset({1, 2, 3, 4, 5})
# Intersection
print(fs1.intersection(fs2)) # Output: frozenset({3})
# Difference
print(fs1.difference(fs2)) # Output: frozenset({1, 2})
# Symmetric Difference
print(fs1.symmetric_difference(fs2)) # Output: frozenset({1, 2, 4, 5})
Syntax of range()
range(stop)
range(start, stop)
range(start, stop, step)
Parameter Description
Examples of range()
Operations on range
As of Python version 3.7, dictionaries are ordered. In Python 3.6 and earlier,
dictionaries are unordered.
Dictionaries are written with curly brackets, and have keys and values:
Example
Create and print a dictionary:
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
print(thisdict)
Dictionary Items
Dictionary items are ordered, changeable, and do not allow duplicates.
Dictionary items are presented in key:value pairs, and can be referred to by
using the key name.
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
print(thisdict["brand"]) #output: Ford
Ordered or Unordered?
As of Python version 3.7, dictionaries are ordered. In Python 3.6 and earlier,
dictionaries are unordered.
When we say that dictionaries are ordered, it means that the items have a
defined order, and that order will not change.
Unordered means that the items do not have a defined order, you cannot refer
to an item by using an index.
Changeable
Dictionaries are changeable, meaning that we can change, add or remove items
after the dictionary has been created.
Example
Duplicate values will overwrite existing values:
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964,
"year": 2020
}
print(thisdict)
Dictionary Length
To determine how many items a dictionary has, use the len() function:
Example
Print the number of items in the dictionary:
print(len(thisdict))
Example
String, int, boolean, and list data types:
thisdict = {
"brand": "Ford",
"electric": False,
"year": 1964,
"colors": ["red", "white", "blue"]
}
type()
From Python's perspective, dictionaries are defined as objects with the data
type 'dict':
<class 'dict'>
Example
Print the data type of a dictionary:
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
print(type(thisdict)) #output: <class 'dict'>
Example
Using the dict() method to make a dictionary:
1.Accessing Items
A dictionary in Python is a collection of key-value pairs. Accessing items in a dictionary can be
done using the key associated with a value. Python provides several ways to retrieve items from
a dictionary.
To access a specific value in a dictionary, use the key inside square brackets [].
If the key does not exist, a KeyError is raised.
Example:
data = {"name": "Alice", "age": 25, "city": "New York"}
print(data["name"]) # Output: Alice
print(data["age"]) # Output: 25
Syntax:
dictionary.get(key, default_value)
Example:
data = {"name": "Alice", "age": 25, "city": "New York"}
print(data.get("name")) # Output: Alice
print(data.get("country")) # Output: None
print(data.get("country", "USA")) # Output: USA
Python provides methods to retrieve all keys, all values, or all key-value pairs from a dictionary.
Use the keys() method to get a view object of all keys in the dictionary.
keys = data.keys()
print(keys) # Output: dict_keys(['name', 'age', 'city'])
Use the values() method to get a view object of all values in the dictionary.
values = data.values()
print(values) # Output: dict_values(['Alice', 25, 'New York'])
Use the items() method to get a view object of all key-value pairs as tuples.
items = data.items()
print(items) # Output: dict_items([('name', 'Alice'), ('age', 25), ('city',
'New York')])
Iterating Through a Dictionary
You can loop through a dictionary to access its keys, values, or both.
Example:
data = {"name": "Alice", "age": 25, "city": "New York"}
Example:
Check if "model" is present in the dictionary:
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
if "model" in thisdict:
print("Yes, 'model' is one of the keys in the thisdict dictionary")
#output: Yes, 'model' is one of the keys in the thisdict dictionary
To change the value of a specific key, use square brackets [] and assign a new value.
Example:
data = {"name": "Alice", "age": 25, "city": "New York"}
data["age"] = 30
print(data)
# Output: {'name': 'Alice', 'age': 30, 'city': 'New York'}
To add a new key-value pair, simply assign a value to a new key using square brackets [].
Example:
data = {"name": "Alice", "age": 25}
data["city"] = "New York"
print(data)
# Output: {'name': 'Alice', 'age': 25, 'city': 'New York'}
The update() method is used to update multiple key-value pairs at once. It can also add new
keys if they do not already exist.
Syntax:
dictionary.update(other_dictionary)
Example:
data = {"name": "Alice", "age": 25}
data.update({"age": 30, "city": "New York"})
print(data)
# Output: {'name': 'Alice', 'age': 30, 'city': 'New York'}
Key Points to Remember
1. Use square brackets [] to change the value of an existing key or add a new key-value pair.
2. Use the update() method to update multiple items or add new items efficiently.
3. Ensure the key you want to change or add is properly specified to avoid unintended
modifications.
Would you like to explore more advanced dictionary operations or practice some examples?
To add a new key-value pair, simply assign a value to a new key using square brackets [].
Example:
Syntax:
dictionary.update(other_dictionary)
Example:
Use the pop() method to remove an item by its key and retrieve its value.
Example:
Use the popitem() method to remove the last inserted key-value pair. This method is only
available in Python 3.7 and later.
Example:
Example:
Use the clear() method to remove all items from the dictionary.
Example:
Example:
1. Use square brackets [] to add a single item or the update() method to add multiple items.
2. Use pop(), popitem(), or del to remove specific items.
3. Use clear() to empty a dictionary without deleting it.
4. Deleting the dictionary using del removes it entirely from memory.
python
CopyEdit
thisdict = {'name': 'John', 'age': 30, 'city': 'New York'}
for key in thisdict:
print(key)
Output:
CopyEdit
name
age
city
2. Looping Through Values: You can loop through the values of the dictionary by
accessing the value using the key.
python
CopyEdit
for key in thisdict:
print(thisdict[key])
Alternatively, you can use the values() method to directly get all values.
python
CopyEdit
for value in thisdict.values():
print(value)
Output:
sql
CopyEdit
John
30
New York
3. Looping Through Keys Using keys() Method: The keys() method returns the keys of
the dictionary, and you can loop through them.
python
CopyEdit
for key in thisdict.keys():
print(key)
4. Looping Through Both Keys and Values Using items() Method: The items()
method returns both the keys and the corresponding values. You can unpack them during
the loop.
python
CopyEdit
for key, value in thisdict.items():
print(key, value)
Output:
sql
CopyEdit
name John
age 30
city New York
These are the common ways to loop through a dictionary, providing flexibility depending on
whether you need just the keys, just the values, or both.
5.Copying a Dictionary in Python
1. Using the copy() Method: The copy() method creates a shallow copy of the dictionary.
This means that it creates a new dictionary with the same key-value pairs, but changes
made to the new dictionary won't affect the original one.
python
CopyEdit
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
mydict = thisdict.copy()
print(mydict)
Output:
arduino
CopyEdit
{'brand': 'Ford', 'model': 'Mustang', 'year': 1964}
2. Using the dict() Function: The dict() function is another way to copy a dictionary. It
takes the original dictionary as an argument and creates a new dictionary with the same
contents.
python
CopyEdit
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
mydict = dict(thisdict)
print(mydict)
Output:
arduino
CopyEdit
{'brand': 'Ford', 'model': 'Mustang', 'year': 1964}
Important Note:
Shallow Copy: Both methods create a shallow copy of the dictionary. If the dictionary contains
nested objects (like lists or other dictionaries), changes to those objects will still affect both the
original and copied dictionaries. For a deep copy (which copies nested objects too), you can use
the copy module's deepcopy() method.
6.Nested Dictionaries in Python
A nested dictionary is a dictionary where some of the values are also dictionaries.
You can create a dictionary that contains other dictionaries. For example, creating a family
dictionary with each child as a sub-dictionary:
python
CopyEdit
myfamily = {
"child1": {
"name": "Emil",
"year": 2004
},
"child2": {
"name": "Tobias",
"year": 2007
},
"child3": {
"name": "Linus",
"year": 2011
}
}
You can also create individual dictionaries and then combine them into one dictionary:
python
CopyEdit
child1 = {
"name": "Emil",
"year": 2004
}
child2 = {
"name": "Tobias",
"year": 2007
}
child3 = {
"name": "Linus",
"year": 2011
}
myfamily = {
"child1": child1,
"child2": child2,
"child3": child3
}
python
CopyEdit
print(myfamily["child2"]["name"])
Output:
CopyEdit
Tobias
You can loop through both the outer dictionary and its nested dictionaries using the items()
method.
python
CopyEdit
for key, obj in myfamily.items():
print(key)
for inner_key, inner_value in obj.items():
print(inner_key + ":", inner_value)
Output:
yaml
CopyEdit
child1
name: Emil
year: 2004
child2
name: Tobias
year: 2007
child3
name: Linus
year: 2011
Key Points:
Accessing Values: Use multiple keys to access the nested values (e.g.,
myfamily["child2"]["name"]).
Looping: Use items() to loop through both the outer and inner dictionaries.
Nested Structure: Dictionaries within dictionaries allow for a hierarchical data structure, useful
for representing more complex relationships.
1. clear()
Syntax:
python
CopyEdit
dict.clear()
Example:
python
CopyEdit
thisdict = {"name": "John", "age": 30}
thisdict.clear()
print(thisdict) # Output: {}
2. copy()
Returns a shallow copy of the dictionary. This means it copies the dictionary structure, but if the
dictionary contains nested objects, those objects are still referenced by both dictionaries.
Syntax:
python
CopyEdit
dict.copy()
Example:
python
CopyEdit
thisdict = {"name": "John", "age": 30}
newdict = thisdict.copy()
print(newdict) # Output: {'name': 'John', 'age': 30}
3. fromkeys()
Returns a new dictionary with keys from the provided sequence and values set to a specified
value (default is None).
Syntax:
python
CopyEdit
dict.fromkeys(sequence, value)
Example:
python
CopyEdit
keys = ("a", "b", "c")
newdict = dict.fromkeys(keys, 0)
print(newdict) # Output: {'a': 0, 'b': 0, 'c': 0}
4. get()
Returns the value for the specified key if the key exists in the dictionary. If the key does not
exist, it returns None (or a specified default value if provided).
Syntax:
python
CopyEdit
dict.get(key, default_value)
Example:
python
CopyEdit
thisdict = {"name": "John", "age": 30}
print(thisdict.get("name")) # Output: John
print(thisdict.get("address", "Not Found")) # Output: Not Found
5. items()
Returns a view object that displays a list of a dictionary's key-value tuple pairs.
Syntax:
python
CopyEdit
dict.items()
Example:
python
CopyEdit
thisdict = {"name": "John", "age": 30}
print(thisdict.items()) # Output: dict_items([('name', 'John'), ('age',
30)])
6. keys()
Returns a view object that displays all the keys in the dictionary.
Syntax:
python
CopyEdit
dict.keys()
Example:
python
CopyEdit
thisdict = {"name": "John", "age": 30}
print(thisdict.keys()) # Output: dict_keys(['name', 'age'])
7. pop()
Removes the specified key and returns the corresponding value. If the key does not exist, it raises
a KeyError. Optionally, a default value can be provided to return if the key is not found.
Syntax:
python
CopyEdit
dict.pop(key, default_value)
Example:
python
CopyEdit
thisdict = {"name": "John", "age": 30}
removed_value = thisdict.pop("age")
print(removed_value) # Output: 30
print(thisdict) # Output: {'name': 'John'}
8. popitem()
Removes and returns the last inserted key-value pair as a tuple. This method is useful when
working with the dictionary in a LIFO (Last In, First Out) manner.
Syntax:
python
CopyEdit
dict.popitem()
Example:
python
CopyEdit
thisdict = {"name": "John", "age": 30}
last_item = thisdict.popitem()
print(last_item) # Output: ('age', 30)
print(thisdict) # Output: {'name': 'John'}
9. setdefault()
Returns the value of a key if it exists. If the key does not exist, it inserts the key with a specified
default value and returns that value.
Syntax:
python
CopyEdit
dict.setdefault(key, default_value)
Example:
python
CopyEdit
thisdict = {"name": "John", "age": 30}
print(thisdict.setdefault("address", "Unknown")) # Output: Unknown
print(thisdict) # Output: {'name': 'John', 'age': 30, 'address': 'Unknown'}
10. update()
Updates the dictionary with the specified key-value pairs. If the key exists, it updates the value.
If the key doesn't exist, it adds the key-value pair.
Syntax:
python
CopyEdit
dict.update(iterable)
Example:
python
CopyEdit
thisdict = {"name": "John", "age": 30}
thisdict.update({"age": 35, "city": "New York"})
print(thisdict) # Output: {'name': 'John', 'age': 35, 'city': 'New York'}
11. values()
Returns a view object that displays all the values in the dictionary.
Syntax:
python
CopyEdit
dict.values()
Example:
python
CopyEdit
thisdict = {"name": "John", "age": 30}
print(thisdict.values()) # Output: dict_values(['John', 30])
Summary of Methods:
Iterator in Python:
An iterator in Python is an object that allows you to traverse through all the elements in a
collection (such as a list, tuple, or string) one at a time. It adheres to the iterator protocol, which
consists of two main methods:
1. __iter__(): This method is used to initialize the iterator and return the iterator object itself.
2. __next__(): This method returns the next item in the sequence. If there are no more items
left, it raises a StopIteration exception to signal the end of the iteration.
Creating an Iterator
1. An iterable: This is an object that can return an iterator (e.g., a list, tuple, or string).
2. An iterator: An iterator is an object that implements the __iter__() and __next__()
methods.
python
CopyEdit
class MyIterator:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self # The object itself is the iterator
def __next__(self):
if self.current > self.end:
raise StopIteration # Signals the end of iteration
self.current += 1
return self.current - 1
Output:
CopyEdit
1
2
3
4
5
Lists
Tuples
Strings
Dictionaries (iterate over keys or values)
Sets
These iterables can be converted into iterators by using the iter() function.
If you try to call next() again when there are no more items, it will raise a StopIteration
exception.
The for Loop and Iterators
Python's for loop automatically uses the __iter__() and __next__() methods behind the
scenes to iterate over an iterable object, making it easy to work with iterators.
python
CopyEdit
my_list = [10, 20, 30, 40]
Output:
CopyEdit
10
20
30
40
1. Memory Efficiency: Iterators allow you to iterate over large data sets or streams without
loading everything into memory at once.
2. Lazy Evaluation: Iterators generate values only when needed, which can improve performance
when dealing with large datasets.
3. Custom Behavior: You can create your own iterators to control how elements are accessed,
filtered, or transformed.
Conclusion
An iterator in Python provides a flexible way to access elements of a collection one at a time,
and it is a powerful tool for handling large datasets efficiently. You can either use Python's built-
in iterables or create custom iterators for your own needs.
In Python, binary data refers to data that is represented in binary form (as a sequence of 0s and
1s), which can be used for various purposes such as storing and processing non-text data like
images, files, and other types of data that are not human-readable. Python provides several ways
to work with binary data, such as using built-in types, encoding and decoding methods, and
specialized modules.
1. bytes Type 🧑💻
The bytes type in Python is used to represent immutable binary data (data that cannot be
changed after creation). This type is typically used for working with raw binary data, such as
reading or writing binary files.
Syntax:
python
CopyEdit
b = bytes([65, 66, 67]) # Creates a bytes object from a list of integers
Example:
python
CopyEdit
b = bytes([65, 66, 67])
print(b) # Output: b'ABC'
In this example, 65, 66, and 67 are the ASCII values for the characters A, B, and C. The bytes
object represents this as binary data.
2. bytearray Type 🔄
The bytearray type is similar to bytes, but it is mutable (can be modified). This is useful when
you need to modify binary data during the execution of your program.
Syntax:
python
CopyEdit
b = bytearray([65, 66, 67]) # Creates a bytearray object from a list of
integers
Example:
python
CopyEdit
b = bytearray([65, 66, 67])
print(b) # Output: bytearray(b'ABC')
b[0] = 90 # Change the first byte to 90 (ASCII 'Z')
print(b) # Output: bytearray(b'ZBC')
In this example, bytearray allows us to modify the content after creation, unlike bytes.
Syntax:
python
CopyEdit
bin_value = 0b1101 # Binary literal representing 13
Example:
python
CopyEdit
bin_value = 0b1101
print(bin_value) # Output: 13 (decimal representation)
Convert Integer to Binary: Use the built-in bin() function to convert an integer to a
binary string.
python
CopyEdit
x = 13
binary_str = bin(x) # Output: '0b1101'
Convert Binary String to Integer: You can use int() with base 2 to convert a binary
string back to an integer.
python
CopyEdit
binary_str = '0b1101'
x = int(binary_str, 2) # Output: 13
Convert String to Binary Data: You can convert a string into a binary representation
using the encode() method.
python
CopyEdit
string = "hello"
binary_data = string.encode('utf-8') # Converts string to binary data
using UTF-8 encoding
print(binary_data) # Output: b'hello'
Syntax:
python
CopyEdit
with open('file.bin', 'rb') as f:
binary_data = f.read()
python
CopyEdit
with open('file.bin', 'wb') as f:
f.write(binary_data)
python
CopyEdit
with open('image.jpg', 'rb') as file:
binary_data = file.read()
print(binary_data[:10]) # Output first 10 bytes of the binary file
In this example, we open a file (image.jpg) in binary mode ('rb') and read its contents.
bytes: Immutable binary data type, useful for storing binary data.
bytearray: Mutable binary data type, useful when you need to modify the binary data.
Binary literals (0b): Allows direct representation of binary numbers.
Conversion functions: bin() for converting integers to binary, int() for converting
binary strings to integers, and encode() for converting strings to binary data.
Binary files: Use open() in binary mode ('rb' and 'wb') for reading and writing binary
files.
Python's support for binary data types allows you to efficiently work with non-textual data, such
as images, audio, and video files, and to process raw data in a variety of applications.
In Python, None is a special constant that represents the absence of a value or null value. It is
often used to indicate that a variable has no value, or that a function does not explicitly return a
value.
1. What is None?
None is a singleton object in Python. This means that there is only one instance of None
in a Python program. It is often used as a default value for variables, function parameters,
or return values.
It is of type NoneType, which is a built-in type in Python.
Syntax:
python
CopyEdit
x = None
Example:
python
CopyEdit
x = None
print(x) # Output: None
In this example, x is assigned the value None, meaning it doesn't have any value or data
associated with it.
When a function does not explicitly return a value, it implicitly returns None. This is a way of
indicating that no meaningful value is returned.
python
CopyEdit
def my_function():
print("Hello")
result = my_function()
print(result) # Output: None
In this example, my_function() prints "Hello" but does not return anything, so result is
assigned None.
None is often used as a default value for function parameters to indicate that no argument has
been passed for that parameter. It can then be checked within the function to set a value or
perform an action.
python
CopyEdit
def greet(name=None):
if name is None:
print("Hello, Stranger!")
else:
print(f"Hello, {name}!")
In this example, if no argument is passed to the name parameter, it defaults to None and the
function prints "Hello, Stranger!".
python
CopyEdit
student = {"name": "John", "age": None}
print(student) # Output: {'name': 'John', 'age': None}
Here, None is used to represent the missing value for the student's age.
3. Comparing None 🔎
Noneis a unique value and should be compared using is rather than == for identity
comparison.
Correct Comparison:
python
CopyEdit
x = None
if x is None:
print("x is None") # Output: x is None
python
CopyEdit
x = None
if x == None: # This works but is not the recommended way
print("x is None") # Output: x is None
The is operator checks for identity, meaning that x is None checks if x is the same object as
None, while == checks for equality (although they happen to behave similarly when comparing to
None).
Example:
python
CopyEdit
x = None
if not x:
print("x is None or False") # Output: x is None or False
In this example, since None is falsy, the if condition evaluates to True, and the message is
printed.
python
CopyEdit
x = None
python
CopyEdit
my_dict = {"key1": 10, "key2": None}
Type casting (or type conversion) in Python refers to converting one data type into another. It
allows you to manipulate data in different formats depending on the needs of your program.
Example:
python
CopyEdit
num_int = 5 # Integer
num_float = 2.5 # Float
In this case, Python promotes the integer (int) to a float (float) because the operation involves
both data types.
Function Description
python
CopyEdit
num = 10
print(float(num)) # Output: 10.0
2. Float to Integer:
python
CopyEdit
num = 10.8
print(int(num)) # Output: 10
3. String to Integer:
python
CopyEdit
num_str = "123"
print(int(num_str)) # Output: 123
4. String to Float:
python
CopyEdit
num_str = "123.45"
print(float(num_str)) # Output: 123.45
5. Integer to String:
python
CopyEdit
num = 456
print(str(num)) # Output: "456"
6. List to Set:
python
CopyEdit
my_list = [1, 2, 2, 3]
print(set(my_list)) # Output: {1, 2, 3}
7. Tuple to List:
python
CopyEdit
my_tuple = (1, 2, 3)
print(list(my_tuple)) # Output: [1, 2, 3]
8. Boolean to Integer:
python
CopyEdit
print(int(True)) # Output: 1
print(int(False)) # Output: 0
python
CopyEdit
num_str = "abc"
print(int(num_str)) # Raises ValueError
2. Loss of Data:
o Converting a float to an integer truncates the decimal part:
python
CopyEdit
num = 5.9
print(int(num)) # Output: 5
python
CopyEdit
print(float("123.45")) # Valid
print(int("123a")) # Invalid (raises ValueError)
python
CopyEdit
result = int(5.8) + float(10)
print(result) # Output: 15.0
python
CopyEdit
my_tuple = (1, 2, 3)
my_list = list(my_tuple)
print(my_list) # Output: [1, 2, 3]
python
CopyEdit
print(True + True) # Output: 2
print(False * 10) # Output: 0
Conclusion
Type casting in Python provides flexibility to manipulate data between different types based on
the program's requirements. While implicit type casting simplifies operations by automatically
promoting data types, explicit type casting gives you precise control over how data should be
transformed. Always ensure conversions are valid to avoid runtime errors!
A generator in Python is a special type of iterable that allows you to create an iterator in a more
efficient and concise way. Instead of returning all the values at once (like a list), a generator
produces values on the fly, one at a time, and only when requested.
Generators are defined using a normal function with the yield keyword instead of return.
1. Lazy Evaluation: Generators produce values only when they are requested, making them
memory-efficient.
2. State Retention: Generators remember their state between iterations, so they can resume
execution right after the last yield statement.
3. Iterables: Generators are inherently iterable, meaning you can use them in loops or with
functions like next().
A generator function is a normal Python function but uses the yield keyword instead of return
to produce a series of values.
Example:
python
CopyEdit
def simple_generator():
yield 1
yield 2
yield 3
print(next(gen)) # Output: 1
print(next(gen)) # Output: 2
print(next(gen)) # Output: 3
# print(next(gen)) # Raises StopIteration (end of generator)
Each time yield is encountered, the function pauses and produces the value.
When next() is called again, the function resumes where it left off.
2. Using Generator Expressions
A generator expression is a concise way to create a generator, similar to list comprehensions but
with parentheses instead of square brackets.
Example:
python
CopyEdit
gen_exp = (x ** 2 for x in range(5))
yield return
Produces a value and pauses the function. Exits the function and sends back a value.
Can be called multiple times (resumes execution). Terminates the function completely.
Advantages of Generators
1. Memory Efficiency: Generators do not store all the values in memory; they generate
values on demand. This is especially useful for processing large datasets.
python
CopyEdit
def large_numbers():
for i in range(1_000_000):
yield i
2. Simpler Code: Generators provide a cleaner way to write iterators without manually
implementing __iter__() and __next__() methods.
3. Infinite Sequences: Generators can represent infinite sequences because they generate
values lazily.
python
CopyEdit
def infinite_numbers():
num = 0
while True:
yield num
num += 1
gen = infinite_numbers()
print(next(gen)) # Output: 0
print(next(gen)) # Output: 1
Generator Methods
1. next()
Example:
python
CopyEdit
def generator():
yield "A"
yield "B"
gen = generator()
print(next(gen)) # Output: A
print(next(gen)) # Output: B
2. send()
Used to send a value into the generator and resume its execution.
Example:
python
CopyEdit
def generator_with_send():
value = yield "Start"
yield f"Received: {value}"
gen = generator_with_send()
print(next(gen)) # Output: Start
print(gen.send("Hello")) # Output: Received: Hello
3. close()
Example:
python
CopyEdit
def my_gen():
yield 1
yield 2
gen = my_gen()
print(next(gen)) # Output: 1
gen.close()
# print(next(gen)) # Raises StopIteration
1. Processing Large Files: Instead of loading an entire file into memory, you can process it
line by line with a generator.
python
CopyEdit
def read_large_file(file_path):
with open(file_path) as file:
for line in file:
yield line.strip()
2. Stream Processing: Generators are ideal for handling streaming data, such as reading
data from an API or processing live logs.
3. Pipeline Processing: Generators allow you to chain multiple transformations efficiently.
python
CopyEdit
def generator1():
for i in range(5):
yield i
def generator2(gen):
for value in gen:
yield value ** 2
pipeline = generator2(generator1())
for val in pipeline:
print(val) # Output: 0 1 4 9 16
Conclusion
Generators are a powerful feature in Python that enable lazy evaluation, memory efficiency,
and cleaner code for creating iterators. By using the yield keyword or generator expressions,
you can process large datasets, create infinite sequences, and build efficient data pipelines with
ease.
In Python, keywords are reserved words that have special meaning and purpose within the
language. These words are part of Python's syntax and cannot be used as identifiers (names for
variables, functions, or classes). They are used to define the structure and logic of Python
programs.
Keyword Description
False Boolean value representing falsehood.
True Boolean value representing truth.
None Represents the absence of a value or a null value.
and Logical AND operator.
or Logical OR operator.
not Logical NOT operator.
if Conditional statement.
elif Else-if conditional statement.
else Default block of code if the if condition is false.
while Looping statement (runs as long as a condition is true).
for Looping statement (iterates over sequences).
break Terminates the nearest enclosing loop.
continue Skips the current iteration of the loop and continues to the next.
def Used to define a function.
return Exits a function and optionally returns a value.
Keyword Description
yield Used in generators to return a value and pause execution.
class Defines a class.
pass Placeholder statement that does nothing.
import Imports a module.
from Used with import to import specific parts of a module.
as Used to give an alias to a module or object.
try Defines a block of code to test for exceptions.
except Defines a block of code to handle exceptions.
finally Defines a block of code to execute no matter what.
raise Raises an exception.
assert Debugging tool to test a condition.
del Deletes objects or variables.
with Used to simplify exception handling by wrapping resources.
lambda Defines anonymous functions (lambda expressions).
global Declares a global variable inside a function.
nonlocal Declares a variable as nonlocal in nested functions.
in Membership operator (checks if an element exists in a sequence).
is Identity operator (checks if two objects are the same).
None Represents the absence of a value or null value.
async Declares an asynchronous function or task.
await Used to pause and resume asynchronous functions.
python
CopyEdit
x = 10
if x > 5:
print("x is greater than 5")
elif x == 5:
print("x is equal to 5")
else:
print("x is less than 5")
python
CopyEdit
i = 0
while i < 5:
print(i)
if i == 3:
break # Exit the loop when i equals 3
i += 1
python
CopyEdit
def add_numbers(a, b):
return a + b
result = add_numbers(3, 5)
print(result) # Output: 8
python
CopyEdit
try:
num = int(input("Enter a number: "))
print(10 / num)
except ValueError:
print("Invalid input! Please enter a number.")
except ZeroDivisionError:
print("Division by zero is not allowed.")
finally:
print("Execution complete.")
5. lambda
python
CopyEdit
square = lambda x: x ** 2
print(square(4)) # Output: 16
Example:
python
CopyEdit
import keyword
print(keyword.kwlist) # Prints a list of all Python keywords
Tips for Using Keywords
1. Avoid using keywords as variable names:
python
CopyEdit
def = 10 # This will throw a SyntaxError because `def` is a keyword.
Conclusion
Python keywords are essential for defining the structure, control flow, and logic of a program.
By understanding and effectively using them, you can write efficient, readable, and error-free
code. Always ensure you don’t use these reserved words as identifiers!
Control structures are the building blocks of any programming language, including Python. They
dictate the order in which instructions are executed, allowing for decision-making, repetition,
and more complex program flow. Here are the main types of control structures in Python :
Conditional statements are used to execute a block of code only if a specific condition is true.
They enable decision-making capabilities in a Python program.
1. if Statement
The if statement executes a block of code only if a condition evaluates to True.
Syntax:
python
CopyEdit
if condition:
# Block of code
Example:
python
CopyEdit
age = 18
if age >= 18:
print("You are eligible to vote.")
If the condition (age >= 18) is True, it will execute the code inside the if block.
If the condition is False, it will skip the block.
2. if-else Statement
The if-else statement provides two paths: one for when the condition is True and another for
when it is False.
Syntax:
python
CopyEdit
if condition:
# Block of code if condition is True
else:
# Block of code if condition is False
Example:
python
CopyEdit
marks = 35
if marks >= 40:
print("You passed the exam.")
else:
print("You failed the exam.")
3. if-elif-else Statement
The if-elif-else statement allows you to check multiple conditions. It evaluates each
condition in sequence until one is True. If none are True, the else block executes.
Syntax:
python
CopyEdit
if condition1:
# Block of code if condition1 is True
elif condition2:
# Block of code if condition2 is True
elif condition3:
# Block of code if condition3 is True
else:
# Block of code if none of the conditions are True
Example:
python
CopyEdit
marks = 75
if marks >= 90:
print("Grade: A+")
elif marks >= 80:
print("Grade: A")
elif marks >= 70:
print("Grade: B")
else:
print("Grade: C")
4. Nested if Statements
You can nest if statements to check multiple levels of conditions.
Syntax:
python
CopyEdit
if condition1:
if condition2:
# Block of code if both condition1 and condition2 are True
Example:
python
CopyEdit
age = 25
citizenship = "Indian"
Syntax:
python
CopyEdit
value = "True Condition" if condition else "False Condition"
Example:
python
CopyEdit
marks = 85
result = "Pass" if marks >= 40 else "Fail"
print(result)
Using and
python
CopyEdit
age = 20
if age >= 18 and age <= 30:
print("You are a young adult.")
Using or
python
CopyEdit
day = "Saturday"
if day == "Saturday" or day == "Sunday":
print("It is the weekend.")
Using not
python
CopyEdit
is_raining = False
if not is_raining:
print("You can go outside without an umbrella.")
Using in
python
CopyEdit
fruit = "apple"
if fruit in ["apple", "banana", "cherry"]:
print("The fruit is available.")
Using not in
python
CopyEdit
fruit = "mango"
if fruit not in ["apple", "banana", "cherry"]:
print("The fruit is not available.")
Conclusion
Conditional statements are the backbone of decision-making in Python. They allow you to
control the flow of your program by executing specific blocks of code based on conditions.
Mastering these will enable you to handle diverse logic and build robust programs.
Let me know if you'd like to practice some problems or see examples for a specific use case!
A for loop in Python is used to iterate over a sequence (e.g., a list, tuple, string, dictionary, or
range) and execute a block of code for each element in the sequence. It is one of the most
commonly used looping structures in Python.
variable: This is the iterator that takes the value of each element in the sequence during each
iteration.
sequence: The collection you want to loop over (e.g., list, string, or range).
The loop body contains the statements to execute for each iteration.
Output:
CopyEdit
apple
banana
cherry
python
CopyEdit
for char in "Python":
print(char)
Output:
css
CopyEdit
P
y
t
h
o
n
python
CopyEdit
for i in range(5):
print(i)
Output:
CopyEdit
0
1
2
3
4
python
CopyEdit
for i in range(2, 6):
print(i)
Output:
CopyEdit
2
3
4
5
python
CopyEdit
for i in range(1, 10, 2):
print(i)
Output:
CopyEdit
1
3
5
7
9
python
CopyEdit
mydict = {"name": "Alice", "age": 25, "city": "New York"}
for key in mydict:
print(key)
Output:
CopyEdit
name
age
city
python
CopyEdit
for value in mydict.values():
print(value)
Output:
sql
CopyEdit
Alice
25
New York
python
CopyEdit
for key, value in mydict.items():
print(key, ":", value)
Output:
yaml
CopyEdit
name : Alice
age : 25
city : New York
python
CopyEdit
for i in range(1, 4):
for j in range(1, 3):
print(f"Outer Loop: {i}, Inner Loop: {j}")
Output:
mathematica
CopyEdit
Outer Loop: 1, Inner Loop: 1
Outer Loop: 1, Inner Loop: 2
Outer Loop: 2, Inner Loop: 1
Outer Loop: 2, Inner Loop: 2
Outer Loop: 3, Inner Loop: 1
Outer Loop: 3, Inner Loop: 2
python
CopyEdit
for i in range(5):
print(i)
else:
print("Loop completed.")
Output:
vbnet
CopyEdit
0
1
2
3
4
Loop completed.
Example of break
python
CopyEdit
for i in range(10):
if i == 5:
break
print(i)
Output:
CopyEdit
0
1
2
3
4
Example of continue
python
CopyEdit
for i in range(5):
if i == 2:
continue
print(i)
Output:
CopyEdit
0
1
3
4
8. Using for Loop with Enumerate
The enumerate() function provides both the index and the value during iteration.
python
CopyEdit
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
print(index, fruit)
Output:
CopyEdit
0 apple
1 banana
2 cherry
python
CopyEdit
squares = [x**2 for x in range(5)]
print(squares)
Output:
csharp
CopyEdit
[0, 1, 4, 9, 16]
1. Basic Example
python
CopyEdit
i = 1
while i <= 5:
print(i)
i += 1
Output:
CopyEdit
1
2
3
4
5
In this example:
python
CopyEdit
i = 1
while i <= 3:
print(i)
i += 1
else:
print("Loop completed!")
Output:
vbnet
CopyEdit
1
2
3
Loop completed!
python
CopyEdit
while True:
print("This loop will run forever!")
break # Use break to exit the loop
Output:
arduino
CopyEdit
This loop will run forever!
python
CopyEdit
i = 1
while i <= 5:
if i == 3:
break
print(i)
i += 1
Output:
CopyEdit
1
2
In this example, the loop stops when i equals 3 due to the break statement.
python
CopyEdit
i = 0
while i < 5:
i += 1
if i == 3:
continue
print(i)
Output:
CopyEdit
1
2
4
5
Here, when i equals 3, the continue statement skips the print statement for that iteration.
python
CopyEdit
password = ""
while password != "python123":
password = input("Enter the password: ")
print("Access granted!")
mathematica
CopyEdit
Enter the password: test
Enter the password: python123
Access granted!
python
CopyEdit
i = 1
while i <= 3:
j = 1
while j <= 2:
print(f"Outer loop: {i}, Inner loop: {j}")
j += 1
i += 1
Output:
mathematica
CopyEdit
Outer loop: 1, Inner loop: 1
Outer loop: 1, Inner loop: 2
Outer loop: 2, Inner loop: 1
Outer loop: 2, Inner loop: 2
Outer loop: 3, Inner loop: 1
Outer loop: 3, Inner loop: 2
python
CopyEdit
counter = 0
while counter < 5:
print(f"Counter: {counter}")
counter += 1
Output:
makefile
CopyEdit
Counter: 0
Counter: 1
Counter: 2
Counter: 3
Counter: 4
python
CopyEdit
i = 0
while i in range(5):
print(i)
i += 1
Output:
CopyEdit
0
1
2
3
4
python
CopyEdit
i = 1
while i <= 5:
print(i) # This will cause an infinite loop because i is not
incremented.
To fix this, ensure that the condition changes within the loop.
b. Using the Wrong Condition
python
CopyEdit
i = 1
while i > 0: # This condition will never terminate if i remains positive.
print(i)
i += 1
python
CopyEdit
user_input = ""
while not user_input.isdigit():
user_input = input("Enter a number: ")
print(f"You entered: {user_input}")
python
CopyEdit
import time
countdown = 5
while countdown > 0:
print(f"Time left: {countdown} seconds")
countdown -= 1
time.sleep(1) # Pause for 1 second
print("Time's up!")
Conclusion
The while loop in Python is a versatile construct that allows you to repeat code blocks as long as
a specific condition holds true. It is essential to understand how to manage the condition and use
control statements (break, continue) effectively to avoid infinite loops and achieve desired
functionality.
In Python, you can gather input from the user using the input() function. The input() function
allows you to prompt the user for information, and it returns the data as a string. Here's a detailed
explanation of how to work with user input in Python:
Example:
python
CopyEdit
name = input("Enter your name: ")
print(f"Hello, {name}!")
The program displays the prompt "Enter your name: ", and waits for the user to type
something.
Whatever the user types is returned as a string and stored in the name variable.
The program then prints a greeting using the value entered.
Sample Output:
mathematica
CopyEdit
Enter your name: Alice
Hello, Alice!
python
CopyEdit
age = input("Enter your age: ")
age = int(age) # Convert the input to an integer
print(f"You are {age} years old.")
Here, the input is converted to an integer using the int() function before it's used.
If the user enters a non-numeric value, this will cause an error. You might want to handle that
using exception handling.
Example: Converting to Float
python
CopyEdit
height = input("Enter your height in meters: ")
height = float(height) # Convert the input to a float
print(f"Your height is {height} meters.")
python
CopyEdit
try:
age = input("Enter your age: ")
age = int(age) # Try to convert to integer
print(f"You are {age} years old.")
except ValueError:
print("Please enter a valid number for age.")
In this example, if the user enters something that can't be converted to an integer (e.g., "abc"),
the program catches the ValueError and prints a friendly message instead of crashing.
Example:
python
CopyEdit
data = input("Enter your name, age, and city (separated by spaces): ")
name, age, city = data.split() # Split the input into three parts
print(f"Name: {name}, Age: {age}, City: {city}")
The split() method splits the input string into a list of words based on spaces.
We then unpack the list into the variables name, age, and city.
Sample Output:
yaml
CopyEdit
Enter your name, age, and city (separated by spaces): Alice 25 NewYork
Name: Alice, Age: 25, City: NewYork
5. Getting Input with Default Value
You can provide a default value when the user doesn't enter anything.
Example:
python
CopyEdit
name = input("Enter your name (default: John): ") or "John"
print(f"Hello, {name}!")
If the user presses Enter without typing anything, the default value "John" is used.
Summary:
User input is a powerful way to make your Python programs interactive. Let me know if you'd
like to explore more examples or any specific scenario!
A function is a block of reusable code that performs a specific task. It allows you to group code
into a single entity, which can be executed whenever needed. Functions are useful for organizing
code, making it modular, and avoiding redundancy.
Reusability: You write the function once and reuse it wherever needed in the program, reducing
code repetition.
Modularity: Functions break large tasks into smaller, manageable chunks of code.
Maintainability: Functions make it easier to update and maintain code since changes need to be
made in one place rather than throughout the entire program.
Abstraction: Functions hide complex logic, allowing you to focus on higher-level tasks while
abstracting away the details.
python
CopyEdit
def greet(name):
print(f"Hello, {name}!")
python
CopyEdit
greet("Alice") # Output: Hello, Alice!
Here, the greet function is called with the argument "Alice", which is passed to the name
parameter.
*args is used to pass a variable number of positional arguments to a function. Inside the
function, args will be a tuple containing all the arguments passed.
python
CopyEdit
def add(*args):
return sum(args)
In this example, *args collects all the positional arguments passed to the function and sums
them.
**kwargs allows you to pass a variable number of keyword arguments (key-value pairs) to a
function. Inside the function, kwargs will be a dictionary containing the arguments.
python
CopyEdit
def describe_person(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
Hands-on Practice
1. Create a Simple Function
python
CopyEdit
def multiply(x, y):
return x * y
This function takes two parameters x and y, multiplies them, and returns the result.
You can set default values for function parameters. If the caller doesn’t provide an argument, the
default value is used.
python
CopyEdit
def greet(name="Stranger"):
print(f"Hello, {name}!")
The function greet has a default argument "Stranger". If no name is provided when calling
the function, the default value is used.
python
CopyEdit
def sum_numbers(*args):
return sum(args)
python
CopyEdit
def display_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
display_info(name="Alice", age=30)
# Output:
# name: Alice
# age: 30
In this example, **kwargs allows you to pass any number of key-value pairs, and the function
prints each pair.
In Python, function parameters are the variables that are defined inside the parentheses of a
function definition. When calling a function, you can pass values for these parameters. There are
different types of parameters that you can use to define functions. Here's an explanation of the
different types of function parameters:
1. Positional Arguments
Positional arguments are the most common type of arguments. They are passed to a function
based on their position. The values provided must match the order of parameters in the function
definition.
Example:
python
CopyEdit
def add(a, b):
return a + b
In the function add, the parameter a gets the value 3, and the parameter b gets the value 4.
The function add(3, 4) works because the values are passed in the same order as the
parameters are defined.
2. Default Arguments
Default arguments are parameters that have a default value if no argument is passed during the
function call. You assign a default value to a parameter when defining the function. If the caller
does not provide a value for that parameter, the default value will be used.
Example:
python
CopyEdit
def greet(name="Stranger"):
print(f"Hello, {name}!")
In the function greet, the parameter name has a default value "Stranger".
When calling greet(), no argument is provided, so "Stranger" is used as the default.
When calling greet("Alice"), the function uses "Alice" as the value for name instead of
the default.
Important: Default arguments must be placed after positional arguments in the function
definition. Otherwise, you'll get a syntax error.
python
CopyEdit
# This will raise a SyntaxError
def greet(name="Stranger", age):
print(f"Hello {name}, you are {age} years old.")
python
CopyEdit
def greet(age, name="Stranger"):
print(f"Hello {name}, you are {age} years old.")
3. Keyword Arguments
Keyword arguments are passed to a function by explicitly specifying the parameter name along
with its value. You can pass keyword arguments in any order as long as you specify the
parameter name when calling the function.
Example:
python
CopyEdit
def greet(name, age):
print(f"Hello {name}, you are {age} years old.")
In the function call greet(name="Alice", age=30), the argument name is explicitly passed
with the value "Alice", and age is explicitly passed with 30.
You can change the order of the arguments when using keyword arguments because Python can
match each argument with the corresponding parameter by name.
Positional Arguments: The values are assigned to parameters based on their position.
o Example: greet("Alice", 25) → name="Alice", age=25
Default Arguments: Parameters that have default values if no argument is provided for
them.
o Example: def greet(name="Stranger") → "Stranger" is used if name is not
passed.
Keyword Arguments: Arguments passed by explicitly specifying the parameter name.
o Example: greet(age=25, name="Alice") → The order of arguments can vary.
In this case:
o name is a positional argument.
o age and city are default arguments.
o You can provide values for age and city, or use the default ones.
Let’s break down the concept of returning values from functions in Python:
python
CopyEdit
def add(a, b):
return a + b
result = add(5, 3)
print(result) # Output: 8
The function add takes two parameters a and b, adds them, and returns the result.
The result of the function call add(5, 3) is stored in the variable result, and then printed.
In this case, the function returns a single value (the sum of a and b).
python
CopyEdit
def get_coordinates():
return 10, 20 # Returns a tuple (10, 20)
Returning a List
You can return a list if you need to return multiple items of the same type.
python
CopyEdit
def get_even_numbers(n):
even_numbers = []
for i in range(n):
if i % 2 == 0:
even_numbers.append(i)
return even_numbers
result = get_even_numbers(10)
print(result) # Output: [0, 2, 4, 6, 8]
Returning a Dictionary
If you need to return data in key-value pairs, you can return a dictionary. This is useful when
each value is associated with a unique key.
python
CopyEdit
def get_person_info(name, age, city):
return {"name": name, "age": age, "city": city}
The function get_person_info takes three parameters and returns a dictionary where the
keys are "name", "age", and "city".
The dictionary is returned with the corresponding values.
Returning a Tuple
As mentioned earlier, functions can return tuples. This is useful when you need to return multiple
values of potentially different types, grouped together.
python
CopyEdit
def calculate_area_and_perimeter(length, width):
area = length * width
perimeter = 2 * (length + width)
return area, perimeter # Returns a tuple (area, perimeter)
4. Hands-on Practice:
a. Returning Multiple Values
python
CopyEdit
def get_max_and_min(numbers):
max_value = max(numbers)
min_value = min(numbers)
return max_value, min_value # Returns a tuple (max_value, min_value)
numbers = [3, 1, 4, 1, 5, 9]
maximum, minimum = get_max_and_min(numbers)
print(f"Maximum: {maximum}, Minimum: {minimum}")
# Output: Maximum: 9, Minimum: 1
This function takes a list of numbers and returns the maximum and minimum values as a tuple.
The values are then unpacked into maximum and minimum.
b. Returning a List
python
CopyEdit
def get_prime_numbers(limit):
primes = []
for num in range(2, limit):
is_prime = True
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
is_prime = False
break
if is_prime:
primes.append(num)
return primes
primes_up_to_20 = get_prime_numbers(20)
print(primes_up_to_20)
# Output: [2, 3, 5, 7, 11, 13, 17, 19]
c. Returning a Dictionary
python
CopyEdit
def get_user_info(name, age, city):
return {"Name": name, "Age": age, "City": city}
Summary:
Returning a Single Value: You can return one value from a function using the return keyword.
Returning Multiple Values: Functions can return multiple values by packing them into a tuple.
Returning Other Formats: Functions can return different data structures like lists, dictionaries,
or tuples.
Unpacking Return Values: You can unpack returned values (e.g., a tuple) into separate variables
for ease of use.
In Python, the scope and lifetime of variables are important concepts that determine where a
variable can be accessed from and how long it remains in memory. Let's break these down with
respect to functions.
1. Scope: Where a Variable Can Be Accessed
The scope of a variable refers to the context in which the variable is accessible in the code.
Python has two primary types of scopes:
Local Scope: A variable defined inside a function is in local scope. This means the
variable can only be accessed within that function.
Global Scope: A variable defined outside of all functions is in global scope. This means
the variable is accessible anywhere in the code, including inside functions (with some
rules).
Variables defined inside a function are local variables, meaning they can only be accessed
within that function. Once the function finishes execution, the local variables are destroyed and
are no longer accessible.
Example:
python
CopyEdit
def my_function():
x = 10 # Local variable
print(x)
my_function() # Output: 10
# print(x) # This will cause an error because x is a local variable to
my_function.
x is a local variable inside my_function. It's accessible only within that function.
Trying to access x outside the function would result in a NameError because it is out of scope.
Variables defined outside of functions are global variables and can be accessed from anywhere
in the program, including inside functions.
Example:
python
CopyEdit
x = 20 # Global variable
def my_function():
print(x) # Accessing the global variable
my_function() # Output: 20
The variable x is defined outside the function and is a global variable.
You can access it inside the function my_function().
Local Variables: The lifetime of a local variable begins when the function is called and
ends when the function finishes execution. Once the function completes, the local
variables are discarded and no longer exist.
Global Variables: The lifetime of a global variable lasts as long as the program is
running. It exists for the entire duration of the program, from the point it is defined until
the program terminates.
Example of Lifetime:
python
CopyEdit
def my_function():
a = 10 # Local variable
print(a)
my_function()
# print(a) # This will raise an error because 'a' no longer exists outside
the function.
The variable a is created when my_function() is called and is destroyed when the function
ends.
After the function ends, a no longer exists.
python
CopyEdit
x = 5 # Global variable
def modify_global():
global x # Declare x as global inside the function
x = 10 # Modify the global variable
print(x) # Output: 5 (before modification)
modify_global()
print(x) # Output: 10 (after modification)
The global keyword tells Python that x refers to the global variable and not a local one.
Without the global keyword, Python would create a new local variable x inside the function,
and the global variable would remain unchanged.
python
CopyEdit
x = 5
def modify_local():
x = 10 # Local variable (does not affect the global x)
print("Inside function:", x)
modify_local()
print("Outside function:", x) # Output: 5 (global x is unchanged)
The x inside the function is a local variable and does not affect the global x.
The global x remains unchanged after calling modify_local().
python
CopyEdit
y = 50 # Global variable
def increase_y():
global y # Declare y as global
y += 10 # Modify the global variable
Here, we used the global keyword to modify the global variable y inside the increase_y()
function.
python
CopyEdit
z = 100 # Global variable
def print_z():
print("Global z inside function:", z)
In this case, we accessed the global variable z inside the function but did not modify it. The
global variable remains the same outside the function.
python
CopyEdit
def local_variable_example():
a = 200 # Local variable
print("Inside function:", a)
The variable a is local to the function local_variable_example, and its lifetime is limited to
the execution of that function.
Key Points:
Local Scope: Variables defined inside a function are local and can only be accessed within that
function.
Global Scope: Variables defined outside of all functions are global and can be accessed
anywhere in the code.
Lifetime:
o Local variables are created when a function is called and destroyed when the function
finishes execution.
o Global variables remain in memory for the entire duration of the program.
Modifying Global Variables: To modify a global variable inside a function, use the global
keyword.
Local vs Global Variables: A variable inside a function is local unless explicitly declared as global.
Recursion is a programming technique where a function calls itself in order to solve a problem.
A recursive function typically has two main parts:
1. What is Recursion?
Recursion occurs when a function calls itself to solve smaller instances of a problem. It's a
powerful tool, often used for problems that can be broken down into smaller, similar
subproblems.
Example of Recursion:
A simple example of recursion is a function that calls itself to calculate the factorial of a number.
2. Advantages of Recursion
Simplifies Complex Problems: Recursion can make certain problems easier to solve. Problems
that involve repetitive tasks, such as traversing trees or solving puzzles like the Tower of Hanoi,
can be naturally solved with recursion.
Code Readability: Recursive functions tend to be shorter and easier to understand when
compared to iterative solutions (loops), especially for problems like searching or sorting.
Elegant Solution: Many algorithms, like Depth First Search (DFS), are more intuitive and easier
to implement recursively.
3. Disadvantages of Recursion
Stack Overflow: Recursion uses the call stack to keep track of function calls. If the recursion
goes too deep (i.e., there are too many recursive calls without hitting the base case), it can
cause a stack overflow, which results in an error.
Memory Usage: Since each recursive call creates a new function call, it can consume more
memory compared to an iterative approach.
Performance Overhead: Recursive functions can sometimes be less efficient than iterative
solutions because of the overhead involved in making function calls and maintaining the call
stack.
4. Hands-on Practice: Recursive Functions for Factorial and
Fibonacci
Let’s look at some practical examples of recursion: Factorial and Fibonacci series.
The factorial of a number n is the product of all positive integers less than or equal to n. The
formula for the factorial is:
scss
CopyEdit
n! = n * (n - 1) * (n - 2) * ... * 1
scss
CopyEdit
n! = n * (n-1)!
python
CopyEdit
def factorial(n):
# Base Case: if n is 0 or 1, return 1
if n == 0 or n == 1:
return 1
# Recursive Case: n * factorial of (n - 1)
else:
return n * factorial(n - 1)
Sample Execution:
For factorial(5):
The Fibonacci series is a sequence of numbers where each number is the sum of the two
preceding ones. The sequence starts with 0 and 1, and the next number is obtained by adding the
previous two numbers.
scss
CopyEdit
F(0) = 0, F(1) = 1
F(n) = F(n-1) + F(n-2) for n > 1
python
CopyEdit
def fibonacci(n):
# Base Case: F(0) = 0, F(1) = 1
if n == 0:
return 0
elif n == 1:
return 1
# Recursive Case: F(n) = F(n-1) + F(n-2)
else:
return fibonacci(n - 1) + fibonacci(n - 2)
Sample Execution:
For fibonacci(6):
scss
CopyEdit
factorial(5) → 5 * factorial(4)
factorial(4) → 4 * factorial(3)
factorial(3) → 3 * factorial(2)
factorial(2) → 2 * factorial(1)
factorial(1) → 1 (base case)
After reaching the base case, the function starts returning the results:
scss
CopyEdit
factorial(1) = 1
factorial(2) = 2 * 1 = 2
factorial(3) = 3 * 2 = 6
factorial(4) = 4 * 6 = 24
factorial(5) = 5 * 24 = 120
For fibonacci(6):
scss
CopyEdit
fibonacci(6) → fibonacci(5) + fibonacci(4)
fibonacci(5) → fibonacci(4) + fibonacci(3)
fibonacci(4) → fibonacci(3) + fibonacci(2)
fibonacci(3) → fibonacci(2) + fibonacci(1)
fibonacci(2) → fibonacci(1) + fibonacci(0)
fibonacci(1) = 1 (base case)
fibonacci(0) = 0 (base case)
scss
CopyEdit
fibonacci(0) = 0
fibonacci(1) = 1
fibonacci(2) = 1 (1 + 0)
fibonacci(3) = 2 (1 + 1)
fibonacci(4) = 3 (2 + 1)
fibonacci(5) = 5 (3 + 2)
fibonacci(6) = 8 (5 + 3)
6. Limitations and Optimization
Stack Overflow: If the recursion goes too deep, the Python interpreter will throw a
RecursionError due to the depth limit of the call stack.
o You can adjust the recursion depth limit using sys.setrecursionlimit() but be
cautious about using very high limits.
Memoization (Optimization): To avoid repeated calculations, especially in functions like
Fibonacci, we can optimize recursion using memoization. This involves storing results of
previous calls so that they can be reused, thus improving performance.
python
CopyEdit
def fibonacci_memo(n, memo={}):
if n in memo:
return memo[n]
if n == 0:
return 0
elif n == 1:
return 1
memo[n] = fibonacci_memo(n - 1, memo) + fibonacci_memo(n - 2, memo)
return memo[n]
print(fibonacci_memo(6)) # Output: 8
This reduces the number of recursive calls, improving the function's efficiency.
Summary:
python
CopyEdit
lambda arguments: expression
Unlike regular functions created with the def keyword, lambda functions are typically written in
a single line and do not have a name.
Example:
python
CopyEdit
add = lambda x, y: x + y
print(add(2, 3)) # Output: 5
Sorting is one of the most common use cases of lambda functions. If you want to sort a list of
items based on some criteria, you can use a lambda function as the sorting key.
The lambda function lambda person: person[1] returns the second element (the age) of
each tuple, and the sorted() function uses this value to sort the list.
Mapping involves applying a function to each element of a list or any other iterable. The map()
function in Python can be used with lambda functions to apply the operation to each element.
The lambda function lambda x: x ** 2 squares each element in the list numbers.
Filtering involves selecting elements from a collection that satisfy a condition. The filter()
function in Python allows you to filter elements of an iterable using a lambda function that
specifies the condition.
python
CopyEdit
# Lambda function for addition
add = lambda x, y: x + y
print(add(10, 20)) # Output: 30
python
CopyEdit
# Lambda function for multiplication
multiply = lambda x, y: x * y
print(multiply(3, 4)) # Output: 12
python
CopyEdit
# List of strings
words = ["apple", "banana", "cherry", "date"]
The lambda function lambda word: len(word) sorts the words by their length.
Example 4: Filtering Even Numbers
python
CopyEdit
numbers = [1, 2, 3, 4, 5, 6]
The lambda function lambda x: x % 2 == 0 returns True for even numbers, filtering out
odd numbers.
python
CopyEdit
numbers = [1, 2, 3, 4, 5]
Lambda functions are particularly useful when you want to define a small function inline,
without the need for a full function definition using def.
In Python, functions are first-class objects, meaning they can be passed around, returned from
other functions, and modified dynamically. This leads to some advanced concepts like
decorators and closures, which allow for more flexible and dynamic behavior. Let’s explore
these concepts in detail:
A decorator is a function that takes another function as input, and returns a new function that
typically calls the original function, possibly modifying its input or output. This allows you to
extend or alter the behavior of a function without permanently modifying the original function.
In Python, decorators are typically used with the @decorator_name syntax, placed above the
function definition that you want to decorate.
python
CopyEdit
def decorator_function(original_function):
def wrapper_function():
print("Function wrapped")
return original_function() # Call the original function
return wrapper_function
python
CopyEdit
@decorator_function
def say_hello():
print("Hello!")
say_hello()
javascript
CopyEdit
Function wrapped
Hello!
python
CopyEdit
def logger_decorator(func):
def wrapper():
print(f"Calling function {func.__name__}")
result = func() # Call the original function
print(f"{func.__name__} executed successfully")
return result
return wrapper
@logger_decorator
def greet():
print("Hello, World!")
greet()
Output:
bash
CopyEdit
Calling function greet
Hello, World!
greet executed successfully
If the function being decorated takes arguments, the decorator must be modified to accept them
as well. This is done by using *args and **kwargs to pass any arguments dynamically.
python
CopyEdit
def repeat_decorator(func):
def wrapper(*args, **kwargs):
print("Repeating function call...")
return func(*args, **kwargs)
return wrapper
@repeat_decorator
def say_hello(name):
print(f"Hello, {name}!")
say_hello("Alice")
Output:
vbnet
CopyEdit
Repeating function call...
Hello, Alice!
2. Function Closures
A closure is a function that "remembers" the values from the enclosing function even after the
enclosing function has finished execution. This means that the closure function has access to the
variables from its enclosing (outer) function even after it has returned.
In the following example, the inner function (closure) remembers the variable x even after the
outer function finishes execution.
python
CopyEdit
def outer_function(x):
def inner_function(y):
return x + y
return inner_function
closure = outer_function(10)
print(closure(5)) # Output: 15
Explanation:
The key idea is that the inner function remembers the value of x even after the outer function
has finished execution. This is a closure.
python
CopyEdit
def counter():
count = 0
def increment():
nonlocal count # Access the variable from the outer function
count += 1
return count
return increment
count_function = counter()
print(count_function()) # Output: 1
print(count_function()) # Output: 2
print(count_function()) # Output: 3
Explanation:
python
CopyEdit
import time
def timing_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs) # Call the original function
end_time = time.time()
print(f"{func.__name__} executed in {end_time - start_time:.4f}
seconds")
return result
return wrapper
@timing_decorator
def slow_function():
time.sleep(2)
print("Function finished!")
slow_function()
Output:
javascript
CopyEdit
Function finished!
slow_function executed in 2.0001 seconds
We’ll write a closure to remember the total sum of all numbers passed to it.
python
CopyEdit
def sum_closure():
total = 0
def add_to_sum(x):
nonlocal total
total += x
return total
return add_to_sum
sum_function = sum_closure()
print(sum_function(10)) # Output: 10
print(sum_function(20)) # Output: 30
print(sum_function(5)) # Output: 35
Explanation:
sum_closure() creates a closure add_to_sum() that remembers the state of total and
adds the passed value to it.
The nonlocal keyword ensures that the total variable from the enclosing scope is modified
inside the closure.
Decorators: Functions that wrap other functions to modify or enhance their behavior. Common
use cases include logging, caching, and access control.
o Syntax: @decorator_name
o Decorators can take arguments and return results.
Closures: Functions that remember the variables from their enclosing function even after the
outer function has returned. They allow us to maintain state across multiple calls.
o Closures are often used for counters, maintaining state, or for function factories.
Practical Examples: You can use decorators to log function calls, measure execution time, or
manage caching. Closures are useful for maintaining state between function calls, such as
creating a counter or managing a running total.
In Python, error handling is a way of gracefully dealing with unexpected situations (exceptions)
that occur during the execution of a program. This is particularly important in functions, as they
may encounter errors due to invalid inputs, unexpected conditions, or other issues. Python
provides a robust mechanism for error handling using the try, except, else, and finally
blocks, along with the ability to raise custom exceptions.
Exception handling is used to catch and handle errors (exceptions) in a way that allows the
program to continue running smoothly. If an error occurs in a part of the program, the normal
flow is interrupted, but with exception handling, we can "catch" the error, handle it, and even
proceed with alternative actions.
python
CopyEdit
try:
# Code that might raise an exception
except SomeException as e:
# Code to handle the exception
else:
# Code to run if no exception occurs
finally:
# Code that runs no matter what
try: This block contains the code that might raise an exception. If an exception is raised here,
Python will look for an appropriate except block.
except: If an exception occurs in the try block, it is caught here. You can catch specific
exceptions, or catch all exceptions.
else: This block is executed if no exception occurs in the try block. It's optional but useful for
clean-up or post-processing tasks.
finally: This block is executed regardless of whether an exception occurred or not. It is often
used for clean-up tasks, such as closing files or releasing resources.
python
CopyEdit
def divide_numbers(a, b):
try:
result = a / b
except ZeroDivisionError as e:
print(f"Error: {e}")
else:
print(f"Division successful, result is: {result}")
finally:
print("Execution completed.")
divide_numbers(10, 2)
divide_numbers(10, 0)
Output:
vbnet
CopyEdit
Division successful, result is: 5.0
Execution completed.
Error: division by zero
Execution completed.
In the first call, the division is successful, and the else block is executed.
In the second call, a ZeroDivisionError is raised, and the except block catches and handles
the error.
You can catch multiple types of exceptions by adding multiple except blocks.
python
CopyEdit
def safe_divide(a, b):
try:
return a / b
except ZeroDivisionError:
print("Cannot divide by zero!")
except TypeError:
print("Both inputs must be numbers!")
else:
print("Division was successful!")
Sometimes, you may want to manually trigger an exception if certain conditions are met. You
can use the raise keyword to raise a custom exception.
python
CopyEdit
raise Exception("Error message")
You can also define your own custom exception class by inheriting from Python’s built-in
Exception class.
python
CopyEdit
class NegativeNumberError(Exception):
"""Custom exception raised when a negative number is provided."""
pass
def check_positive_number(number):
if number < 0:
raise NegativeNumberError("Negative number is not allowed.")
else:
print(f"Number {number} is valid.")
try:
check_positive_number(-5)
except NegativeNumberError as e:
print(f"Error: {e}")
Output:
typescript
CopyEdit
Error: Negative number is not allowed.
In this example:
You can also raise built-in exceptions when necessary. For example, raising a ValueError if the
input is not valid:
python
CopyEdit
def check_age(age):
if age < 18:
raise ValueError("Age must be 18 or older.")
print("Age is valid.")
try:
check_age(15)
except ValueError as e:
print(f"Error: {e}")
Output:
javascript
CopyEdit
Error: Age must be 18 or older.
Let's write a function to calculate the square root of a number and handle invalid inputs like
negative numbers or non-numeric inputs.
python
CopyEdit
import math
def calculate_square_root(value):
try:
if value < 0:
raise ValueError("Cannot calculate square root of a negative
number.")
return math.sqrt(value)
except ValueError as e:
print(f"Error: {e}")
except TypeError:
print("Error: Input must be a number.")
else:
print("Square root calculated successfully.")
finally:
print("Function execution completed.")
calculate_square_root(16)
calculate_square_root(-4)
calculate_square_root("hello")
Output:
typescript
CopyEdit
Square root calculated successfully.
Function execution completed.
Error: Cannot calculate square root of a negative number.
Function execution completed.
Error: Input must be a number.
Function execution completed.
Let’s raise a custom exception when trying to withdraw an amount greater than the account
balance:
python
CopyEdit
class InsufficientFundsError(Exception):
"""Custom exception for insufficient funds."""
pass
try:
balance = 500
balance = withdraw(balance, 600)
except InsufficientFundsError as e:
print(f"Error: {e}")
else:
print(f"Withdrawal successful. New balance is {balance}.")
Output:
javascript
CopyEdit
Error: Insufficient funds in your account.
The InsufficientFundsError is raised if the withdrawal amount exceeds the balance, and
the error is caught and printed.
try, except, else, and finally are used for catching and handling exceptions, allowing the
program to continue running or clean up resources even if an error occurs.
Raising Exceptions: Use the raise keyword to raise built-in or custom exceptions when a
function or program encounters an error condition.
o Custom exceptions can be defined by subclassing the Exception class.
Handling Multiple Exceptions: You can use multiple except blocks to handle different types of
exceptions.
finally Block: Code inside finally will always run, regardless of whether an exception
occurred or not. This is ideal for cleanup tasks.
In Python, exception handling is used to handle runtime errors gracefully instead of crashing the
program. The try-except block allows us to catch errors and take appropriate actions.
🔹 What is an Exception?
An exception is an error that occurs during program execution. Common examples include:
✅ ZeroDivisionError – Dividing by zero
✅ ValueError – Invalid data type conversion
✅ FileNotFoundError – Trying to open a missing file
✅ IndexError – Accessing an out-of-range index in a list
Instead of stopping the program abruptly, Python provides try-except to handle these
exceptions.
✅ Output:
csharp
CopyEdit
Cannot divide by zero!
✅ Possible Outputs:
css
CopyEdit
Invalid input! Please enter a number. # If input is 'abc'
csharp
CopyEdit
Cannot divide by zero. # If input is 0
python
CopyEdit
try:
num = int(input("Enter a number: "))
result = 10 / num
except ZeroDivisionError:
print("You cannot divide by zero!")
except ValueError:
print("Invalid input! Please enter a number.")
else:
print(f"Result: {result}") # Executes only if no error occurs
finally:
print("Execution completed.") # Always executes
✅ Possible Outputs:
yaml
CopyEdit
Enter a number: 2
Result: 5.0
Execution completed.
csharp
CopyEdit
Enter a number: 0
You cannot divide by zero!
Execution completed.
🔹 Raising Custom Exceptions using raise
python
CopyEdit
try:
age = int(input("Enter your age: "))
if age < 0:
raise ValueError("Age cannot be negative!")
except ValueError as e:
print(f"Error: {e}")
✅ Output:
yaml
CopyEdit
Enter your age: -5
Error: Age cannot be negative!
Start with beginner tasks and gradually move to intermediate and advanced tasks as
you get comfortable with the concepts.
Practice debugging your code when exceptions or errors occur.
Try to modify existing tasks to add more complexity (e.g., adding new conditions or
operations).
Use external libraries or modules for advanced tasks to boost your understanding.