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

python unit ii

The document provides an overview of various Python comprehensions, including list, dictionary, set, and generator comprehensions, along with their syntax and examples. It also discusses Python functions, their declaration, types, arguments, and the concept of generators and decorators. Additionally, it explains namespaces and scope in Python, detailing the different types of namespaces and their lifetimes.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

python unit ii

The document provides an overview of various Python comprehensions, including list, dictionary, set, and generator comprehensions, along with their syntax and examples. It also discusses Python functions, their declaration, types, arguments, and the concept of generators and decorators. Additionally, it explains namespaces and scope in Python, detailing the different types of namespaces and their lifetimes.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

Comprehensions in Python provide us with a short and concise way to construct new

sequences (such as lists, sets, dictionaries, etc.) using previously defined


sequences. Python supports the following 4 types of comprehension:
 List Comprehensions
 Dictionary Comprehensions
 Set Comprehensions
 Generator Comprehensions
List Comprehensions
List Comprehensions provide an elegant way to create new lists. The following is the basic
structure of list comprehension:
Syntax: output_list = [output_exp for var in input_list if (var satisfies this
condition)]
input_list = [1, 2, 3, 4, 4, 5, 6, 7, 7]
output_list = []

for var in input_list:


if var % 2 == 0:
output_list.append(var)

print("Output List using for loop:", output_list)


Output:
Output List using for loop: [2, 4, 4, 6]
Dictionary Comprehensions
Extending the idea of list comprehensions, we can also create a dictionary using dictionary
comprehensions. The basic structure of a dictionary comprehension looks like below.
output_dict = {key:value for (key, value) in iterable if (key, value satisfy this
condition)}
Example 1: Generating odd number with their cube values without using dictionary
comprehension
Suppose we want to create an output dictionary which contains only the odd numbers that
are present in the input list as keys and their cubes as values. Let’s see how to do this
using for loops and dictionary comprehension.

 Python3

input_list = [1, 2, 3, 4, 5, 6, 7]

output_dict = {}

for var in input_list:


if var % 2 != 0:
output_dict[var] = var**3

print("Output Dictionary using for loop:",output_dict )

Output:
Output Dictionary using for loop: {1: 1, 3: 27, 5: 125, 7: 343}
Set Comprehensions
Set comprehensions are pretty similar to list comprehensions. The only difference between
them is that set comprehensions use curly brackets { }
Let’s look at the following example to understand set comprehensions.
Example 1 : Checking Even number Without using set comprehension
Suppose we want to create an output set which contains only the even numbers that are
present in the input list. Note that set will discard all the duplicate values. Let’s see how
we can do this using for loops and set comprehension.

 Python3

input_list = [1, 2, 3, 4, 4, 5, 6, 6, 6, 7, 7]

output_set = set()

for var in input_list:


if var % 2 == 0:
output_set.add(var)

print("Output Set using for loop:", output_set)

Output:
Output Set using for loop: {2, 4, 6}
Generator Comprehensions
Generator Comprehensions are very similar to list comprehensions. One difference
between them is that generator comprehensions use circular brackets whereas list
comprehensions use square brackets. The major difference between them is that
generators don’t allocate memory for the whole list. Instead, they generate each value one
by one which is why they are memory efficient. Let’s look at the following example to
understand generator comprehension:

 Python3

input_list = [1, 2, 3, 4, 4, 5, 6, 7, 7]

output_gen = (var for var in input_list if var % 2 == 0)


print("Output values using generator comprehensions:", end = ' ')

for var in output_gen:


print(var, end = ' ')

Output:
Output values using generator comprehensions: 2 4 4 6

2.2 Python Functions


Python Functions is a block of statements that return the specific task. The idea is to put
some commonly or repeatedly done tasks together and make a function so that instead of
writing the same code again and again for different inputs, we can do the function calls to
reuse code contained in it over and over again.
Some Benefits of Using Functions
 Increase Code Readability
 Increase Code Reusability
Python Function Declaration
The syntax to declare a function is:

Syntax of Python Function Declaration

Types of Functions in Python

Below are the different types of functions in Python:


 Built-in library function: These are Standard functions in Python that are available
to use.
 User-defined function: We can create our own functions based on our
requirements.
Creating a Function in Python
We can define a function in Python, using the def keyword. We can add any type of
functionalities and properties to it as we require. By the following example, we can
understand how to write a function in Python. In this way we can create Python function
definition by using def keyword.
Python
# A simple Python functiondef fun():
print("Welcome to GFG")

Calling a Function in Python


After creating a function in Python we can call it by using the name of the functions
Python followed by parenthesis containing parameters of that particular function. Below is
the example for calling def function Python.
Python
# A simple Python functiondef fun():
print("Welcome to GFG")

