0% found this document useful (0 votes)
16 views

Chapter 02 Advanced Data Structures and Functions

Uploaded by

Aya
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

Chapter 02 Advanced Data Structures and Functions

Uploaded by

Aya
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 103

1

Data Structure
A particular way of organizing data in a computer
Collection is a single “variable” used to store multiple values,
1- List = [ ] ordered and (mutable) changeable ; duplicates are allowed
2- Set = { } unordered and mutable, No duplicates
3- Tuple = ( ) ordered and immutable, duplicates allowed, Faster
4- Dictionary = { key : value} pairs, ordered and changeable, No duplicates

2
Very Useful Tip
# print all the attributes and methods of this data
structure
print(dir(collection_name))

# in details
print(help(collection_name))

3
What are LISTS ?

• A list is a sequential collection of values (called


elements) where each value is identified by an
index.
• The FIRST index is ZERO.
• Lists are ordered and mutable ( can
change their items)
• duplicates are allowed
4
What are LISTS ?
• The simplest way to create a list in Python is to enclose
the elements in square brackets. We can use range also.

my_list = [ 1,2,9,4]
• The elements of a list do not have to be of the
same type.
my_list =["Hello", 5, 3.8, [6,8] , (45,68)]
print(my_list)
5
What are LISTS ?
• Accessing Lists
my_integers = [2,4,8,16,32]
To retrieve the first element :

myFirstElement = my_integers[0]
To retrieve the second element :

mySecondElement = my_integers[1]
6
What are LISTS ?
• Accessing Lists
my_integers = [2,4,8,16,32]
One way to get last element :

myLastElement = my_integers[-1]

7
What are LISTS ?
• Accessing Lists
myList = ['P', 'Y', 'T', 'H', 'O', 'N']

Index

Index

myList[4] == myList[-2] == “O” 8


What are LISTS ?
• List Slicing Remember:
>>> t = [9, 41, 12, 3, 74, 15] the second number is
>>> t[1:3] “up to but not including”
[41,12]
>>> t[:4] listName[start:end:step]
[9, 41, 12, 3]
# Reverse the list
>>> t[3:] reversed_lst = lst[::-1] # lst[-1::-1]
[3, 74, 15]
>>> t[:] # Get every second element
[9, 41, 12, 3, 74, 15] every_second = lst[::2]
9
What are LISTS ?
• Adding to Lists my_integers = [2, 4, 8, 16, 32]
To add another element :

my_integers.append(46)
my_integers = my_integers + [46]

my_integers += [46]

10
What are LISTS ?
Modifying my Lists
my_integers = [2, 4, 8, 16, 32,46]
To change an element :
my_integers[5] = 64
To delete an element (using an index) :
del my_integers[3]
To remove a value in the list :
my_integers.remove(2) 11
What are LISTS ?
Modifying my Lists
my_integers = [2, 4, 8, 16, 32,46]
To pop a value from the list :
Value= my_integers.pop() # can be used with append()
to create a stack (LIFO last in first out)
print(my_integers) # prints [2, 4, 8, 16, 32]

Pop with index


my_integers.pop(0) # [4, 8, 16, 32] 12
What are LISTS ?
Modifying my Lists
my_integers = [2, 4, 8, 16, 32,46]
To insert a value into the list:
List.insert(index,object)

Example:
my_integers.insert(0, 10) # [10,2, 4, 8, 16, 32,46]

13
What are LISTS ?

my_integers = [2, 4, 8, 16, 32,46]


The length of a list ( Elements count) :
length = len(my_integers)

words=["moon","sun","tree","world","ice"]
words.sort() # result ?
words.sort(key=len) # result ?

14
Functions
 append  Indexing e.g., L[i]
 insert  Slicing e.g., L[1:5]
 index
 count
 Concatenation e.g., L + L
 sort  Repetition e.g., L * 5
 reverse
 Membership test e.g., ‘a’ in L
 remove
 pop  Length e.g., len(L)
 extend
List_name.function(arguments) 15
s = [1,2,3]
t = ['begin', s, 'end']
>>> t
['begin', [1, 2, 3], 'end']

>>> t[1][1]
2
16
# Traditional way
squares = []
for x in range(10):
squares.append(x**2)

# Using list comprehension


squares = [x**2 for x in range(10)]

17
Use conditional expressions within comprehensions.
even_squares = [x**2 for x in range(10) if x % 2 == 0]

Nested Lists with comprehensions

matrix = [[j for j in range(5)] for i in range(3)]


