100% found this document useful (1 vote)
210 views37 pages

Python Material Part1

This document provides an introduction to Python fundamentals including data types, expressions, variables, functions, and control statements. It explains that Python is an easy-to-learn yet powerful programming language mainly used for data science tasks. It presents sample code to print text, calculate values, take user input, and define basic functions.

Uploaded by

Manish Arvind
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
Download as docx, pdf, or txt
100% found this document useful (1 vote)
210 views37 pages

Python Material Part1

This document provides an introduction to Python fundamentals including data types, expressions, variables, functions, and control statements. It explains that Python is an easy-to-learn yet powerful programming language mainly used for data science tasks. It presents sample code to print text, calculate values, take user input, and define basic functions.

Uploaded by

Manish Arvind
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1/ 37

PYTHON

Chapter-1: Python Fundamentals

1.1 Introduction
The word Python - isn’t it scary? Doesn’t it bring the image of a big snake found in the
Amazon forest? Well, it is time to change this image. Now on, you will remember Python as
a free-to-use open-source programming language that is great for performing Data Science
tasks. Python, the programming language, was named after the famous BBC Comedy Show
Monty Python’s Flying Circus. It is an easy-to-learn yet powerful object-oriented
programming language that is mainly used now for analyzing data.
1.2 First Program in Python
Let us now try our first Program in Python. A Statement is an instruction that the
computer will execute. Perhaps the simplest Python Program that you can write is the one
that contains a single print statement, as shown below:
> print (“Hello, Python!”)
When the computer executes the above print statement, it will simply display the value you
write within the parentheses (i.e. “Hello, Python!”). The value you write in the parentheses is
called the argument. If you are using a Jupiter Notebook, you will see a small rectangle
with the above print statement. This is called a cell. If you select this cell with your Mouse
and then click the “Run All” button, the computer will execute the print statement and
display the output (i.e. Hello, Python!) beneath the cell, as shown below:
print (“Hello, Python!”)
Hello, Python!

1.3 Data Types in Python


The integers like 11, real numbers like 21.62 and the strings like “Python” are known
as literals in Python. They are represented by the data types int, float and str respectively.
Apart from these widely used data types, some other data types are also available in Python,
as shown in the following diagram. We will learn about all of them later.
Data Types in Python

Numbers Sequences Mappings None


(No values)

Integer Floating Complex String List Tuple Dictionary


Point Number
Boolean
2

Data Type Examples


Integer 29, 38000
Floating Point 21.62, 3.14
Complex Number 2.9 + 3.8j, 4.7 + 5.6j
Boolean True, False
String “Hello Python”, “Data Science”
List [2, 10, 29, 38, 56], [“Neha”, 83, 65, 70.4]
Tuple (2, 92, 47, 65, 47), (8, 7.4, 9, “ABC”)
Dictionary {“a” : 1, “e” : 2, “i” : 3, “0” : 4, “u” : 5}
None It is used to indicate the absence of value. It is also used to indicate the
end of a List. The “None” value in Python means “There is nothing
else.”

Using the type( ) function, we can find the data type of a value. For example, type (29)
will return int, while type (3.14) will return float. If a string contains an integer value, we
can convert it to int. This is known as type casting. For example, int (“38”) will return 38,
while int (True) will return 1. On the other hand, bool (1) will return True. The data types,
List, Tuple and Dictionary are known as sequence data types.
1.4 Expressions
A simple example for an expression is 33+60–10. Here, we call the numbers 33, 60 and
10 as operands and the Maths symbols + and – as operators. The value of this expression is
83. We can perform the multiplication operation by using the asterisk symbol, and the
division operation by using the forward slash symbol, as shown below:
5*5 25/5
The values of the above expressions will be evaluated as 25 and 5.0, respectively.
We can use double slash for integer division, in which case the result will be rounded.
Python follows mathematical conventions when evaluating a mathematical expression. The
arithmetic operators in the following two expressions are in different order. But, in both the
cases, Python performs multiplication first and then the addition to obtain the final result:
120 120
2 * 60 + 30 30 + 2 * 60
150 150
The expressions in the parentheses are performed first in the following example. We
then multiply the result by 60. The final result is 1920.
32
(30 + 2) * 60
3

1920

1.5 Variable
We can use variables to store values. In the following example, we assign the value
10000 to the variable principal by using the assignment operator (i.e. the equals sign). We
can then use the value somewhere else in the code by typing the exact name of the variable.
principal = 10000
years =3
interest_rate = 10
simple_interest = (principal * years * interest_rate) / 100
print(simple_interest)