# Driver code to call a functionfun()


Output:
Welcome to GFG

Python Function with Parameters

If you have experience in C/C++ or Java then you must be thinking about the return
type of the function and data type of arguments. That is possible in Python as well
(specifically for Python 3.5 and above).
Python Function Syntax with Parameters
def function_name(parameter: data_type) -> return_type:
"""Docstring"""
# body of the function
return expression
The following example uses arguments and parameters that you will learn later in this
article so you can come back to it again if not understood.
Python
def add(num1: int, num2: int) -> int: """Add two numbers"""
num3 = num1 + num2

return num3
# Driver codenum1, num2 = 5, 15ans = add(num1, num2)print(f"The addition of {num1}
and {num2} results {ans}.")
Output:
The addition of 5 and 15 results 20.
Python Function Arguments
Arguments are the values passed inside the parenthesis of the function. A function can
have any number of arguments separated by a comma.
In this example, we will create a simple function in Python to check whether the number
passed as an argument to the function is even or odd.
Python
# A simple Python function to check# whether x is even or odddef evenOdd(x):
if (x % 2 == 0):
print("even")
else:
print("odd")

# Driver code to call the functionevenOdd(2)evenOdd(3)


Output:
even
odd

Types of Python Function Arguments

Python supports various types of arguments that can be passed at the time of the function
call. In Python, we have the following function argument types in Python:
 Default argument
 Keyword arguments (named arguments)
 Positional arguments
 Arbitrary arguments (variable-length arguments *args and **kwargs)
Let’s discuss each type in detail.

Default Arguments

A default argument is a parameter that assumes a default value if a value is not provided
in the function call for that argument. The following example illustrates Default arguments
to write functions in Python.
Python
# Python program to demonstrate# default argumentsdef myFun(x, y=50):
print("x: ", x)
print("y: ", y)

# Driver code (We call myFun() with only# argument)myFun(10)


Output:
x: 10
y: 50
Like C++ default arguments, any number of arguments in a function can have a default
value. But once we have a default argument, all the arguments to its right must also have
default values.

Generators in Python
A Generator in Python is a function that returns an iterator using the Yield keyword. In this
article, we will discuss how the generator function works in Python.
Generator Function in Python
A generator function in Python is defined like a normal function, but whenever it needs to
generate a value, it does so with the yield keyword rather than return. If the body of a def
contains yield, the function automatically becomes a Python generator function.

Create a Generator in Python

In Python, we can create a generator function by simply using the def keyword and the yield
keyword. The generator has the following syntax in Python:
def function_name():
yield statement
Example:
In this example, we will create a simple generator that will yield three integers. Then we
will print these integers by using Python for loop.
Python
# A generator function that yields 1 for first time,# 2 second time and 3 third timedef
simpleGeneratorFun():
yield 1
yield 2
yield 3
# Driver code to check above generator functionfor value in simpleGeneratorFun():
print(value)
Output:
1
2
3
Generator Object
Python Generator functions return a generator object that is iterable, i.e., can be used as
an Iterator. Generator objects are used either by calling the next method of the generator
object or using the generator object in a “for in” loop.
Example:
In this example, we will create a simple generator function in Python to generate objects
using the next() function.
Python
# A Python program to demonstrate use of # generator object with next()
# A generator functiondef simpleGeneratorFun():
yield 1
yield 2
yield 3
# x is a generator objectx = simpleGeneratorFun()
# Iterating over the generator object using next
# In Python 3, __next__()print(next(x))print(next(x))print(next(x))
Output:
1
2
3

Generator Expression Syntax

The generator expression in Python has the following Syntax:


(expression for item in iterable)
Example:
In this example, we will create a generator object that will print the multiples of 5 between
the range of 0 to 5 which are also divisible by 2.
Python
# generator expressiongenerator_exp = (i * 5 for i in range(5) if i%2==0)
for i in generator_exp:
print(i)

Decorators in Python
Decorators are a very powerful and useful tool in Python since it allows programmers to
modify the behaviour of a function or class. Decorators allow us to wrap another function in
order to extend the behaviour of the wrapped function, without permanently modifying it.
But before diving deep into decorators let us understand some concepts that will come in
handy in learning the decorators.

First Class Objects


In Python, functions are first class objects which means that functions in Python can
be used or passed as arguments.
Properties of first class functions:

 A function is an instance of the Object type.


 You can store the function in a variable.
 You can pass the function as a parameter to another function.
 You can return the function from a function.
 You can store them in data structures such as hash tables, lists, …