print(matrix)
# Output: [[0, 1, 2, 3, 4], [0, 1, 2, 3, 4], [0, 1, 2, 3, 4]]

element = matrix[1][2] # Accesses the element at row 1, column 2 18


Flattening a list of lists:
nested = [[1, 2], [3, 4], [5]]
flattened = [item for sublist in nested for item in sublist]

print(flattened) # prints [1, 2, 3, 4, 5]

Old method:
flattened=[]
for sublist in nested:
for item in sublist:
flattened.append(item)

19
20
Tuple is a collection which is ordered and immutable
Duplicates are allowed, Faster data structure

coordinates = (10, 20)


How to make a tuple? In round brackets
Example:
>>> t = ()
>>> t = (1, 2, 3)
>>> t = (1, )
Check the type with
>>> t = 1,
>>> a = (1, 2, 3, 4, 5)
print(type(t))
>>> print (a[1]) # 2
21
Assign tuple elements to variables.

a, b = (1, 2)
print(a) # Output: 1

# Swapping variables
a, b = b, a

print(a) # Output: 2

22
a= [1,2,3,4,5]
a[1]=6 # not allowed  Error

Traceback (most recent call last):


File "c:\Users\Salim\Untitled-1.py", line 2, in <module>
a[1]=6
~^^^
TypeError: 'tuple' object does not support item assignment

23
Operations in Tuple
 Indexing e.g., T[i]
 Slicing e.g., T[1:5]
 Concatenation e.g., T + T
 Repetition e.g., T * 5
 Membership test e.g., ‘a’ in T
 Length e.g., len(T)

24
Operations in Tuple
 Indexing e.g., T[i]
 Slicing e.g., T[1:5]
 Concatenation e.g., T + T
 Repetition e.g., T * 5
 Membership test e.g., ‘a’ in T
 Length e.g., len(T)

25
Operations in Tuple
What do you think ?

a= ([1,5,66],2,"hello",4,5)
print(a[2][1]) # ?
print(a[1][1]) # ?

26
Operations in Tuple
What do you think ?

a= ([1,5,66],2,"hello",4,5)
print(a[2][1]) # ?
print(a[1][1]) # ?

27
Tuple’s pre-built functions
Tuple_name.count(value)
Tuple_name.index(value)
a= ([1,5,66],2,"hello",5,4,5)
print(a.count(5)) # answer is 2
print(a.index(5)) # answer is 3

28
Tuple with loops

a= ([1,5,66],2,"hello",5,4,5)
for item in a:
print(item)

29
Named Tubles
Will be discussed in OOP chapter
# Python code to demonstrate namedtuple()
from collections import namedtuple

# Declaring namedtuple()
Student = namedtuple('Student', ['name', 'age', 'DOB'])

# Adding values
S = Student('Nandini', '19', '2541997')

# Access using index


print("The Student age using index is : ", end="")
print(S[1])

# Access using name


print("The Student name using keyname is : ", end="")
30
print(S.name)
Tubles in functions as return values
Will be discussed in functions

def get_min_max(numbers):
return min(numbers), max(numbers)

min_val, max_val = get_min_max([1, 2, 3, 4, 5])

print(type(get_min_max([1, 2, 3, 4, 5]))) # <class 'tuple'>

31
SETs
32
Sets
A set is a collection of elements

Set = { } # declared with curly brackets

unordered : No index or positional ordering


Mutable collection ( add/ remove)
Elements must be immutable (no lists or dictionaries)
No duplicates ( unique elements)

33
Sets
Why use sets?
Fast membership testing
Efficient operations for union, intersection, and difference
accepted_set = {1, 2, 3}
rejected_set = {1, [2,6], 3}# error no lists allowed
empty_set = set()

34
Sets
Basic Set Operations
Adding Elements:
my_set.add(4)
Removing Elements:
my_set.remove(2) # Raises KeyError if not found
my_set.discard(2) # Safe remove

35
Sets
Set’s Methods
Membership Testing: print( 3 in my_set)

if 3 in my_set:
print("Found")
Clear all elements: my_set.clear()
Copying a Set: new_set = my_set.copy()
Remove and return the first element: elem=my_set.pop()
36
Built-in Set Methods
Mathematical Set Operations
Union: set1.union(set2) # OR set1 | set2
Intersection: set1.intersection(set2) # OR set1 & set2
Difference: set1.difference(set2) # OR set1 - set2