3000
Recall that we can find the data type of a value by using the type( ) function. For
example, type(29) will return int. We can apply the type( ) function on a variable also. For
example, type(principal) will return int.
1.6 Method of providing the input through the keyboard
In the above Program, input values are provided as part of the Program. But, often, the
input values are received from the User through the keyboard. The input( ) function shall be
used for this purpose.
name = input (“What is your name?”)
When the above statement is executed, the prompt will be displayed as a vertical line, as
shown below:
What is your name? |
We have to type the name in front of the above prompt (|), as shown below:
What is your name? Ganesh
Now, “Ganesh” will be assigned as the value of the variable name.
We have just now seen the method of reading in a string. Even if we provide a
number as the input, the input( ) function will return the entered value as a string. So, what
should we do if we have to read in an integer or a fractional value? What is the way out? We
have to use the int( ) and float( ) functions, as shown below:
age = int(input (“what is your age?”))
percentage = float(input (“Enter your percentage of marks:”)

1.7 Program to calculate Mean


4

The following Program will read in the marks obtained by a student in three different
subjects and then calculate the average mark.

# Program to calculate the Average


mark1 = int(input (“Enter the first mark:”))
mark2 = int(input (“Enter the second mark:”))
mark3 = int(input (“Enter the third mark:”))
average = (mark1 + mark2 + mark3)/3
print (“Average Mark is: “, average)
We will see the following entries on the Screen when we execute the above Program.
Enter the first mark : 90
Enter the second mark : 70
Enter the third mark : 80
Average mark is : 80

1.8 Control statements in Python


The if statement, the for statement and the while statement are the important Control
Statements that are available in Python. The simple form of the if statement tests a condition
and if the condition evaluates to true, it carries out one set of instructions. Otherwise, it
carries out another set of instructions. Example:
import statistics
marks = [10, 20, 60]
option = int(input(“Enter 1 to calculate Mean, 2 to calculate Median:”))
if option == 1
average = statistics.mean (marks)
else
average = statistics.median (marks)
print (average)
Here, when the value of option is 1, the output will be 30. Otherwise, the output will be 20.
The for statement is used to repeatedly execute a set of statements for a certain number of
times. Here is an example.
for a in [1, 3, 5]
print(a)
print(a * a)
Here, the two print statements will be repeatedly executed three times. Here, a will take the
values 1, 3 and 5, one by one. So, the output will be as follows:
1
1
5

3
9
5
25
The while statement is used to repeatedly execute a set of statements as long as a condition
remains true. Here is an example:
n=1
while n < = 3
print (n*n)
n = n+1
Here, n will take the values 1, 2 and 3. So, the output will be as follows:
1
4
9
Note:
Many programming languages use curly braces to delimit blocks of code. But Python
uses indentation, as shown below:

for i in [ 1, 2, 3, 4, 5 ] :
print i
for j in [ 1, 2, 3, 4, 5 ] :
print j
print ( i + j )
print i
print (“looping is over”)

1.9 User-defined Functions


When a Code Segment is to be reused (i.e., executed again and again), it shall be
defined as a function. Every function has a name and it is defined by using the def statement.
The statements indented below the def statement form the body of the function.
def mult (a, b) :
c=a*b
return c

mult (20, 10) # Invoking the mult( ) function. Output will be 200.
The syntax of the user-defined function is as follows:
def user_defined_function_name (list_of_arguments) :
6

body of the user_defined function


In the above example, mult is the name of the function. In this example, a and b
constitute the argument list. The two statements c = a*b and return c constitute the body of
the function.
The syntax for calling the user-defined function is as follows:
user_defined_function_name (list_of_arguments)
In the above example, mult (20, 10) calls the user-defined function. The values 20 and
10 are passed as the values of a and b. The value of c is calculated as 200 and it is returned.
When the user-defined function is called, the values are transferred from the calling function
to the called function. These values are called as arguments. (In the above example, 20 and
10 are the arguments). Four types of arguments are possible in Python.
a) Default Arguments
The value of an argument may be specified when an user-defined function is defined.
Such an argument is called a default argument. Here is an example:
def mult (a = 20, b = 10)
c = a*b
return c
mult( ) # 200 will be the result
mult (30, 20) # 600 will be the result
If the arguments are not passed during the function call ( (eg) mult( ) ), then the default
values (i.e., 20 and 10) are assigned. However, if the arguments are passed ( (eg) mult
(30,20)), the passed arguments are assigned. (In this case, the default values are ignored).
b) Required Arguments
Consider the following user-defined function:
def sum (a, b=10)
return (a+b)
In this example, a is the required argument. Its value should be provided during the
function call.
c) Keyword Arguments
Consider the following ways of calling the above sum( ) function:
sum (60, 40) # 60 will be assigned to a; 40 to b.
sum (b = 40, a = 60) # 60 will be assigned to a; 40 will be assigned to b.
Here, a and b are called keyword arguments. When they are used, values can be listed in a
different order in the argument list.
7

d) Variable length Arguments


Consider the following user-defined function:
def disp (x, *t) :
print (“Value of first argument: “ , x)
print (“Number of Variable Arguments: “, len (t) )
print (“The Variable Arguments: “)
for i in t
print (i)
n1 = int (input (“Enter a Number:” ))
n2 = int (input (“Enter a Number:” ))
n3 = int (input (“Enter a Number:” ))
n4 = int (input (“Enter a Number:” ))
disp (n1, n2, n3, n4)
Output:
Enter a Number : 200
Enter a Number : 300
Enter a Number : 400
Enter a Number : 500
Value of first argument: 200
Number of Variable Arguments: 3
The Variable Arguments:
300
400
500
1.10 Anonymous Functions
In Python, we can define a user-defined function without a name. Such a function is
called an anonymous function. It is not defined with the def keyword. Instead, the keyword
lambda is used. Such a function can consist of only one expression. It can have multiple
number of arguments. It will return only one value. Here is an example.
m = lambda x, y : x*y
n1 = int (input (“Enter a Number:”) )
n2 = int (input (“Enter a Number:”) )
print (“The two input values:”, n1, n2)
print (“The result:”, m (n1,n2) )
Output
Enter a Number: 10
Enter a Number: 20
The two input values: 10 20
The result: 200
8

The syntax of an anonymous function is as follows:


lambda list_of_arguments: expression
In the above example, x and y are the arguments. Here x*y is the expression. Note that the
arguments and the expression are separated by : symbol.
1.11 Scope of Local Variables and Global Variables
The Variables are of two types: local and global. Local Variable is a Variable that is
defined within a user-defined function. The value of a local variable is available only within
the given user-defined function. Here is an example:
def f1( ) :
x = 10
print (“Value of Local Variable x inside f1( ): ”, x)
f1( )
print (“Value of Local Variable x outside f1( ): ”, x)
Output
Value of Local Variable x inside f1( ) : 10
print (“Value of Local Variable x outside f1( ): ”, x)
Name ERROR : name ‘x’ is not defined
Now, consider the following user-defined function:
x = 10
def f1 ( ) :
print (“Value of Global Variable x inside f1( ): ”, x)
f1( )
print (“Value of Global Variable x outside f1( ): ”, x)
Output
Value of Global Variable x inside f1( ): 10
Value of Global Variable x outside f1( ): 10
In Python, scope resolution for the Variable follows the famous “LEGB” rule. Thus,
for a Variable name, the initial search is made in the Local name space. If the Variable is not
found, then the search is made in the Enclosed name space. If the Variable is not found, then
the search is made in the Global name space. If the Variable is not found in the global name
space, then finally the search is made in the Built-in name space. The following table
compares Local  Global Variables.
S. Local Variable Global Variable

1. Local Variables are declared within the Global Variables are declared outside the
function functions, but within the main program.
9

2. The scope of a Local Variable is restricted The Global Variable is accessible


to the function in which it is declared. throughout the entire program.
3. The value of a Local Variable can be The value of the Global Variable can be
assessed only within the function in which accessed throughout the entire program.
it is declared.

1.12 Functional Programming


In Python, the map( ) function, filter( ) function and reduce( ) function are applied to
each element of a List. The map( ) function will take a list as input and applies itself to each
element of that list. Here is an example:
a = [1, 2, 3, 4]
b = [10, 20, 30, 40]
c = list (map (lambda x, y : x+y, a, b) )
print (“a =”, a)
print (“b =”, b)
print (“map( ) result= ”, c)
Output
a = [1, 2, 3, 4]
b = [10, 20, 30, 40]
map( ) result = [11, 22, 33, 44]
The filter( ) function takes two arguments. The first argument is the function to be applied
on the values in a list. The second argument is the list of values on which the function is to
be applied. This function will display only those values that satisfy a specified condition.
a = [15, 20, 24, 35]
c = list (filter (lambda x: x%2 == 0, a) )
print (“a= ”, a)
print (“filter( ) result = ”, c)
Output
a = [15, 20, 24, 35]
filter( ) result = [20, 24]
The reduce( ) function repeatedly applies itself on the input list of values and fuinally
generates a single value as answer.
from functools import reduce
a = [15, 20, 24, 35]
c = reduce (lambda x, y : x+y, a)
print = (“filter( ) result= ”, c)
Output
10

