Unit - Iii
Unit - Iii
Functions: Function Definition – Function Call – Variable Scope and its Lifetime-
Return Statement. Function Arguments: Required Arguments, Keyword Arguments,
Default Arguments and Variable Length ArgumentsRecursion. Python Strings: String
operations- Immutable Strings - Built-in String Methods and Functions - String
Comparison. Modules: import statementThe Python module – dir() function –
Modules and Namespace – Defining our own modules.
Introduction to Functions
Basic Syntax
To define a function in Python, you use the def keyword followed by the function
name, parentheses, and a colon. The body of the function is indented.
def function_name(parameters):
# Function body
# Code to be executed
return result
Components of a Function
def my_function():
print(x) # Accessing global variable
my_function() # Output: 30
print(x)
Output: 30
Built-in Scope
▪ Definition: Contains built-in functions and names that are always available in
Python.
▪ Access: Anywhere in the code.
def create_variable():
x = [1, 2, 3] # Local variable, will be garbage collected after function exits
print(x)
create_variable()
gc.collect() # Manually invoking garbage collection
Static and Dynamic Lifetime
▪ Static Lifetime:
o Variables with a static lifetime exist for the duration of the program.
o Examples: Global variables, constants.
▪ Dynamic Lifetime:
o Variables with a dynamic lifetime exist only during specific periods of
execution.
o Examples: Local variables, temporary objects.
Lifetime in Context of Classes and Objects
▪ Instance Variables:
o Variables defined inside a class constructor (__init__ method).
o Lifetime: Exist as long as the instance (object) exists.
• Class Variables:
o Variables defined inside a class but outside any method.
o Lifetime: Exist as long as the class is in memory.
• Example:
class MyClass:
class_variable = "I am a class variable" # Class variable
age: 40
location: TIRUPATTUR
result = add(5, 3)
print(result)
Output: 8
Returning Multiple Values
▪ Tuple Packing and Unpacking:
o Python allows functions to return multiple values as a tuple.
o These values can be unpacked into separate variables.
• Example:
def get_name_and_age():
name = "SKS"
age = 40
return name, age
result = no_return()
print(result)
Output: None
Function Arguments
Introduction
▪ Function Arguments: Values passed to a function when it is called.
▪ Parameters: Variables listed in the function definition.
Required Arguments
▪ Definition: Arguments that must be provided to the function in the correct
positional order.
▪ Usage: Used when a function needs specific values to operate.
Example:
def add(a, b):
return a + b
result = add(3, 5)
print(result)
Output: 8
# add(3) # This will raise an error because the second argument is missing
Keyword Arguments
▪ Definition: Arguments passed to a function by explicitly specifying the
parameter names.
▪ Usage: Improves readability and allows changing the order of arguments.
Example:
def greet(name, message):
print(f"Hello, {name}! {message}")
str2 = "12345"
is_digit = str2.isdigit() # True
str3 = "Hello123"
is_alnum = str3.isalnum() # True
# Efficient
result = "".join(words)
Example: String Operations
▪ Basic Example:
str1 = "Hello, World!"
print(str1.upper()) # 'HELLO, WORLD!'
print(str1.lower()) # 'hello, world!'
print(str1.replace("World", "Python")) # 'Hello, Python!'
print(str1.split(",")) # ['Hello', ' World!']
print(" ".join(["Hello", "Python"])) # 'Hello Python'
Immutable Strings
▪ Definition: Immutability means that once a string is created, it cannot be
changed. Any operation that appears to modify a string will actually create a
new string.
▪ Example:
str1 = "Hello"
# Attempting to change a character will result in an error
# str1[0] = 'J' # Raises TypeError: 'str' object does not support item
assignment
Implications of Immutability
▪ Memory Efficiency: Reusing the same string object reduces memory usage.
▪ Thread Safety: Immutable objects are inherently thread-safe since they cannot
be modified after creation.
Creating New Strings from Existing Ones
▪ Concatenation: Results in a new string.
str1 = "Hello"
str2 = str1 + " World" # New string "Hello World"
▪ Replacement: Results in a new string.
str1 = "Hello"
str2 = str1.replace("H", "J") # New string "Jello"
Common Operations Creating New Strings
▪ Slicing:
str1 = "Hello"
substr1 = str1[:2] # New string "He"
▪ Case Conversion:
str1 = "Hello"
upper_str = str1.upper() # New string "HELLO"
lower_str = str1.lower() # New string "hello"
▪ Trimming Whitespace:
str1 = " Hello "
stripped_str = str1.strip() # New string "Hello"
In-Place Modifications (Not Allowed)
▪ Since strings are immutable, there are no in-place modification methods. Any
"modification" results in the creation of a new string.
str1 = "Hello"
# Attempting in-place modification
# str1[0] = 'J' # Raises TypeError: 'str' object does not support item
assignment
Performance Considerations
▪ Efficient Concatenation: Use the join() method for concatenating multiple
strings to avoid performance issues.
words = ["Efficient", "string", "concatenation"]
result = " ".join(words) # New string "Efficient string concatenation"
▪ Avoiding Repeated Concatenation: Repeated concatenation in loops is
inefficient due to the creation of multiple intermediate strings.
# Inefficient
result = ""
for word in words:
result += word # Each concatenation creates a new string
# Efficient
result = "".join(words)
Copy-on-Write Optimization
▪ Python optimizes memory usage by using the same memory location for
identical immutable objects, a concept known as interning.
str1 = "Hello"
str2 = "Hello"
is_same_object = str1 is str2 # True, both refer to the same memory
location
Immutability and Data Structures
▪ Tuple Containing Strings: Tuples are immutable, and thus, any string within a
tuple remains immutable.
tup = ("Hello", "World")
# tup[0] = "Hi" # Raises TypeError: 'tuple' object does not support item
assignment
Built-in String Methods and Functions
Python has a set of built-in methods that you can use on strings
capitalize()
1
Capitalizes first letter of string
center(width, fillchar)
2 Returns a space-padded string with the original string centered to a
total of width columns.
decode(encoding='UTF-8',errors='strict')
4 Decodes the string using the codec registered for encoding.
encoding defaults to the default string encoding.
encode(encoding='UTF-8',errors='strict')
5 Returns encoded string version of string; on error, default is to raise
a ValueError unless errors is given with 'ignore' or 'replace'.
expandtabs(tabsize=8)
7 Expands tabs in string to multiple spaces; defaults to 8 spaces per
tab if tabsize not provided.
isalnum()
10 Returns true if string has at least 1 character and all characters are
alphanumeric and false otherwise.
isalpha()
11 Returns true if string has at least 1 character and all characters are
alphabetic and false otherwise.
isdigit()
12
Returns true if string contains only digits and false otherwise.
islower()
13 Returns true if string has at least 1 cased character and all cased
characters are in lowercase and false otherwise.
isnumeric()
14 Returns true if a unicode string contains only numeric characters
and false otherwise.
isspace()
15 Returns true if string contains only whitespace characters and false
otherwise.
istitle()
16
Returns true if string is properly "titlecased" and false otherwise.
isupper()
17 Returns true if string has at least one cased character and all cased
characters are in uppercase and false otherwise.
join(seq)
18 Merges (concatenates) the string representations of elements in
sequence seq into a string, with separator string.
Sr.No Function & Description
len(string)
19
Returns the length of the string
ljust(width[, fillchar])
20 Returns a space-padded string with the original string left-justified
to a total of width columns.
lower()
21
Converts all uppercase letters in string to lowercase.
lstrip()
22
Removes all leading whitespace in string.
maketrans()
23
Returns a translation table to be used in translate function.
max(str)
24
Returns the max alphabetical character from the string str.
min(str)
25
Returns the min alphabetical character from the string str.
rfind(str, beg=0,end=len(string))
27
Same as find(), but search backwards in string.
rjust(width,[, fillchar])
29 Returns a space-padded string with the original string right-justified
to a total of width columns.
rstrip()
30
Removes all trailing whitespace of string.
split(str="", num=string.count(str))
31 Splits string according to delimiter str (space if not provided) and
returns list of substrings; split into at most num substrings if given.
splitlines( num=string.count('\n'))
32 Splits string at all (or num) NEWLINEs and returns a list of each line
with NEWLINEs removed.p>
Sr.No Function & Description
startswith(str, beg=0,end=len(string))
Determines if string or a substring of string (if starting index beg and
33
ending index end are given) starts with substring str; returns true if
so and false otherwise.
strip([chars])
34
Performs both lstrip() and rstrip() on string.
swapcase()
35
Inverts case for all letters in string.
title()
36 Returns "titlecased" version of string, that is, all words begin with
uppercase and the rest are lowercase.
translate(table, deletechars="")
37 Translates string according to translation table str(256 chars),
removing those in the del string.
upper()
38
Converts lowercase letters in string to uppercase.
zfill (width)
Returns original string leftpadded with zeros to a total of width
39
characters; intended for numbers, zfill() retains any sign given (less
one zero).
isdecimal()
40 Returns true if a unicode string contains only decimal characters
and false otherwise.
string comparison
String comparison is the process of comparing two strings. These two strings
act as operands or parameters that participate to check their differences. Mostly, the
comparison process uses the ASCII value or Unicode value to compare two strings.
There are three different programming approaches we can use to compare two
strings in Python.
Method 1: Using Relational Operator
Relational operators are mostly used to compare two constants. Since, it comes
under the category of binary operator, it helps in comparing strings in Python also.
After using a relational operator on both operands, it either returns True or False
depending on the condition. These type of operators in Python are also called
the comparison operators. There are 6 different types of comparison operators in
Python.
== (Equal
operator) Checks whether both operands are equal or not
Checks whether the left-hand side operand is greater
> (Greater than) than the right-hand side operand
>= (Greater than Checks whether the left-hand side operand is greater
or equals) than or equal to the right-hand side operand
<= (Less than or Checks whether the right-hand side operand is greater
equals) than or equals to the left-hand side operand
!= (Not equals) Checks whether both operands are not equal or not
Example:
print("Karlos" == "Karlos")
print("Karlos" < "karlos")
print("Karlos" > "karlos")
print("Karlos" != "Karlos")
Output:
True
True
False
False
Method 2: Using is and is not (Identity) operator
In Python, the == operator is used for comparing the values for both the
operands while checking for equality. But the Python's 'is' operator (which is an
identity operator) helps in checking whether both its operands are referring to the
same object or not. This also happens in the case of != and 'is not' operators of
Python.
Program:
val1 = "Karlos"
val2 = "Karlos"
val3 = val1
valn = "karlos"
Python Module
A Python module is a file containing Python definitions and statements. A
module can define functions, classes, and variables. A module can also include
runnable code.
Grouping related code into a module makes the code easier to understand and
use. It also makes the code logically organized.
Create a Python Module
To create a Python module, write the desired code and save that in a file
with .py extension. Let’s understand it better with an example:
Example:
Let’s create a simple calc.py in which we define two functions, one add and
another subtract.
# A simple module, calc.py
def add(x, y):
return (x+y)
Output:
12
Python Import From Module
Python’s from statement lets you import specific attributes from a module without
importing the module as a whole.
# importing sqrt() and factorial from the module math
from math import sqrt, factorial
# if we simply do "import math", then math.sqrt(16) and math.factorial()
are required.
print(sqrt(16))
print(factorial(6))
Output:
4.0
720
Built-in Modules
There are several built-in modules in Python, which you can import whenever you
like.
Example
Import and use the platform module:
import platform
x = platform.system()
print(x)
Output:
Windows
datetime: Provides classes for manipulating dates and times.
import datetime
now = datetime.datetime.now()
print(now) # Current date and time
Using the dir() Function
There is a built-in function to list all the function names (or variable names) in a
module. The dir() function:
Example
List all the defined names belonging to the platform module:
import platform
x = dir(platform)
print(x)
Output:
['_Processor', '_WIN32_CLIENT_RELEASES', '_WIN32_SERVER_RELEASES',
'__builtins__', '__cached__', '__copyright__', '__doc__', '__file__', '__loader__', '__name__',
'__package__', '__spec__', '__version__', '_comparable_version', '_default_architecture',
'_follow_symlinks', '_get_machine_win32', '_java_getprop', '_mac_ver_xml', '_node',
'_norm_version', '_os_release_cache', '_os_release_candidates', '_parse_os_release',
'_platform', '_platform_cache', '_sys_version', '_sys_version_cache', '_syscmd_file',
'_syscmd_ver', '_uname_cache', '_unknown_as_blank', '_ver_stages', '_win32_ver',
'_wmi', '_wmi_query', 'architecture', 'collections', 'freedesktop_os_release',
'functools', 'itertools', 'java_ver', 'libc_ver', 'mac_ver', 'machine', 'node', 'os',
'platform', 'processor', 'python_branch', 'python_build', 'python_compiler',
'python_implementation', 'python_revision', 'python_version',
'python_version_tuple', 're', 'release', 'sys', 'system', 'system_alias', 'uname',
'uname_result', 'version', 'win32_edition', 'win32_is_iot', 'win32_ver']
Namespaces
A namespace is a container that holds a set of identifiers (variable names) and
their corresponding objects. It helps in avoiding name conflicts and managing the
scope of variables.
❖ Built-in Namespace: Contains built-in functions and exceptions.
print(len("hello")) # 5
❖ Global Namespace: Contains global variables and functions defined in a
module.
x = 10 # Global variable
def func():
print(x) # Accesses global variable
❖ Local Namespace: Contains local variables defined inside a function.
x = 10 Output:
def func():
10
print(x)
func() # 10 10
print(x) # 10
❖ Local Scope: Variables declared inside a function have a local scope and can
only be accessed within that function.
❖ Enclosing Scope: Variables in the enclosing scope (in nested functions) can be
accessed using the nonlocal keyword.
x = 10 Output:
def func(): 20
global x
x = 20
func()
print(x) # 20