Consider the below examples for better understanding.
Example 1: Treating the functions as objects.
Python3
# Python program to illustrate functions # can be treated as objects def shout(text):
return text.upper()
print(shout('Hello'))
yell = shout
print(yell('Hello'))
Output:
HELLO
HELLO
Decorators
As stated above the decorators are used to modify the behaviour of function or class. In
Decorators, functions are taken as the argument into another function and then called
inside the wrapper function.
Syntax for Decorator:
@gfg_decorator
def hello_decorator():
print("Gfg")

'''Above code is equivalent to -

def hello_decorator():
print("Gfg")

hello_decorator = gfg_decorator(hello_decorator)'''

2.4 Namespace & Scope

What is Namespace?

In Python, a way to give each object a unique name is through a namespace. Variables and
methods are examples of objects in Python. To put it another way, it is a collection of the
known symbolic names and the details about the thing that each name refers to. A name can
be thought of as a key in a dictionary, and objects are the values in a namespace. We should
figure out it with a genuine model - A namespace resembles a last name. If there are
multiple "Peter" names in the class, it may be difficult to locate a "Peter" name; however,
when we specifically request "Peter Warner" or "Peter Cummins," In a class, it might not be
common for multiple students to have the same first and last name.

The Python interpreter can get a better understanding of the exact method or variable in the
code thanks to the namespace. As a result, its name contains additional information,
including Space (related to scope) and Name, which denotes a unique identifier.

In Python, there are four types of namespaces which are given below.

o Built-in
o Global
o Enclosing
o Local
As these namespace various have lifetimes, Python interpreter creates namespaces as
necessary and deletes them when they are no longer needed.

Let's understand the various types of namespace in Python.

The Built-in Namespace

As its name suggests, it contains pre-defined names of all of Python's built-in objects already
available in Python. Let's list these names with the following command.

Open the Python terminal and type the following command.

Command -

dir(__builtins__)
Output:

['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError',


'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError',
'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError',
'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError',
'Exception', 'False', 'FileExistsError'
The Global Namespace

The global namespace consists of any names in Python at any level of the main program. It
is created when the main body executes and remains in existence until the interpreter
terminates.

The Python interpreter creates a global namespace for any module that our Python loads
with the import statement. To get more information, visit our Python Module.

The Local and Enclosing Namespaces

The local namespaces are used by the function; When the function is run, the Python
interpreter creates a new namespace. The local namespaces continue to exist after the
function has finished running. The capability can likewise comprise of another capability. As
shown below, we can define one function within another.

Example -

def f():
print('Initiate f()')

def g():
print('Initiate g()')
print('End g()')
return

g()

print('Initiate f()')
return
f()
In the above model, the capability g() is characterized inside the collection of f(). We called
the g() function within the f() and the main f() function. Let's look at how the above
function works:

o Python creates a new namespace for f() when we call it.


o Likewise, the f() calls g(), g() gets its own different namespace.
o The local namespace g() was created for the enclosing namespace, f().
Each of these namespaces is terminated when the function is terminated.

cope of the Object/Variable

The term "scope" specifies which coding region of a particular Python object can be accessed.
Every object and variable has a scope in the program from which we can access that variable.
For instance, a function variable can only be accessed within the function. Let's examine the
following illustration:

Example -

def scope_func():
print("Inside scope_func")
def scope_inner_func():
var = 20
print("Inside inner function, value of var:",var)
scope_inner_func()
print("Try printing var from outer function: ",var)
scope_func()
Output:

Inside scope_func
Inside inner function, value of var: 20
Traceback (most recent call last):
File "d:/Python Project/listproblems.py", line 343, in
scope_func()
File "d:/Python Project/listproblems.py", line 342, in scope_func
print("Try printing var from outer function: ",var)
NameError: name 'var' is not defined

Python Namespace Dictionaries

In the previous tutorial, we talked about how namespaces are like dictionaries, with keys
representing object names and values representing actual objects. As dictionaries, Python
uses both global and local namespaces. Access to global and local namespace dictionaries is
made possible by Python's globals() and locals() methods.

The globals() Method

The globals() method returns a reference to the current global namespace dictionary. We
can use it to access the objects in the global namespace. Let's see the below example.

Example -
>>> type(globals())
<class 'dict'>
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <cl
ass '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__
': <module 'builtins' (built-in)>}

Changing Variables Out of Scope

In the calling environment, the function can change the argument by passing a different
value, but sometimes it can't change the value.

An immutable argument cannot be modified by a function.

A mutable argument can be changed in place, but it cannot be completely redefined.

Let's understand the following scenario.

Example -

. x = 20
. def func():
. x = 40
. print(x)
.
. func()
.
. print(x)
Output:

40
20

You might also like