filter( ) result = 94
1.13 Modules
A set of built-in functions and constants that were written for a specific purpose
constitute a Module. For example, the module named re contains functions and constants
required for working with regular expressions. If we wish to make use of the functions
defined in the re module, such as the compile( ) function, we have to import the re module,
as shown below:
import re
my_regular_expression = re.compile (“[0-9]+”, re.I)
Here, we prefix the compile( ) function with the name of the module (i.e., re). If we already
use re in our Program for some other purpose, we can use an alias, as shown below:
import re as regex
my_regular_expression = regex.compile (“[0-9]+”, re.I)
In Python, we use the functions in the module named matplotlib.pyplot for drawing a
variety of figures, such as the Bar Chart and the Pie Chart.
import matplotlib.pyplot
matplotlib.pyplot.plot( ... )
Here, the name of the module is a lengthy one. Instead of writing this lengthy name again
and again, we can use the alias option, as shown below:
import matplotlib.pyplot as plt
plt.plot( ... )
If we need only a few specific functions and constants defined in a Module, we can
import them explicitly and use them without qualification, as shown below:
from collections import defaultdict, counter
lookup = defaultdict (int)
my_counter = counter( )
Note that we are not invoking the defaultdict( ) function in the format
collections.defaultdict( ).
The module is a single Python file. It is saved with .py extension. Assume that a
module named sum has the following functions. Assume further that the following code is
saved as sum.py.
def add (x, y) :
return (x+y)
def mul (a, b) :
return (a*b)
def sub (x, y) :
11

return (x–y)
def div (a, b) :
return (a/b)
The above module sum is imported in the following program. Then, the functions in
this module are used.
import sum
n1 = int ( input (“Enter the first number:” ) )
n2 = int ( input (“Enter the second number:” ) )
print (“The result of add( ): ”, sum.add (n1, n2))
print (“The result of mul( ): ”, sum.mul (n1, n2))
Output
Enter the first number: 30
Enter the second number: 10
The result of add( ): 40
The result of mul( ): 300
The package contains a group of module files. It also contains ...init... py file. All the
components of a package are placed in a single directory. The package directory should be
differentiated from the ordinary directory. For this purpose, the package directory contains
... init ... py file. Every package directory contains this file. Package Installer for Python
(PIP) is used for installing a package.
Python allows the handling of the exceptions raised in the invoked functions.
1.14 Whitespace Formatting
Whitespace is ignored inside parentheses and brackets. This can be helpful for long-
winded computations:
long_winded_computation = (1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+
16+17+18+19+20)
Whitespace can be used for making code easier to read:
list_of_lists = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
easier_to_read_list_of_lits = [ [1, 2, 3],
[4, 5, 6],
[7, 8, 9] ]
We can also use a backslash to indicate that a statement continues onto the next line.
two_plus_three =2+\
3
1.15 Object-oriented Programming in Python
12

In object-oriented programming, focus is given on the data. The code that works with
the data are grouped into a single entity and it is called as a class. The class contains member
data and methods. Some of the principles of object-oriented programming are listed below:
a) Abstraction: Abstraction allows the Programmer to use the object without knowing the
details of the object.
b) Inheritance: Inheritance allows one class to derive the functionality and characteristics
of the other class.
c) Encapsulation: Encapsulation binds all the data members and methods into a single
entity called as class.
d) Polymorphism: Polymorphism allows the same entity to be used a different form. Both
compile-time polymorphism and run-time polymorphism are possible in Python.
1.16 Classes and Objects in Python
A class is a collection of data and the methods that interact with those data. An instance
of a class is known as an object. Each data type in Python, namely the integers, floats,
strings, booleans, lists, sets and dictionaries is an object. We will now develop a class to
represent a circle.

radius

All we need to describe a circle is its radius. Let us also consider the colour to make it easier
later to distinguish between the different instances of the class circle. Here, the data
attributes of the class circle are radius and colour. The class circle shall now be defined
with the constructor and an utility method for calculation the area, as shown below:
class circle (object):
def - init - (self, radius, color) :
self.radius = radius
self.color = color
def calculate - area (self):
area = 3.14 * self.radius * self.radius
return area
We shall now create an object named playground whose radius is 400 meters and the
preferred color is green. We shall also calculate its area.
playground = Circle(400, ‘green’)
area1 = playground. calculate-area( )
13

print (area1)
5024
We will now develop a class to represent a rectangle.

breadth

length
All we need to describe a Rectangle is its length and breadth. Here, the data attributes of
the class. Rectangle are length and breadth. The class Rectangle shall now be defined with a
constructor and an utility method, as shown below:
class Rectangle (object) :
def-init-(self, length, breadth)
self.length = length
self.breadth = breadth
def calculate-perimeter (self) :
perimeter = 2(length + breadth)
return perimeter
We shall now create an object named ClassRoom whose length is 40 feet and the breadth is
20 feet. We will then calculate its area.
classroom = Rectangle (40, 20)
perimeter = classroom.calculate-perimeter( )
perimeter
120

1.17 Inheritance in Python


In object oriented programming, inheritance is a mechanism in which a new class is
derived from an already defined class. The derived class is known as a subclass or a child
class. The pre-existing class is known as the base class or a parent class or super class. The
mechanism of inheritance gives rise to hierarchy in classes. The major purpose of inheriting
a base class into one or more derived classes is code reuse. The subclass inherits all the
methods and properties of the superclass. The subclass can also create its own methods and
replace the methods of the superclass. The process of replacing the methods defined in the
super class with the new methods with the same name in the derived class is known as
overriding.
We will now define a base class named person that has two data attributes, namely
name and age and two methods namely getName( ) and getAge( ). We will also define a
14