37
Built-in Set Methods
Mathematical Set Operations
TODO by you: Try and understand the use of these
methods
set1.update
set1.difference_update
set1.intersection_update
set1.symmetric_difference
set1.symmetric_difference_update
set1.issubset(set2)
set1.issuperset(set2) 38
Sets are useful for duplication removal

my_list = [8, 9,10,9,8,7,4,2,10,9,6,5,4,85,5,6,9,5,54,54,5,49,8,46]


my_list= list(set(my_list)) # must cast it back to a list
print(my_list)

39
A100% immutable variation of Sets

Frozen Sets
frozen_set = frozenset([1, 2, 3])
frozen_set: has NO add, remove, discard,clear or pop methods

40
41
Dictionaries

A dictionary is a collection of key:value pairs.


Keys: Must be unique and immutable (e.g., strings,
numbers, tuples).
Values: Can be any data type.

Use Cases: Efficient data retrieval, structured data


representation.

42
Dictionaries

Creating a Dictionary
Syntax
dict = {'key1': 'value1', 'key2': 'value2'}

Empty Dictionary: empty_dict = {}

43
Dictionaries

Accessing Dictionary Elements

Access by Key:
value = dict['key1'] # returns an error if « key not found »

Using get() Method (returns None if key not found):


value = dict.get('key1') # this is better

44
Dictionaries
Modifying a Dictionary

Adding or Updating Elements:


dict['key3'] = 'value3' # Add or update

Removing Elements:
Using del: del my_dict['key1']
Using pop() (returns the removed value):
val=my_dict.pop('key2') # we can remove val=
45
Methods in Dictionary
Common Methods:
keys(): Returns all keys.
values(): Returns all values.
items(): Returns all key-value pairs.

keys = dict.keys()
values = dict.values()
items = dict.items()

46
Methods in Dictionary
 has_key(key)
 clear()
 copy() makes a copy of the dictionary
 get(key[,x])
 setdefault(key[,x]) Returns the value of a key; if the key does not exist, inserts
the key with a default value ex: dict.setdefault('key4', 'default_value')
 update(D) Updates the dictionary with elements from another dictionary or
iterable.
 popitem() removes and return the last inserted item ( key:value)
example: key, value = dict.popitem() 47
Methods in Dictionary
Checking for Keys
Using in Operator:
if 'key1' in dict:
print("Key found")

48
Methods in Dictionary
Iterating Over a Dictionary
To extract Keys only
for key in dict:
print(key)

for key in dict.keys():


print(key)
Keys will be listed in arbitrary order 49
Methods in Dictionary
Iterating Over a Dictionary
To extract Values only:

for value in dict.values():


print(value)

50
Methods in Dictionary
Iterating Over a Dictionary
To extract keys and values:

for key,value in dict.items():


print(key, value)

51
Nested Dictionaries
Creating a Nested Dictionary:
nested_dict = {
'dict1': {'keyA': 'valueA'},
'dict2': {'keyB': 'valueB'}
}

Accessing Nested Values:


value = nested_dict['dict1']['keyA']

52
Nested Dictionaries
Merging Dictionaries (Python 3.9+):
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
merged_dict = dict1 | dict2 # Output: {'a': 1, 'b': 3, 'c': 4}

53
Nested Dictionaries

Intersection of Dictionaries ( TODO by YOU)

How ?

54
55
What is a Function

Functions in Python allow you to encapsulate


a block of code to perform a specific task,
making your code more organized, reusable,
and modular.
Functions help break a problem into smaller,
manageable parts.
56
What is a Function
General syntax:
def function_name(parameters):
# code block
return value

def keyword is used to declare a function.


function_name: Identifier for the function.
parameters: Inputs to the function (optional).
return: Output or return value of the function (optional).
57
What is a Function
Creating and Calling Functions
Example: A basic function that prints a greeting message
def greet():
print("Hello, Welcome to Python Functions!")

greet() # Calling the function

Output Hello, Welcome to Python Functions!


58
What is a Function
Function Parameters and Arguments

def greet(name): # 'name' is a parameter


print(f"Hello, {name}!")

greet("Alice") # 'Alice' is an argument

Parameters: Variables listed inside the function definition.


Arguments: Values passed into the function when it is called.
59
Functions: Return Values
Returning Single Values
Functions can return data to the caller using the return keyword.
def square(x):
return x ** 2

result = square(5)
print(result) # Output: 25

60
Functions: Return Values
Returning Multiple Values
You can return multiple values by separating them with commas.
def calculate(x, y):
sum_ = x + y
product = x * y
return sum_, product

result_sum, result_product = calculate(4, 5)


