Python Unit2
Python Unit2
Python Arrays
An array is a collection of items stored at contiguous memory locations. The idea is to store multiple
items of the same type together. This makes it easier to calculate the position of each element by
simply adding an offset to a base value, i.e., the memory location of the first element of the array
(generally denoted by the name of the array).
Array can be handled in Python by a module named array. They can be useful when we have to
manipulate only a specific data type values. A user can treat lists as arrays. However, user cannot
constraint the type of elements stored in a list. If you create arrays using the array module, all elements
of the array must be of the same type.
array(data_type, value_list) is used to create an array with data type and value list specified in its
arguments.
Some of the data types are mentioned below which will help in creating an array of different data
types.
PYHTON PROGRAMMING
# Creation of Array
print ("The new created array is : ", end =" ") for
i in range (0, 3):
Output :
The new created array is : 1 2 3
output
First element: 2
Second element: 4
Last element: 8
Python List
A list is a mutable and ordered collection i.e., elements of the list can be changed and it maintains
the order of insertion of its items. Because of the property of order maintaining, each element of the
list has a fixed index and it permits the list to have duplicate elements. In Python, list is very useful as
it has the ability to contain non-homogeneous elements.
Python Array
Python arrays are also a collection but its items are stored at contiguous memory locations. It can
store only homogeneous elements(elements of the same data type). Arrays are very beneficial in
performing mathematical operations on the elements. Unlike lists, arrays can not be declared
directly. To create an array the array module must be imported and the syntax of the declaration is
different from that of the list.
PYHTON PROGRAMMING
Looping an array
for i in (a):
print (i, end ="
") print()
output
123
Adding Elements to a Array
Elements can be added to the Array by using built-in insert() function. Insert is used to insert one or
more data elements into an array. Based on the requirement, a new element can be added at the
beginning, end, or any given index of array. append() is also used to add the value mentioned in its
arguments at the end of the array.
# inserting array
using # insert()
function a.insert(1,
4)
PYHTON PROGRAMMING
Output :
Array before insertion : 1 2 3
Output :
Access element is: 1
Note – Remove method in List will only remove the first occurrence of the searched element.
print ("\r")
print("\r")
Output:
The new created array is : 1 2 3 1 5
Slicing of a Array
In Python array, there are multiple ways to print the whole array with all the elements, but to print a
specific range of elements from the array, we use Slice operation. Slice operation is performed on
array with the use of colon(:). To print elements from beginning to a range use [:Index], to print
elements from end use [:-Index], to print elements from specific Index till the end use [Index:], to
PYHTON PROGRAMMING
print elements within a range, use [Start Index:End Index] and to print whole List with the use of
slicing operation, use [:]. Further, to print whole array in reverse order, use [::-1].
a = arr.array('i', l)
print("Initial Array: ")
for i in (a):
print(Sliced_array)
Output
Initial Array:
PYHTON PROGRAMMING
1 2 3 4 5 6 7 8 9 10
print ("\r")
Output:
output
array('i', [10, 20, 30])
array('i', [10, 20, 30, 50])
Python Functions
A function is a block of organized, reusable code that is used to perform a single, related action.
Functions provide better modularity for your application and a high degree of code reusing.
Python gives you many built-in functions like print(), etc. but you can also create your own functions.
These functions are called user-defined functions.
Defining a Function
• Any input parameters or arguments should be placed within these parentheses. You can also
define parameters inside these parentheses.
• The first statement of a function can be an optional statement - the documentation string of
the function or docstring.
• The code block within every function starts with a colon (:) and is indented.
PYHTON PROGRAMMING
• The statement return [expression] exits a function, optionally passing back an expression to
the caller. A return statement with no arguments is the same as return None.
Syntax
Example
The following function takes a string as input parameter and prints it on standard screen.
Defining a function only gives it a name, specifies the parameters that are to be included in the
function and structures the blocks of code.
Once the basic structure of a function is finalized, you can execute it by calling it from another
function or directly from the Python prompt.
output
Pass by reference
All parameters (arguments) in the Python language are passed by reference. It means if you change
what a parameter refers to within a function, the change also reflects back in the calling function. For
example −
There is one more example where argument is being passed by reference and the reference is being
overwritten inside the called function.
Example-3
a=[10,20,
30]
print(a)
def
sum(x):
PYHTON PROGRAMMING
x.append('bca')
print(x)
sum(a)
print(a)
Function Arguments
You can call a function by using the following types of formal arguments −
describe_pet('hamster', 'harry')
output
I have a hamster.
Example-2
To call the function printme(), you definitely need to pass one argument, otherwise it gives a syntax
error as follows −
printme();
Keyword arguments
A keyword argument is a name-value pair that you pass to a function. You directly associate the
name and the value within the argument, so when you pass the argument to the function, there’s no
confusion (you won’t end up with a harry named Hamster). Keyword arguments free you from
having to worry about correctly ordering your arguments in the function call, and they clarify the
role of each value in the function call.
The function describe_pet() hasn’t changed. But when we call the function, we explicitly tell Python
which parameter each argument should be matched with. When Python reads the function call, it
knows to store the argument 'hamster' in the parameter animal_type and the argument 'harry' in
pet_name.
The order of keyword arguments doesn’t matter because Python knows where each value
should go. The following two function calls are equivalent:
describe_pet(animal_type='hamster', pet_name='harry') describe_pet(pet_name='harry',
animal_type='hamster')
Note: When you use keyword arguments, be sure to use the exact names of the parameters in
Example-2
The following example gives more clear picture. Note that the order of parameters does not matter.
Name: miki
Age 50
Default arguments
A default argument is an argument that assumes a default value if a value is not provided in the
function call for that argument. The following example gives an idea on default arguments, it prints
default age if it is not passed −
Name: miki
Age 50
Name: miki
Age 35
Note: When you use default values, any parameter with a default value needs to be listed after all
the parameters that don’t have default values. This allows Python to continue interpreting
positional arguments correctly.
Sometimes you won’t know ahead of time how many arguments a function needs to accept.
Fortunately, Python allows a function to collect an arbitrary number of arguments from the calling
statement.
PYHTON PROGRAMMING
You may need to process a function for more arguments than you specified while defining the
function. These arguments are called variable-length arguments and are not named in the function
definition, unlike required and default arguments.
Syntax for a function with non-keyword variable arguments is this − def
functionname([formal_args,] *var_args_tuple ):
"function_docstring"
function_statements return [expression]
An asterisk (*) is placed before the variable name that holds the values of all non keyword variable
arguments. This tuple remains empty if no additional arguments are specified during the function
call. This syntax works no matter how many arguments the function receives.
Example-1
def make_pizza(*toppings):
"""Print the list of toppings that have been requested."""
print(toppings)
make_pizza('xyz')
make_pizza('aaa', 'bbb', 'ccc')
Output is:
10
Output is:
70
60
50
PYHTON PROGRAMMING
This way the function will receive a dictionary of arguments, and can access the items accordingly:
Example
If the number of keyword arguments is unknown, add a double ** before the parameter name:
def my_function(**kid):
Example-2
Python functions can return single as well as multiple values. To return multiple values, you can
return either a dictionary, a Python tuple, or a list to your main program.
The statement return [expression] exits a function, optionally passing back an expression to the
caller. A return statement with no arguments is the same as return None.
All the above examples are not returning any value. You can return a value from a function as
follows −
Using Tuple:
# A Python program to return multiple
x = 20
# aa=(str,x)
#return aa
Output:
palanpur
20
Using a list: A list is like an array of items created using square brackets. They are different from
arrays as they can contain items of different types. Lists are different from tuples as they are
mutable.
list = fun()
print(list)
Output:
['palanpur', 20]
d['x'] = 20
return d
d = fun()
print(d)
Output:
A lambda function can take any number of arguments, but can only have one expression.
These functions are called anonymous because they are not declared in the standard manner by using
the def keyword. You can use the lambda keyword to create small anonymous functions.
• Lambda forms can take any number of arguments but return just one value in the form of an
expression. They cannot contain commands or multiple expressions.
Syntax
PYHTON PROGRAMMING
The syntax of lambda functions contains only a single statement, which is as follows − lambda
[arg1 [,arg2,.....argn]]:expression
Example-1
Add 10 to argument a, and return the result:
x = lambda a : a + 10
print(x(5))
output 15
Example-2
Value of total : 30
Value of total : 40
Recursion is a programming technique where a function calls itself either directly or indirectly to
solve a problem by breaking it into smaller, simpler subproblems.
In Python, recursion is especially useful for problems that can be divided into identical smaller tasks,
such as mathematical calculations, tree traversals or divide-and-conquer algorithms.
Working of Recursion
A recursive function is just like any other Python function except that it calls itself in its body. Let's
see basic structure of recursive function:
def recursive_function(parameters):
if base_case_condition:
return base_result
else:
return recursive_function(modified_parameters)
def factorial(n):
if n == 0: # Base case
return 1
else: # Recursive case
return n * factorial(n - 1)
print(factorial(5))
OUTPUT : 120
Explanation:
Base Case: When n == 0, recursion stops and returns 1.
Recursive Case: Multiplies n with the factorial of n-1 until it reaches the base case.
print(fibonacci(10))
OUTPUT : 55
Explanation:
Base Cases: If n == 0, the function returns 0. If n == 1, the function returns 1. These two cases
are necessary to stop the recursion.
Recursive Case: function calls itself twice with decrements of n (i.e., fibonacci(n-1) and
fibonacci(n-2)), summing results of these calls.
PYHTON PROGRAMMING
Scope of Variables
All variables in a program may not be accessible at all locations in that program. This depends on
where you have declared a variable.
The scope of a variable determines the portion of the program where you can access a particular
identifier. There are two basic scopes of variables in Python −
• Global variables
• Local variables
Variables that are defined inside a function body have a local scope, and those defined outside have
a global scope.
This means that local variables can be accessed only inside the function in which they are declared,
whereas global variables can be accessed throughout the program body by all functions. When you
call a function, the variables declared inside it are brought into scope. Following is a simple example
–
You can send any data types of argument to a function (string, number, list, dictionary etc.), and it
will be treated as the same data type inside the function.
E.g. if you send a List as an argument, it will still be a List when it reaches the function:
PYHTON PROGRAMMING
def my_function(food):
for x in food:
print(x)
my_function(fruits)
Function Description
range() Returns a sequence of numbers, starting from 0 and increments by 1 (by default)
round() Rounds a numbers
set() Returns a new set object
super() Returns an object that represents the parent class
tuple() Returns a tuple
type() Returns the type of an object
Python Modules
What is a Module?
Consider a module to be the same as a code library.
Create a Module
To create a module just save the code you want in a file with the file extension .py:
Example
PYHTON PROGRAMMING
Use a Module
Now we can use the module we just created, by using the import statement:
Example
Import the module named mymodule, and call the greeting function:
import mymodule
mymodule.greeting("Jonathan")
Now we’ll make a separate file called making_pizzas.py in the same directory as pizza.py. This file
imports the module we just created and then makes two calls to make_pizza():
PYHTON PROGRAMMING
import pizza
pizza.make_pizza(16, 'pepperoni')
Output
- pepperoni
Making a 12-inch pizza with the following toppings:
- mushrooms
- green peppers
- extra cheese
This first approach to importing, in which you simply write import followed by the name of the
module, makes every function from the module available in your program. If you use this kind of
import statement to import an entire module named module_name.py, each function in the module
is available through the following syntax:
syntax
module_name.function_name()
You can import as many functions as you want from a module by separating each function’s name
with a comma:
The making_pizzas.py example would look like this if we want to import just the function we’re
going to use:
With this syntax, you don’t need to use the dot notation when you call a function. Because we’ve
explicitly imported the function make_pizza() in the import statement, we can call it by name when
we use the function.
You’ll give the function this special nickname when you import the function.
Here we give the function make_pizza() an alias, mp(), by importing make_pizza as mp. The as
keyword renames a function using the alias you provide:
mp(16, 'pepperoni')
The import statement shown here renames the function make_pizza() to mp() in this program. Any
time we want to call make_pizza() we can simply write mp() instead, and Python will run the code in
make_pizza() while avoiding any confusion with another make_pizza() function you might have
written in this program file.
p.make_pizza(16, 'pepperoni')
• The module pizza is given the alias p in the import statement, but all of the module’s
functions retain their original names. Calling the functions by writing p.make_pizza() is not
only more concise than writing pizza.make_pizza(),but also redirects your attention from the
module name and allows you to focus on the descriptive names of its
PYHTON PROGRAMMING
functions. These function names, which clearly tell you what each function does, are more
important to the readability of your code than using the full module name.
The asterisk in the import statement tells Python to copy every function from the module pizza into
this program file.
Variables in Module
The module can contain functions, as already described, but also variables of all types (arrays,
dictionaries, objects etc):
Example
The module named mymodule has one function and one dictionary:
def greeting(name):
print("Hello, " + name)
person1 = {
"name": "John",
"age": 36,
"country": "Norway"
}
Example
Import only the person1 dictionary from the module:
from mymodule import person1
print (person1["age"])
PYHTON PROGRAMMING
Packages
Python packages are a way to organize and structure code by grouping related modules into
directories. A package is essentially a folder that contains an __init__.py file and one or more Python
files (modules). This organization helps manage and reuse code effectively, especially in larger
projects. It also allows functionality to be easily shared and distributed across different applications.
Packages act like toolboxes, storing and organizing tools (functions and classes) for efficient access
and reuse.
Key Components of a Python Package
Module: A single Python file containing reusable code (e.g., math.py).
Package: A directory containing modules and a special __init__.py file.
Sub-Packages: Packages nested within other packages for deeper organization.
Example :
In this example, we are creating a Math Operation Package to organize Python code into a
structured package with two sub-packages: basic (for addition and subtraction) and advanced (for
multiplication and division). Each operation is implemented in separate modules, allowing for
modular, reusable and maintainable code.
math_operations/__init__.py:
This __init__.py file initializes the main package by importing and exposing the calculate function
and operations (add, subtract, multiply, divide) from the respective sub-packages for easier
access.
math_operations/calculator.py:
This calculate file is a simple placeholder that prints "Performing calculation...", serving as a basic
demonstration or utility within the package.
def calculate():
PYHTON PROGRAMMING
print("Performing calculation...")
math_operations/basic/__init__.py:
This __init__.py file initializes the basic sub-package by importing and exposing the add and
subtract functions from their respective modules (add.py and sub.py). This makes these functions
accessible when the basic sub-package is imported.
# Export functions from the basic sub-package
math_operations/basic/add.py:
return a + b
math_operations/basic/sub.py:
return a – b
In the same way we can create the sub package advanced with multiply and divide modules. Now,
let's take an example of importing the module into a code and using the function:
calculate()
Output:
6
8
PYHTON PROGRAMMING
Python Packages
Suppose you have developed a very large application that includes many modules. As the number of
modules grows, it becomes difficult to keep track of them all if they are dumped into one location.
This is particularly so if they have similar names or functionality. You might wish for a means of
grouping and organizing them.
Packages allow for a hierarchical structuring of the module namespace using dot notation. In the
same way that modules help avoid collisions between global variable names, packages help avoid
collisions between module names.
Creating a package is quite straightforward, since it makes use of the operating system’s inherent
hierarchical file structure. Consider the following arrangement:
Here, there is a directory named pkg that contains two modules, mod1.py and mod2.py. The
contents of the modules are:
mod1.py
PYHTON PROGRAMMING
def foo():
print('[mod1] foo()')
class Foo:
pass
mod2.py
def bar():
print('[mod2] bar()')
class Bar:
pass
Given this structure, if the pkg directory resides in a location where it can be found (in one of the
directories contained in sys.path), you can refer to the two modules with dot
notation (pkg.mod1, pkg.mod2) and import them with the syntax you are already familiar with:
>>> pkg.mod1
Traceback (most recent call last):
File "<pyshell#34>", line 1, in <module>
pkg.mod1
AttributeError: module 'pkg' has no attribute 'mod1'
>>> pkg.mod1.foo()
Traceback (most recent call last):
File "<pyshell#35>", line 1, in <module>
pkg.mod1.foo()
AttributeError: module 'pkg' has no attribute 'mod1'
>>> pkg.mod2.Bar()
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
pkg.mod2.Bar()
AttributeError: module 'pkg' has no attribute 'mod2'
To actually import the modules or their contents, you need to use one of the forms shown above.
Package Initialization
If a file named __init__.py is present in a package directory, it is invoked when the package or a
module in the package is imported. This can be used for execution of package initialization code,
such as initialization of package-level data.
__init__.py
Let’s add this file to the pkg directory from the above example:
mod1.py
def foo():
from pkg import A
print('[mod1] foo() / A = ', A)
class Foo:
pass
>>> from pkg import mod1
Invoking __init__.py for pkg
>>> mod1.foo()
[mod1] foo() / A = ['quux', 'corge', 'grault']
__init__.py can also be used to effect automatic importing of modules from a package. For example,
earlier you saw that the statement import pkg only places the name pkg in the caller’s local symbol
table and doesn’t import any modules. But if __init__.py in the pkg directory contains the following:
__init__.py
>>> pkg.mod1.foo()
[mod1] foo()
>>> pkg.mod2.bar()
[mod2] bar()
Note: Much of the Python documentation states that an __init__.py file must be present in the
package directory when creating a package. This was once true. It used to be that the very presence
of __init__.py signified to Python that a package was being defined. The file could contain
initialization code or even be empty, but it had to be present.
Starting with Python 3.3, Implicit Namespace Packages were introduced. These allow for the
creation of a package without any __init__.py file. Of course, it can still be present if package
initialization is needed. But it is no longer required. Check out What’s a Python Namespace Package,
and What’s It For? to learn more.
Importing * From a Package
For the purposes of the following discussion, the previously defined package is expanded to contain
some additional modules:
There are now four modules defined in the pkg directory. Their contents are as shown below:
mod1.py
def foo():
print('[mod1] foo()')
class Foo:
pass
mod2.py
def bar():
print('[mod2] bar()')
class Bar:
PYHTON PROGRAMMING
pass
mod3.py
def baz():
print('[mod3] baz()')
class Baz:
pass
mod4.py
def qux():
print('[mod4] qux()')
class Qux:
pass
(Imaginative, aren’t they?)
You have already seen that when import * is used for a module, all objects from the module are
imported into the local symbol table, except those whose names begin with an underscore, as
always:
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',
'__package__', '__spec__']
>>> dir()
['Baz', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',
'__package__', '__spec__', 'baz']
>>> baz()
[mod3] baz()
>>> Baz
<class 'pkg.mod3.Baz'>
The analogous statement for a package is this:
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',
'__package__', '__spec__']
PYHTON PROGRAMMING
Instead, Python follows this convention: if the __init__.py file in the package directory contains
a list named __all__, it is taken to be a list of modules that should be imported when the
statement from <package_name> import * is encountered.
For the present example, suppose you create an __init__.py in the pkg directory like this:
pkg/__init__.py
__all__ = [
'mod1',
'mod2',
'mod3',
'mod4'
]
Now from pkg import * imports all four modules:
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',
'__package__', '__spec__']
By the way, __all__ can be defined in a module as well and serves the same purpose: to control
what is imported with import *. For example, modify mod1.py as follows:
pkg/mod1.py
__all__ = ['foo']
def foo():
print('[mod1] foo()')
class Foo:
pass
Now an import * statement from pkg.mod1 will only import what is contained in __all__:
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',
'__package__', '__spec__']
>>> foo()
[mod1] foo()
>>> Foo
Traceback (most recent call last):
File "<pyshell#37>", line 1, in <module>
Foo
NameError: name 'Foo' is not defined
foo() (the function) is now defined in the local namespace, but Foo (the class) is not, because the
latter is not in __all__.
In summary, __all__ is used by both packages and modules to control what is imported when import
* is specified. But the default behavior differs:
For a package, when __all__ is not defined, import * does not import anything.
For a module, when __all__ is not defined, import * imports everything (except—you
guessed it—names starting with an underscore).
PYHTON PROGRAMMING
Subpackages
Packages can contain nested subpackages to arbitrary depth. For example, let’s make one more
modification to the example package directory as follows:
The four modules (mod1.py, mod2.py, mod3.py and mod4.py) are defined as previously. But now,
instead of being lumped together into the pkg directory, they are split out into
two subpackage directories, sub_pkg1 and sub_pkg2.
Importing still works the same as shown previously. Syntax is similar, but additional dot notation is
used to separate package name from subpackage name:
In addition, a module in one subpackage can reference objects in a sibling subpackage (in the event
that the sibling contains some functionality that you need). For example, suppose you want to
import and execute function foo() (defined in module mod1) from within module mod3. You can
either use an absolute import:
pkg/sub__pkg2/mod3.py
def baz():
print('[mod3] baz()')
class Baz:
pass
pkg/sub__pkg2/mod3.py
def baz():
print('[mod3] baz()')
class Baz:
pass
Conclusion