derived class named student, which has two additional data attributes, namely rollNumber
and marks and two additional methods, namely getRollNumber( ) and getMarks( ).
class person (object):
def-init- (self, name, age):
self.name = name
self.age = age
def getName (self):
return self.rollNumber
def getAge (self):
return self.age
class student (person):
def-init- (self, name, age, rollNumber, marks):
super (student, self). -init-(self, name, age)
self.rollNumber = rollNumber
self.marks = marks
def getRollNumber(self):
return self.rollNumber
def getMarks (self):
return self.marks
The above classes shall be instantiated and used as shown below:
person1 = person (“Ganesh”, 20)
person1.getName( )
Ganesh
person1.getAge( )
20
student1 = student (“Ganesh”, 20, 101, 83
student1.getName( )
Ganesh
student1.getAge( )
20
student1.getRollNumber( )
101
student1.getMarks( )
83
Chapter-2: Data Structures in Python

2.1 Introduction
Lists, Tuples, Dictionaries and Data Frames are the important data structures available
in Python. All of them are often used now for analyzing data. We will briefly discuss them
one by one.
2.2 Lists
A list is an ordered sequence of comma-separated values of any data type. The values
in a list are written between square brackets. A value in a list can be accessed by specifying
its position in the list. The position is known as index. Here is an example.
list1 = [1, 2, 3, 4, 5]
list1 [0]
1
The lists are mutable. This means that the elements of a list can be changed at a later stage, if
necessary.
list2 = [10, 12, 14, 18, 30, 47]
list2[0] = 20
list2
[20, 12, 14, 18, 30, 47]
Each element of a List can be accessed via an index, as we have seen above. The elements in
a List are indexed from 0. Backward indexing from –1 is also valid. The following table
represents the relationship between the index and the elements in the following list:

Element Index Negative Index


“Michael Jackson” 0 -3
10.1 1 -2
2018 2 -1

Here, L[0] is “Michael Jackson”


L[1] is 10.1
L[2] is 2018
L[–1] is 2018
L[–2] is 10.1
L[–3] is “Michael Jackson”
L[1:3] will provide the list [10.1, 2018]
A list can be created by using the list( ) function, as shown below:
list3 = list (<sequence>)
Here, the sequence shall be a list or string or tuple. Examples:
list4 = list (“hello”)
list4
[‘h’, ‘e’, ‘l’, ‘l’, ‘o’]
list5 = list ((‘p’, ‘y’, ‘t’, ‘h’, ‘o’, ‘n’)) # Tuple
list5
[‘p’, ‘y’, ‘t’, ‘h’, ‘o’, ‘n’]
2.3 Reading in the elements of a List through the keyboard
We can use the list( ) method to read in the elements of a list through the keyboard, as
shown below:
list6 = list (input(“Enter the elements of the List: “))
Enter the elements of the List: 1 2 3 4 5
list6
[‘1’, ‘2’, ‘3’, ‘4’, ‘5’]
Notice that the integers that we have entered as input are represented as strings in the above
case. In order to enter a list of integers or fractional values through the keyboard, we have to
use the eval( ) method, as shown below:
marks = list(eval(input (“Enter marks obtained in 3 Maths, Physics, Chemistry:”)))
Enter marks obtained in Maths, Physics, Chemistry: [92, 74, 83]
percentage = list(eval(input(“Enter percentage marks: “)))
Enter percentage marks: [92.0, 74.0, 83.0]

2.4 List Operations


The most common operations that we perform with the lists include joining lists,
replicating lists and slicing lists. We will briefly discuss about each one of them now.
Joining Two Lists
Joining two lists is very easy just like you perform addition literally. The concentration
operator +, when used with two Lists, joins the two Lists. Here is an example:
list7 = [1, 2, 4]
list8 = [5, 7, 8]
list7 + list8
[1, 2, 4, 5, 7, 8]
Replicating (i.e. Repeating) Lists
As in the case of Strings, you can use the * operator to replicate a List for a specified
number of times. Example:
list7 * 3
[1, 2, 4, 1, 2, 4, 1, 2, 4]
Slicing the Lists
As in the case of Strings, a List Slice is a part of a List, that is extracted out of it.
Example:
list8 = [10, 15, 20, 25, 30, 35, 40, 45, 50]
seq1 = list8[3:6]
seq1
[25, 30, 35]
Note that the slice of a list contains the elements falling between the indices 3 and 6,
not including 6 (i.e., it contains the elements at the positions 3, 4, and 5).
Recall what you have learnt about the negative indexing. In the above example, the
negative index of the element 50 is –1 and the negative index of 40 is –3. So, the above List
Slice shall also be obtained as shown below:
list9 = [10, 15, 20, 25, 30, 35, 40, 45, 50]
seq2 = list9 [3 : –3]
seq2
[25, 30, 35]

2.5 List Methods


Python offers many built-in functions and methods for performing List manipulations.
We will now briefly learn about the important built-in methods that are used for List
manipulations.
1. The index( ) method returns the index of the first matched item from the list. Example:
list10 = [13, 18, 11, 16, 18, 14]
list10.index(18)
1
2. The append( ) method adds a value to the end of the List. Example:
colors = [‘red’, ‘green’, ‘blue’]
colors.append (‘yellow’)
colors
[‘red’, ‘green’, ‘blue’, ‘yellow’]
3. While the append( ) method adds just one element to the List, the extend( ) method can
add multiple elements to a List.
t1 = [‘a’, ‘b’, ‘c’]
t2 = [‘d’, ‘e’]
t1.extend (t2)
t1
[‘a’, ‘b’, ‘c’, ‘d’, ‘e’]
t2
[‘d’, ‘e’]
4. While the append( ) method and the extend( ) method insert the element(s) at the end of
the List, the insert( ) method inserts an element somewhere in between or any position
of your choice. Example:
t1 = [‘a’, ‘e’, ‘u’]
t1.insert (2, ‘i’)
t1
[‘a’, ‘e’, ‘i’, ‘u’]
5. The pop( ) method removes an element from a given position in the List and returns it. If
no index is specified, this method removes and returns the last item in the List. Example:
t2 = [‘k’, ‘a’, ‘e’, ‘i’, ‘p’, ‘q’, ‘u’]
ele1 = t2.pop(o)
ele1
‘k’
t2
[‘a’, ‘e’, ‘i’, ‘p’, ‘q’, ‘u’]
ele2 = t2.pop( )
ele2
‘u’
t2
[‘a’, ‘e’, ‘i’, ‘p’, ‘q’]
6. The pop( ) method removes an element whose position is given. But, what if you know
the value of the element to be removed, but you don’t know its index (i.e. position) in
the List. Well, Python provides the remove( ) method for this purpose. This method
removes the first occurrence of given item from the List. Example:
t3 = [‘a’, ‘e’, ‘i’, ‘p’, ‘q’, ‘a’, ‘q’, ‘p’]
t3.remove (‘q’)
t3
[‘a’, ‘e’, ‘i’,’p’, ‘a’, ‘q’, ‘p’]
7. The clear( ) method removes all the items from the given List. The List becomes an
empty List after this method is applied to it. Example:
t4 = [2, 4, 5, 7]
t4.clear( )
t4
[]
8.The count( ) method returns the number of times given item occurs in the List.
Example:
t5 = [13, 18, 20, 10, 18, 23]
t5.count (18)
2
9. The reverse( ) method just reverses the items in a List. It does not return anything.
Example:
t6 = [‘e’, ‘i’, ‘q’, ‘a’, ‘q’, ‘p’]
t6.reverse ( )
t6
[‘p’, ‘q’, ‘a’, ‘q’, ‘i’, ‘e’]
10. The sort( ) method sorts the items in a List in the ascending order by default. It does not
return anything. If we want this method to sort the items in the descending order, we
have to include the argument reverse = True. Example:
t7 = [‘e’, ‘i’, ‘q’, ‘a’, ‘q’, ‘p’]
t7.sort( )
t7
[‘a’, ‘e’, ‘i’, ‘p’, ‘q’, ‘q’]
t7.sort (reverse = True)
t7
[‘q’, ‘q’, ‘p’, ‘i’, ‘e’, ‘a’]
Programming Example 2.1
The following program reads in the marks obtained by a student in 5 different subjects,
store them in a List and then calculate the average mark.
Program to calculate the average
mark_list = list(eval(input (“Enter the marks in 5 subjects:”)))
length = len (mark_list)
sum = 0
for i in range (0, length) :
sum = sum+ mark_list [i]
average = sum/length
print (“Mean = ”, average)
Output
Enter the marks in 5 subjects: [70, 60, 80, 100, 90]
Mean = 80
Note: Here, the mean can also be found by using the built-in function mean( ), as shown
below:
# Program using built-in function
import statistics
mark_list = list(eval (input (“Enter the marks in 5 subjects: ”) ))
average = statistics.mean (mark_list)
print (average)
Output
Enter the marks in 5 subjects: [70, 60, 80, 100, 90)
Mean = 80
Programming Example 2.2
The following program reads in the salaries obtained by the 5 employees in a Startup,
store them in a List and then calculate the median salary.
Program to calculate the Median
salaries = list(eval(input (“Enter the salaries of 5 employees:”)))
size = len (salaries)
if (size % 2 is 0):
mid = size // 2
higherelement = salaries [mid]
mid1 = mid -1
lowerelement = salaries [mid1]
average = (lowerelement + higherelement)/2
print (“MedianSalary =”, average)
else:
mid = size // 2
average = salaries [mid]
print (“Median Salary=”, average)
Output
Enter the salaries in 5 employees: [50000, 40000, 70000, 90000, 100000]
Median Salary = 70000
Note: Here, the median shall also be found by using the build-in function median ( ), as
shown below:
# Program using built-in function
import statistics
salaries = list(eval (input (“Enter the salaries of 5 employees: ”) ))
average = statistics.median (salaries)
print (“Median Salary=”, average)
Output
Enter the salaries of 5 employees: 50000, 40000, 70000, 90000, 100000
Median Salary = 70000
2.6 Tuples
A Tuple is an ordered sequence of comma-separated values of any data type. The value
in a Tuple are written between round brackets. Tuples are just like Lists. The only difference
is that once we define a Tuple, we cannot change its contents. If we have to change the
contents of a Tuple, we have to store the changed contents as a new Tuple. Due to this
reason, the Tuples are said to be immutable. Here are some Tuples:
tuple1 = (2, 4.7, 10, 10.1)
tuple2 = (‘a’, ‘b’, 1, 2.5, 3)
As in the case of Lists, each element of a Tuple can be accessed via an index. The element in
a Tuple are indexed from 0. Backward indexing from –1 is also valid. The following table
represents the relationship between the index and the elements in the following Tuple
T = (‘a’, ‘e’, ‘i’, ‘o’, ‘u’)
Element Index Negative Index
‘a’ 0 –5
‘e’ 1 –4
‘i’ 2 –3
‘o’ 3 –2
‘u’ 4 –1
Here, T[0] is ‘a’
T[2] is ‘i’
T[4] is ‘u’
T[–1] is ‘u’
T[–3] is ‘i’
T[–5] is ‘a’
A Tuple, T, can be created by using the tuple( ) function, as shown below:
T = tuple (<sequence>)
Here, the sequence shall be a list or a string or another tuple.
Examples:
tuple1 = (1, 5, 10)
tuple2 = tuple ( [1, 2.5, 3.7, ‘a’, ‘b’] )
tuple3 = tuple (“hello”)
tuple3
(“h”, “e”, “l”, “l”, “o”)
2.7 Reading in the elements of a Tuple through the keyboard
The elements of a Tuple shall be provided through the keyboard by using the tuple()
method, as shown below:
tuple4 = tuple ( input (“Enter the elements of the Tuple:” ))
Enter the elements of the Tuple: 1 2 3 4 5
tuple4
(‘1’, ‘2’, ‘3’, ‘4’, ‘5’)
The tuple( ) around input( ) will create a tuple by using individual characters as elements, as
illustrated above. But the most commonly used method to input the elements of a Tuple is to
provide them through the keyboard by using the eval( ) method, as shown below:
tuple5 = eval (input (“Enter the elements of a Tuple:”))
Enter the elements of a Tuple: (1, 2, “be”, [5, 6])
tuple5
(1, 2, “be”, [5, 6])
When we have used the tuple( ) method around the input( ) method above, the integers that
we have entered (i.e. 1 2 3 4 5) were represented as the strings. (i.e. ‘1’, ‘2’, ‘3’, ‘4’, ‘5’).
But, when we have used the eval( ) method around the input( ) method above, the numbers 1
and 2 were represented as numbers. (They are not represented as the strings ‘1’ and ‘2’).
2.8 Tuple Operations
The most common operations that we perform with the tuples include joining tuples,
replicating tuples and slicing tuples. We will briefly discuss about each one of them now.
Joining two Tuples
Joining two Tuples is just like you perform the addition operation. The concentration
operator +, when used with two tuples, joins the two tuples. Here is an example.
t1 = (1, 3, 5)
t2 = (6, 7, 8)
T1 + t2
(1, 3, 5, 6, 7, 8)
Replicating (i.e. Repeating) Tuples
As in the case of Lists, you can use the * operator to replicate a Tuple for a specified
number of times. Example:
t1 * 3
(1, 3, 5, 1, 3, 5, 1, 3, 5)
Slicing the Tuples
As in the case of Lists and Strings, a slice of a Tuple is a part of a Tuple, as illustrated
below:
t3 = (10, 12, 14, 20, 22, 24, 30, 32, 34)
t4 = t3 [3 : –3]
t4
(20, 22, 24)
Comparing Tuples
We can compare two Tuples without having to write code with loops for achieving
it.
a = (2, 3)
b = (2, 3)
c = (‘2’, ‘3’)
d = (2.0, 3.0)
e = (2, 3, 4)
a == b
True
a == c
False
a == d
True
a<e
True
Unpacking a Tuple
Creating a Tuple from a set of values is called packing. Its reverse (i.e. creating
individual values from a Tuple’s elements is called unpacking.
t = (1, 2, ‘A’, ‘B’)
(w, x, y, z) = t
w
1
x
2
y
‘A’
z
‘B’
Deleting a Tuple
The del statement is used to delete a Tuple. We can delete a complete Tuple. But we
cannot delete the individual elements of a Tuple, as the Tuples are immutable.
2.9 Tuple Methods
Python offers many built-in functions and methods for performing Tuple
manipulations. We will now briefly learn about the important built-in methods that are used
for Tuple manipulations.
1. len( ) method
This method returns the length of a Tuple. (i.e. the number of elements in a Tuple).
employee = (‘John’, 10000, 24, ‘Sales’)
len(employee)
4
2. max( ) method
This method returns the element that has the maximum value.
t1 = (10, 12, 14, 20, 22, 24, 30, 32, 34)
max(t1)
34
3. min( ) method
This method returns the element that has the minimum value.
t2 = (10, 12, 14, 20, 22)
min(t2)
10
4. index( ) method
This method returns the index of an element in a Tuple.
t3 = (3, 4, 5, 6)
t3.index(5)
2
5. count( ) method
This method returns the number of times an element occurs in a Tuple.
t4 = (2, 4, 2, 5, 7, 4, 8, 9, 9, 11, 7, 2)
t4.count(2)
3
6. tuple( ) method
This is the constructor method. It is used to create tuples from different types of values.
t = tuple ( [1, 2, 3] ) # Creating a Tuple from a List
t
(1, 2, 3)

2.10 Sets
A Set is a collection of distinct elements. As in the case of Lists and Tuples, the
elements of a set can be of different data types. (i.e., Values of different data types can be
placed within a Set). Unlike Lists and Tuples, sets are unordered. This means that the Sets
do not record the element position. Sets only have unique elements. This means there is
only one of a particular element in a Set. To define a Set, you have to use curly brackets.
You have to place the elements of a Set within the curly brackets, as shown below:
set1 = {“rock”, “R&B”, “disco”, “hard rock”, “pop”, “soul”}
You can convert a List to a Set by using the function Set. This is called type-casting. You
have to simply use the List as the input to the function set( ). The result will be a List
converted to a Set.
Let us go over an example. We start off with a List. We input the List to the function
set(). The function set() returns a Set. Notice how there are no duplicate elements.
album-list = [“Michael Jackson”, “Thriller”, “Thriller”, 1982]
album-set = set (album-list)
album-set
{“Michael Jackson”, “Thriller”, 1982}

Let us go over the Set operations. These can be used to change the Set. Consider the
Set, A, given below:
A = {“Thriller”, “Back in Black”, “AC/DC”}
We can add an item to a Set by using the add( ) method.
A . add (“NSYNC”)
A
{“AC/DC”, “Back in Black”, “NSYNC”, “Thriller”}
We can remove an item from a Set by using the remove( ) method.
A. remove (“NSYNC”)
A
{“AC/DC”, “Back in Black”, “Thriller”}
We can verify whether an element is in the set by using the in command, as follows:
A = {“AC/DC”, “Back in Black”, “Thriller”}
“AC/DC” in A
True
These are the types of Mathematical Set operations. There are other operations that we
can do. For example, we can find the union/intersection of two sets.
album-set-1 = {“AC/DC”, “Back in Black”, “Thriller”}
album-set-2 = {“AC/DC”, “Back in Black”, “The Dark Side of the Moon”}
album-set-3 = album-set-1 & album-set-2
album-set-4 = album-set-1 . union(album-set-2)
album-set-3
{“AC/DC”, “Back in Black”}
album-set-4
{“AC/DC”, “Back in Black”, “Thriller”, “The Dark Side of the Moon”}
Here, all the elements of album-set-3 are in album-set-1. We can check whether a Set is a
SubSet of another Set by using the issubject( ) method. Here is an example:
album-set-3 . issubject(album-set-1)
True
2.11 Dictionaries
A Dictionary is a collection of key:value pairs. The elements in a Dictionary are
written between curly brackets. In the case of Lists and Tuples, an index is associated with
each element. But, in the case of a Dictionary, a key is associated with each element. The
key should be unique. In the case of Lists and Tuples, the index is used to access the
elements. But, in the case of a Dictionary, the key is used to access the elements.
Dictionaries are mutable. So, we can change some of the elements of a Dictionary and
then store the changed elements in the same Dictionary object. Dictionaries are unordered,
as no index is associated with the elements of a Dictionary. A Dictionary, D, can be created
by using a Command of the following form:
<Dictionary-name> = {<key> : <value>, <key> : <value>, ...}
Example
teachers = {“Benedict” : “Maths”, “Albert” : “CS”, “Andrew” : “Commerce” }
An element in a Dictionary can be accessed by using the key, as illustrated below:
teachers [“Andrew”]
Commerce
Traversing a Dictionary
Traversal of a collection of values means accessing and processing each element of it.
The traversal can be done in the case of a Dictionary by using the for loop, as shown below:
d1 = {5 : “Number”, “a” : “String”, (1, 2) : “Tuple” }
for key in d1
print (key, “:”, d1 [key])
a : String
(1,2) : Tuple
5 : Number
Programming Example 2.3
We will now write a Program to create a Phone Dictionary for our friends and then
print it.
PhoneDirectory = {“Jagdish” : “94437 55625”, “Bala” : “96297 09185”,
“Saravanan” : “99947
49333”}
for name in PhoneDirectory :
print (name, “:”, PhoneDirectory [name])
The output of the above program will be as shown below:
Jagdish : 94437 55625
Bala : 96297 09185
Saravanan : 99947 49333
Adding an element to a Dictionary
We can add a new key:value pair to a Dictionary by using a simple assignment
statement, as shown below:
Employee = {“name” : “John”, “salary” : 10000, “age” : 24}
Employee [“dept”] = “Sales”
Employee
{“name” : “John”, “salary” : 10000, “age” : 24, “dept” : “Sales”}

Updating an element in a Dictionary


Like the Lists, the Dictionaries are also mutable. So, we can add an element to an
existing Dictionary, as shown above. We can also change (i.e. update) an existing element by
using a simple assignment statement, as shown below:
Employee2 = {“name” : “John”, “salary” : 10000, “age” : 24}
Employee2 [“Salary”] = 20000
Employee2
{“name” : “John”, “salary” : 20000, “age” : 24}
Deleting an existing element from a Dictionary
Both the del( ) method and the pop( ) method can be used for this purpose, as
illustrated below:
Employee3 = {“salary” : 10000, “age” : 24, “name” : “John”}
del Employee3 [“age”]
Employee 3
{“salary” : 10000, “name” : “John”}
Employee4 = {“salary” : 10000, “age” : 24, “name” : “John”}
Employee4.pop (“age”)
24
Employee4
{“salary” : 10000, “name” : “John”}

Dictionary Methods
Let us now briefly discuss the various built-in functions and methods that are provided
by Python to manipulate the elements of Dictionaries.
1. len( ) method
This method returns the number of key:value pairs in a Dictionary
Employee5 = {“name” : “John”, “salary” : 10000, “age” : 24}
len (Employee5)
3
2. clear( ) method
This method removes all the elements of a Dictionary and makes it an empty Dictionary.
When we use the del statement, the Dictionary no more exists, not even an empty
Dictionary.
Employee6 = {“name” : “John”, “salary” : 10000, “age” : 24}
Employee6.clear( )
Employee6
{}
3. get( ) method
This method helps us to get the value that is associated with a key.
Employee7 = {“salary” : 10000, “department” : “Sales”, “age” : 24, “name” : “John”}
Employee7.get (“department”)
“Sales”
4. items( ) method
This method returns all the key:value pairs in a Dictionary.
Employee8 = {“name” : “John”, “salary” : 10000, “age” : 24}
myList = Employee8.items( )
for x in myList
print x
(“salary”, 10000)
(“age”, 24)
(“name”, “John”)
5. keys( ) method
This method returns all the keys in a Dictionary
Employee9 = {“salary” : 10000, “department” : “sales”, “age” : 24, “name” : “John”}
Employee9.keys( )
[“salary”, “department”, “age”, “name”]
6. values( ) method
This method returns all the values in a Dictionary
Employee10 = {“salary” : 10000, “department” : “Sales”, “age” : 24, “name” : “John”}
Employee10: values( )
[10000, “Sales”, 24, “John”]

7. update( ) method
This method merges key:value pairs from the new dictionary into the original
dictionary, adding or replacing, as needed.
Employee11 = {“name” : “John”, “salary” : 10000, “age” : 24}
Employee12 = {“name” : “David”, “salary” : 54000, “department” : “Sales”}
Employees11.update (Employees12)
Employees11
{“salary”: 540000, “department”: “Sales”, “name”: “David”, “age”: 24}
Note:
The elements of Employees12 dictionary have overridden the elements of
Employees11 dictionary having the same keys. So, the values associated with the keys
“name” and “salary” have been changed.
2.12 Default Dictionary
Imagine that you are trying to count the number of occurrences of the words in a
document. An obvious approach is to create a Dictionary in which the keys are words and the
values are counts. As you check each word, you can increment its count if it is already in the
Dictionary and add it to the Dictionary if it is not.
word_counts = { }
for word in document:
if word in word_counts:
word_counts [word] = word_counts [word] + 1
else:
word_counts [word] = 1
We can just handle the exception that may arise due to trying to look up a missing key.
word_counts = { }
for word in document:
try:
word_counts [word] = word_counts [word] + 1
except keyError:
word_counts [word] = 1
A third approach is to use the get( ) method, which behaves gracefully in the case of missing
Keys:
word_counts = { }
for word in document:
previous_count = word_counts.get (word, 0)
word_counts [word] = previous_count + 1
Every one of these is slightly unwieldly. In such cases, defaultdict( ) method is helpful.
A defaultdict is like a regular dictionary, except that when you try to look up a key it doesn’t
contain, it first adds a value for it by using a zero-argument function you provided when you
created it. In order to use defaultdicts, you have to import them from collections module.
2.13 Exception Handling
When something goes wrong, Python raises an exception. If they are not handled,
exceptions will cause our Program to crash. We can handle the exceptions by using try and
except, as shown below:
try :
print (0/0)
except ZeroDivisionError :
print ( “cannot divide by zero” )
Suppose that a Person is not sure whether a Tuple is immutable or not. So, when he writes
code to alter the value of an element, he will make use of exception handling, as shown
below:
try:
my_tuple [1] = 3
except TypeError:
print (“cannot modify a Tuple”)
Suppose that a Person is not sure whether a key named “Kate” is present in a Dictionary or
not. So, when she writes code to access the value associated with the key “Kate”, she will
make use of exception handling so that her Program does not crash in case the key “Kate” is
not present in the Dictionary.
try:
kates_grade = grades [“kate”]
except keyError:
print (“no value for kate!”)
So for, we have discussed about handling exceptions that are raised by default. Exceptions
can also be raised manually, as shown in the following example:
try:
a = int (input (“Enter the value of a:”) )
b = int (input (“Enter the value of b:”) )
print (“The value of a =”, a)
print (“The value of b =”, b)
if (a-b) < 0 :
raise Exception (“Exception raised”)
except Exception as e:
print (“Received exception:”, e)

Output
Enter the value of a : 15
Enter the value of b : 20
The value of a = 15
The value of b = 20
Received exception : value of a-b is < 0

2.14 Counter
A Counter turns a sequence of values into a defaultdict(int) - like object. The keys will
be mapped to counts.
from collections import counter
c = Counter ( [0, 1, 2, 0] ) # c is {0:2, 1:1, 2:1}
Counter gives us a very simple way to solve our word-counts problem:
word_counts = Counter (document) # Here, document is a list of words
The most_common( ) method of Counter instance is often used in Natural Language
Processing.
# print the 10 most common words and their counts
for word, count in word_counts.most_common(10) :
print (word, count)
2.15 List Comprehensions
Frequently, you will want to transform a list into another list by choosing only certain
elements, by transforming elements, or both. The Pythonic way to do this is with list
comprehensions.
even_members = [x for x in range(5) if x%2 == 0] # [0, 2, 4]
squares = [x*x for x in range(5) ] # [0, 1, 4, 9, 16]
even_squares = [x*x for x in even_numbers] # [0, 4, 16]
We can similarly turn lists into dictionaries or sets, as shown below:
square_dict = {x: x*x for x in range (5) } # {0:0, 1:1, 2:4, 3:9, 4:16}
square_set = {x*x for x in [1, –1] } # {1}
If you don’t need the value from the list, it is common to use an underscore as the variable:
zeroes = [0 for _ in even-numbers ] # has the same length as even-numbers
A list comprehension can include multiple for loops:
pairs = [(x, y)
for x in range (10)
for y in range (10) ] # 100 pairs (0,0), (0,1), ..., (9, 8), (9,9)
The later for loops can use the results of earlier for loops:
increasing_pairs = [(x, y) # only pairs with x < y
for x in range (10) # range 1 to
10 equals
for y in rang (x+1, 10)]# [1, 2, 3, 4, 5, 6, 7, 8,
9]

2.16 Automated Testing and Assert


As Data Scientists, we will be writing a lot of code. How can we be confident that our
code is correct? One way is with types. (We will discuss this later). Another way is with
automated tests.
There are elaborate frameworks for writing and running tests. But, we will use the
assert statement for this purpose. It will cause your code to raise an assertionError if your
specified condition is not met.
assert 1+1 == 2
assert 1+1 == 2, “1+1 should equal 2 but didn’t”
As you can see in the second case, you can optionally add a message to be displayed if
the assertion fails. The above example is a trivial one. A real-life example is given below:
def smallest_item (xs)
return min (xs)
assert smallest_item ( [10, 20, 5, 40] ) == 5
assert smallest_item ( [1, 0, –1, 2] ) == –1
The assert statement is used as shown above. It is a good practice to liberally use the assert
statement in your code, as it helps you to be confident that your code is correct.
2.17 Iterables and Generators
We can retrieve the specific elements of a List by their indices. But you don’t always
need this! A list of a billion numbers takes up a lot of memory. If you only want the elements
one at a time, there is no good reason to keep them all around in the memory. If you need
only the first few elements, generating the entire billion of values is highly wasteful.
Often all we need is to iterate over a collection of values by using for and in. In this
case, we can create generators, which can be iterated over just like lists but generate their
values lazily on demand. One way to create a generator is to use a function and the yield
operator, as shown below:
def generate_range (n) :
i=0
while i < n :
yield i # every call to yield produces a value of the
Generator
i=i+1
The following loop will make use of the yielded values one at a time until no value is left:

for i in generate_range (10) :


print ( f “i : {i}” )
With a generator, you can even create an infinite sequence:
def natural_numbers ( ) :
n=1
while True :
yield n
n = n+1
A second way to create generators is by using for comprehensions wrapped in parentheses:
evens_below_20 = ( i for i in generate_range (20) if 1%2 = = 0 )
Such a generator comprehension doesn’t do any work until you iterate over it by using for
or next.
Quite frequently, when we are iterating over a list or a generator, we will want not just
the values but also their indices. For this common case, Python provides an enumerate
function, which turns values into pairs (index, value):
names = [ “Alice”, “Bob”, “Charlie”, “Debbie” ]
# not Pythonic way of writing code
for i in range ( len (names) ) :
print ( f “name {i} i {names[i]}” )
# also not Pythonic way of writing code
i=0
for name in names :
print ( f “name {i} is {names [i]}” )
i=i+1
# Pythonic way of writing code
for i, name in enumerate (names) :
print ( f “name {i} is {name}” )
2.18 Random Number Generation
As we learn Data Science, we will frequently need to generate random numbers. We
can generate random numbers by using the functions in the random module:
import random
random.seed (10) # This ensures that we get the same results every time.
The random( ) function in the random module is used most often. This function
generates random numbers in the range 0 to 1. The random numbers that are generated by
this function will be uniformly distributed in the interval [0, 1]. Suppose that you generate
100 numbers by using this function. Then, 25 of them will lie in the interval [0, 0.25],
another 25 in the interval [0.25, 0.50], another 25 in the interval [0.50, 0.75] and 25 in the
interval [0.75, 1].
four_uniform_random_numbers = [random.random( ) for_in_range(r)]
# [0.57140259468, 0.42888905467, 0.57809130113, 0.20609823213]
We will sometimes use random.randrange( ) function. It takes either one or two
arguments and returns an element chosen randomly from the corresponding range:
random.randrange(10) # choose randomly from the range [0, 1, 2, ..., 8, 9]
random.randrange(3, 6) # choose randomly from the range [3, 4, 5]
There are a few more methods that we will sometimes find convenient. For example,
random.shuffle( ) randomly reorders the elements of list:
up_to_ten = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
random.shuffle (up_to_ten)
print (up_to_ten)
# [7, 2, 6, 8, 9, 4, 10, 1, 3, 5] (Your results will probably be different.)
If you need to randomly pick one element from a list, you can use the random.choice( )
function.
randomly_picked_value = random.choice ( [“Alice”, “Bob”, “Charlie”] )
If you wish to select a random sample of values without replacement, (i.e., with no
duplicate), you can use the random.sample( ) function.
lottery_numvers = range(60)
winning_numbers = random.sample (lottery_numbers, 6) # [16, 36, 10, 6, 25, 9]
In order to select a random sample of values with replacement (i.e., allowing
duplicates), you can just make multiple calls to random choice( ) function.
four_numbers_with_replacement = [random.choice ( range(10) ) for_in_range (4) ]
print ( four_members_with_replacement) # [9, 4, 4, 2]
2.19 Type Annotations
Python is a dynamically typed language. This means that it is general it does not care
about the data types of the objects we use, as long as we use them in valid ways:
def add (a, b):
return a+b
assert add (10, 5) == 15, “+ is valid for numbers”
assert add ( [1, 2], [3] == [1,2,3], “+ is valid for lists
assert add (“hi”, “there”) == “hi there”, “+ is valid for strings”
try :
add (10, “five”)
except TypeError :
print (“cannot add an int to a string”)
In a statistically typed language, such as C++, the data types of the arguments and the
returned value of the above add( ) function will be specified in more or less the same way in
which they are specified below:
def add (a : int, b : int)  int :
return a+b
add (10, 5) # You like this to be OK
add (“hi”, “there”) # You like this to be not OK
The above version of add( ) function with the int type annotations is valid in recent versions
of Python, such as Python 3.6.
However, the above-mentioned type annotations don’t actually do anything. You can
still use the above annotated add( ) function to add two strings, even though it is wrong to do
so. If you make the call add (10, “five”), it will raise the TypeError specified above. That
said, there are still two good reasons to use type annotations in your Python code:
1. Types are an important form of documentation. The second function stub given below is
more informative than the first one.
def dot_product (x, y): ... ... ...
def dot_product (x : Vector, y : Vector)  float ... ... ...
2. There are external tools, such as mypy, that will read your code, inspect the type
annotations, and let you know about type errors before you ever run your code. For
example, if you run mypy over a file containing add (“hi”, “there”), it will warn you, as
shown below:
error : Argument 1 to “add” has incompatible type “str", excepted “int”
Like assert testing, this is a good way to find mistakes in your code before you ever run
it.
How to write Type Annotations?
For built-in types such as int, float and bool, you just use the type itself as the
annotation. (e.g.) def add (a: int, b: int)  int). What if you have a list?
def total (xs : list)  float
return sum (total)
This is not wrong. But the type is not specific enough. It is clear that we really want xs
to be a list of floats, not a list of strings.
The typing module provides a number of parameterized types that we can use to do
just this:
from typing import List # Note the capital letter L
def total ( xs: List [float] )  float:
return sum (total)
Up until now, we have only specified annotations for function parameters and return
types. For variables themselves, it is usually obvious what the data type is:
x : int = 5 # Type annotation is not necessary here. It is obvious.
However, sometimes it is not obvious:
values =[] # Data Type is not clear here
best_so_far = None # Data Type is not clear here
In such cases, we will supply inline type hints, as shown below:
from typing import Optional
values: List [int] = [ ]
best_so_far: Optional [floar] = None allowed to be either a float or None

You might also like