print(result_sum, result_product) # Output: 9 20
61
Functions: Function Arguments
Positional and Keyword Arguments
Positional arguments are assigned based on their position in the function call.

def greet(first, last):


print(f"Hello, {first} {last}!")

greet("John", “Smith") # Output: Hello, John Smith!

62
Functions: Function Arguments
Positional and Keyword Arguments
Keyword arguments allow you to pass arguments by explicitly naming them.

greet(last=“Smith", first="John") # Output: Hello, John


Smith!

63
Functions: Function Arguments
Default Arguments
Default values can be assigned to function parameters.

def greet(name="Stranger"):
print(f"Hello, {name}!")

greet() # Output: Hello, Stranger!


greet("Alice") # Output: Hello, Alice!

64
Functions: Function Arguments
Arbitrary Arguments (*args, **kwargs)
*args allows you to pass a variable number of positional arguments.
**kwargs allows you to pass a variable number of keyword arguments.
def total_sum(*args):
return sum(args)

print(total_sum(1, 2, 3, 4)) # Output: 10


def display_details(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")

display_details(name="Alice", age=25) # Output: name: Alice, age:


65
25
Functions: Lambda Functions
What is a Lambda Function?
A lambda function is a small anonymous function defined
using the lambda keyword
Syntax:
lambda arguments: expression
Lambda functions are used for short, simple operations.
def myfunction(parameters):
The normal function
value = expression
return value 66
Functions: Lambda Functions
What is a Lambda Function?
Example:
square = lambda x: x ** 2
print(square(5)) # Output: 25
Example: Lambda with multiple arguments.
add = lambda x, y: x + y
print(add(3, 4)) # Output: 7

67
Functions: Lambda Functions
Lambda in filter(), map() and reduce()
filter(function,iterable) filters elements from an iterable
based on a condition.

nums = [1, 2, 3, 4, 5, 6]
even_nums = list(filter(lambda x: x % 2 == 0, nums))
print(even_nums) # Output: [2, 4, 6]

68
Functions: Lambda Functions
Lambda in filter(), map() and reduce()
map(function,iterable) applies a function to all items in an
iterable:

nums = [1, 2, 3, 4]
squared = list(map(lambda x: x ** 2, nums))
print(squared) # Output: [1, 4, 9, 16]

69
Functions: Lambda Functions
Lambda in filter(), map() and reduce()
The reduce(function,iterable) function from functools
reduces an iterable to a single value by applying a function
cumulatively.
from functools import reduce
nums = [1, 2, 3, 4]
result = reduce(lambda x, y: x + y, nums)
print(result) # Output: 24
70
Functions: Lambda Functions
Lambda in filter(), map() and reduce()
from functools import reduce
def add(a,b):
return a+b
With a normal function

nums = [1, 2, 3, 4]
result = reduce(add, nums)
print(result) # Output: 24
With lambda function
from functools import reduce
nums = [1, 2, 3, 4]
result = reduce(lambda x, y: x + y, nums)
print(result) # Output: 24 71
Special and Advanced Functions
Recursive Functions
A recursive function is a function that calls itself to
solve a problem.
def factorial(n):
if n == 1:
return 1
else:
return n * factorial(n - 1)

print(factorial(5)) # Output: 120


72
Special and Advanced Functions
Recursive Functions

Create a recursive Power(x,n) function

73
Special and Advanced Functions
Higher-Order Functions
A function that takes another function as an argument or
returns a function is called a higher-order function.
def outer_function(message):
def inner_function():
print(message)
return inner_function

my_func = outer_function("Hello!") # inner_function is


returned, Not called
my_func() # Output: Hello! 74
Special and Advanced Functions
Decorators
• A decorator is a function that takes another function and extends
its behavior without explicitly modifying it.
• They are often used in scenarios like logging, access control,
memoization (caching the results of a function), etc.

75
Special and Advanced Functions
Decorators
def decorator_function(func):
def wrapper():
# Extend or modify behavior
print("Before function call")
func()
Output:
print("After function call") Before function call
return wrapper
Hello!
@decorator_function After function call
def say_hello():
print("Hello!")

say_hello() 76
Special and Advanced Functions
Function Arguments in Decorators
• Decorators can also handle functions with arguments.
def decorator_with_args(func):
def wrapper(*args, **kwargs):
print(f"Arguments passed: {args}")
return func(*args, **kwargs)
return wrapper

@decorator_with_args
def add(a, b):
return a + b

result = add(3, 5)
77
print(result) # Output: 8
Special and Advanced Functions
Chaining Multiple Decorators
• You can apply multiple decorators to a single function by stacking
@decorator_name lines.

@decorator_one
@decorator_two
def my_function():
pass # Placeholder

78
Special and Advanced Functions
Closures
Key Characteristics of a Closure:
Nested function: There is a function defined inside another
function.
Enclosing scope: The inner function captures the variables from the
outer function's scope.
Returned function: The outer function returns the inner function,
which can still access the variables of the outer function.

79
Special and Advanced Functions
Closures

• A closure occurs when a function retains the state of its lexical


environment even after the outer function has finished execution.

80
Special and Advanced Functions
Closures are useful when:
• keeping track of function state, and more.
Example: Creating a counter with closure:
def counter():
count = 0
def increment():
nonlocal count nonlocal ?
count += 1
return count
return increment

my_counter = counter()
print(my_counter()) # Output: 1
81
print(my_counter()) # Output: 2
Special and Advanced Functions
Closures
Closures are useful when:
• You want to delay execution but still "remember" the state of
variables.
• You want to encapsulate logic in a function and maintain access to
data without using global variables.
• Closures are commonly used in decorators, callbacks, and when
building function factories.
82
Special and Advanced Functions
Currying Functions
• Currying is the process of transforming a function with multiple
arguments into a series of functions that each take one argument.
def multiply(a):
def by(b):
return a * b Instead of multiply(2,5)
return by

doubler = multiply(2)
print(doubler(5)) # Output: 10

It’s possible to call with of multiply(2) (5) 83


Special and Advanced Functions
Currying Functions

Currying with lambda ?

Write a curried function that multiplies three


numbers and returns the product.

?
84
Special and Advanced Functions
Function Composition
Function Composition is a fundamental concept in functional
programming where multiple functions are combined into a
single function. The output of one function becomes the input
of another. This technique allows you to build complex
operations by composing simpler functions. ( Sounds like
pipline ?)

85
Special and Advanced Functions
Function Composition
def add(x):
return x + 2

def multiply(x):
return x * 3

def compose(f, g):


return lambda x: f(g(x))

# f(g(x)) = multiply(add(5)) -> multiply(5 + 2) -> 7 * 3 = 21


composed = compose(multiply, add)
print(composed(5)) # Output: 21
86
Special and Advanced Functions
# Define functions
def clean_data(data):
return [x.strip() for x in data]

def filter_data(data):
return [x for x in data if x]

def process_data(data):
return [x.upper() for x in data]

# Define compose_multiple without lambda or reduce


def compose_multiple(func1, func2, func3):
def composed(data):
data = func1(data) # Apply the first function
data = func2(data) # Apply the second function
return func3(data) # Apply the third function
?
return composed
# Create data pipeline
data_pipeline = compose_multiple(clean_data, filter_data, process_data)
# Input data
data = [" apple ", "", "banana ", " ", "cherry "]
# Process the data through the pipeline
processed = data_pipeline(data)
print(processed) # Output: ['APPLE', 'BANANA', 'CHERRY'] 87
Special and Advanced Functions
Generator Functions
• Generator functions return an iterator and are written using yield
instead of return. They allow lazy evaluation and memory
efficiency by producing items one at a time.
def simple_generator():
yield 1
yield 2
yield 3
len() WONT WORK

for value in simple_generator(): Generators have no length


print(value) # Output: 1 2 3 88
Special and Advanced Functions
send() and close() with Generators
• Generators can also receive values using the send() method and can
be stopped with close().
def generator():
value = 0
while True:
value = yield value
if value is None:
break
gen = generator()
next(gen)
print(gen.send(10)) # Output: 10
89
gen.close()
Special and Advanced Functions
Coroutines
Coroutines are generalizations of subroutines, and they allow pausing and resuming
execution. They are defined with async def and executed with await.
Coroutines are used for non-blocking I/O operations such as reading files or making
network requests.
import asyncio

async def fetch_data():


print("Fetching data...")
await asyncio.sleep(2) # Simulate a network call or delay
return {"data": "example"}

result = asyncio.run(fetch_data())
print(result) 90
Special and Advanced Functions
Coroutines with Multiple Await Calls
You can chain multiple asynchronous operations using await inside a coroutine. For
example, let’s extend the fetch_data() coroutine to simulate multiple steps in an
asynchronous workflow.
import asyncio

async def fetch_data():


print("Fetching data...")
await asyncio.sleep(2) # Simulate network call
data = {"data": "example"}

print("Processing data...")
await asyncio.sleep(1) # Simulate processing delay
data["processed"] = True

return data

result = asyncio.run(fetch_data()) 91
print(result)
Special and Advanced Functions
Coroutines with Multiple Tasks

One of the biggest advantages of coroutines is that they allow


you to run multiple tasks concurrently without blocking the
main thread.
You can use asyncio.gather() to run multiple coroutines at
the same time.

92
Special and Advanced Functions
Coroutines with Multiple Tasks
Example: Running Multiple Coroutines Concurrently
import asyncio

async def fetch_data_1():


print("Fetching data from source 1...")
await asyncio.sleep(3) # Simulate network delay
return "Data from source 1"

async def fetch_data_2():


print("Fetching data from source 2...")
await asyncio.sleep(1) # Simulate network delay
return "Data from source 2" Output ?
async def main():
# Run both coroutines concurrently Fetching data from source 1...
results = await asyncio.gather(fetch_data_1(), fetch_data_2()) Fetching data from source 2...
print(results) ['Data from source 1', 'Data
from source 2']
# Run the main coroutine 93
asyncio.run(main())
Special and Advanced Functions
Error Handling in Coroutines
Just like normal functions, coroutines can also raise exceptions. You can
handle exceptions within coroutines using try-except blocks.
import asyncio

async def fetch_data():


try:
print("Fetching data...")
await asyncio.sleep(2)
# Simulate an error
raise ValueError("Data fetch failed!") Output
except ValueError as e:
print(f"Error occurred: {e}")
Fetching data...
return {"data": "default"}
Error occurred: Data fetch
failed! {'data': 'default'}
result = asyncio.run(fetch_data())
print(result)
94
Special and Advanced Functions
Coroutine with asyncio.wait_for()
You can set timeouts for coroutines using asyncio.wait_for() to prevent them
from running indefinitely.
import asyncio

async def slow_task():


await asyncio.sleep(5)
return "Task completed"

async def main():


try:
result = await asyncio.wait_for(slow_task(), timeout=3)
print(result)
except asyncio.TimeoutError:
print("The task timed out!")

# Run the main coroutine


95
asyncio.run(main())
Special and Advanced Functions
Chaining Coroutines
You can create chains of coroutines where one coroutine awaits another.
import asyncio
async def step1():
print("Step 1")
await asyncio.sleep(1)
return "result from step 1"

async def step2(previous_result):


print(f"Step 2 received: {previous_result}")
await asyncio.sleep(1)
return "result from step 2"

async def main():


result1 = await step1()
result2 = await step2(result1)
print(result2)
96
asyncio.run(main())
Special and Advanced Functions
When to Use Coroutines
Coroutines are particularly useful in the following scenarios:
I/O-bound operations: Reading or writing files, making HTTP requests,
interacting with databases.
Concurrent tasks: Performing multiple tasks simultaneously without blocking
each other.
Event-driven systems: Tasks that need to wait for events to occur, such as
network requests, timers, or user inputs.

Coroutines are less useful for CPU-bound tasks, such as mathematical


computations or data processing that require constant CPU usage. For those,
multithreading or multiprocessing is more appropriate.
97
Special and Advanced Functions
When to Use Coroutines
Coroutines are particularly useful in the following scenarios:
I/O-bound operations: Reading or writing files, making HTTP requests,
interacting with databases.
Concurrent tasks: Performing multiple tasks simultaneously without blocking
each other.
Event-driven systems: Tasks that need to wait for events to occur, such as
network requests, timers, or user inputs.

Coroutines are less useful for CPU-bound tasks, such as mathematical


computations or data processing that require constant CPU usage. For those,
multithreading or multiprocessing is more appropriate.
98
99
Predefined Functions
and Libraries
100
Predefined Functions and Libraries
Python’s Built-in Functions

Python provides many predefined functions, such


as len(), type(), abs(), sorted(), max(), etc.
print(len("Python")) # Output: 6
print(abs(-10)) # Output: 10
print(sorted([3, 1, 4, 2])) # Output: [1, 2, 3,
4]

101
Predefined Functions and Libraries
Useful Libraries for Functions
• math: Provides mathematical functions.
• itertools: Contains useful tools for iteration, such as
chain(), combinations(), permutations().
• functools: Provides higher-order functions like reduce().
import math
print(math.sqrt(16)) # Output: 4.0

from itertools import permutations


print(list(permutations([1, 2, 3]))) # Output:
[(1, 2, 3), (1, 3, 2), (2, 1, 3), ...] 102
Any questions ?

103

You might also like