Module-3
Dictionaries: Dictionary Operations, Dictionary Methods, Aliasing and
Copying
Numpy: About, Shape, Slicing, Masking, Broadcasting, Dtype.
Files: About files, writing our first file, reading a file line-at-a-time, turning
a file into a list of lines, reading the whole file at once, working with binary
files, directories, fetching something from the web.
Dictionary is a data structure that stores the value in key: value pairs. Values in
a dictionary can be of any data type and can be duplicated, whereas keys can't
be repeated and must be immutable. Dictionaries are written with curly `
brackets, and have keys and values:
• Keys are case sensitive which means same name but different cases of
Key will be treated distinctly.
• Keys must be immutable which means keys can be strings, numbers or
tuples but not lists.
• Duplicate keys are not allowed and any duplicate key will overwrite the
previous value.
• Internally uses hashing. Hence, operations like search, insert, delete can
be performed in Constant Time.
How to Create a Dictionary
Dictionary can be created by placing a sequence of elements within curly {}
braces, separated by a 'comma'.
thisdict = {
"College": "Navkis",
"Branch": "Engineering",
"year": 2025
}
print(thisdict)
d1 = {1: 'Raj', 2: 'Ram', 3: 'Ravi'}
print(d1)
# create dictionary using dict() constructor
d2 = dict(a = "Navkis", b = "College", c = "Engineering")
print(d2)
Dictionary Items
Dictionary items are ordered, changeable, and do not allow duplicates.
Dictionary items are presented in key:value pairs, and can be referred to by
using the key name.
Example
Print the "branch" value of the dictionary:
thisdict = {
"College": "Navkis",
"Branch": "Engineering",
"year": 2025
}
print(thisdict["Branch"])
Ordered or Unordered?
As of Python version 3.7, dictionaries are ordered. In Python 3.6 and earlier,
dictionaries are unordered.
When we say that dictionaries are ordered, it means that the items have a
defined order, and that order will not change.
Unordered means that the items do not have a defined order, you cannot refer to
an item by using an index.
Changeable
Dictionaries are changeable, meaning that we can change, add or remove items
after the dictionary has been created.
Duplicates Not Allowed
Dictionaries cannot have two items with the same key:
thisdict = {
"College": "Navkis",
"Branch": "Engineering",
"year": 2025
"year": 2026
}
print(thisdict)
Dictionary Length
To determine how many items a dictionary has, use the len() function
Example
Print the number of items in the dictionary:
print(len(thisdict))
Dictionary Items - Data Types
The values in dictionary items can be of any data type:
Example
String, int, boolean, and list data types:
thisdict = {
"College": "Navkis",
"Branch": ["UG", "PG"],
"year": 2025
}
print(thisdict)
type()
From Python's perspective, dictionaries are defined as objects with the data type
'dict':
<class 'dict'>
Example
Print the data type of a dictionary:
thisdict = {
"College": "Navkis",
"Branch": ["UG", "PG"],
"year": 2025
}
print(type(thisdict))
The dict() Constructor
It is also possible to use the dict() constructor to make a dictionary.
Example
Using the dict() method to make a dictionary:
thisdict = dict(name = "Raj", age = 36, country = "India")
print(thisdict)
Accessing Items
You can access the items of a dictionary by referring to its key name, inside
square brackets:
Example
Get the value of the "age" key:
thisdict = dict(name = "Raj", age = 36, country = "India")
x = thisdict["age"]
print(x)
There is also a method called get() that will give you the same result:
thisdict = dict(name = "Raj", age = 36, country = "India")
x = [Link]("age")
print(x)
Get Keys
The key() method will return a list of all keys in the dictionary.
thisdict = dict(name = "Raj", age = 36, country = "India")
x = [Link]()
print(x)
The list of the keys is a view of the dictionary, meaning that any changes done to
the dictionary will be reflected in the keys list.
Example
Add a new item to the original dictionary, and see that the keys list gets updated
as well:
person = {
"Name": "Raj",
"age": 36,
"year": 1964
}
x = [Link]()
print(x) #before the change
person["Gender"] = "male"
print(x) #after the change
Get Values
The values() method will return a list of all the values in the dictionary.
Example
Get a list of the values:
person = {
"Name": "Raj",
"age": 36,
"year": 1964
}
x = [Link]()
print(x)
The list of the values is a view of the dictionary, meaning that any changes done
to the dictionary will be reflected in the values list.
Example
Make a change in the original dictionary, and see that the values list gets
updated as well:
person = {
"Name": "Raj",
"age": 36,
"year": 1964
}
x = [Link]()
print(x) #before the change
person["year"] = 2025
print(x) #after the change
Example
Add a new item to the original dictionary, and see that the values list gets
updated as well:
person = {
"Name": "Raj",
"age": 36,
"year": 1964
}
x = [Link]()
print(x) #before the change
person["gender"] = "male"
print(x) #after the change
Get Items
The items() method will return each item in a dictionary, as tuples in a list.
Example
Get a list of the key:value pairs
x = [Link]()
The returned list is a view of the items of the dictionary, meaning that any
changes done to the dictionary will be reflected in the items list.
Check if Key Exists
To determine if a specified key is present in a dictionary use the in keyword.
person = {
"Name": "Raj",
"age": 36,
"year": 1964
}
if "Name" in person:
print("Yes, 'Name' is one of the keys in the thisdict dictionary")
Change Values
You can change the value of a specific item by referring to its key name:
person = {
"Name": "Raj",
"age": 36,
"year": 1964
}
person["year"] = 2025
print(person)
Update Dictionary
The update() method will update the dictionary with the items from the given
argument.
The argument must be a dictionary, or an iterable object with key:value pairs.
Example
Update the "year" of the car by using the update() method:
person = {
"Name": "Raj",
"age": 36,
"year": 1964
}
[Link]({"year": 2020})
print(person)
Adding Items
Adding an item to the dictionary is done by using a new index key and
assigning a value to it:
person = {
"Name": "Raj",
"age": 36,
"year": 1964
}
person["gender"] = "male"
print(person)
Update Dictionary
The update() method will update the dictionary with the items from a given
argument. If the item does not exist, the item will be added.
The argument must be a dictionary, or an iterable object with key:value pairs.
person = {
"Name": "Raj",
"age": 36,
"year": 1964
}
[Link]({"gender": "male"})
print(person)
Remove Items
There are several methods to remove items from a dictionary:
Example
The pop() method removes the item with the specified key name:
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
[Link]("model")
print(thisdict)
The popitem() method removes the last inserted item (in versions before 3.7, a
random item is removed instead):
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
[Link]()
print(thisdict)
The del keyword removes the item with the specified key name:
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
del thisdict["model"]
print(thisdict)
The del keyword can also delete the dictionary completely:
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
del thisdict
print(thisdict) #this will cause an error because "thisdict" no longer exists.
The clear() method empties the dictionary:
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
[Link]()
print(thisdict)
Loop Dictionaries
When looping through a dictionary, the return value are the keys of the
dictionary, but there are methods to return the values as well.
Print all key names in the dictionary, one by one:
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
for x in thisdict:
print(x)
Print all values in the dictionary, one by one:
for x in thisdict:
print(thisdict[x])
values() method to return values of a dictionary:
for x in [Link]():
print(x)
keys() method to return the keys of a dictionary:
for x in [Link]():
print(x)
both keys and values, by using the items() method:
for x, y in [Link]():
print(x, y)
Copy Dictionaries
You cannot copy a dictionary simply by typing dict2 = dict1, because: dict2 will
only be a reference to dict1, and changes made in dict1 will automatically also
be made in dict2.
There are ways to make a copy, one way is to use the built-in Dictionary
method copy()
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
mydict = [Link]()
print(mydict)
Another way to make a copy is to use the built-in function dict()
thisdict = {
"brand": "Ford",
"model": "Mustang",
"year": 1964
}
mydict = dict(thisdict)
print(mydict)
Nested Dictionaries
A dictionary can contain dictionaries, this is called nested dictionaries.
Create a dictionary that contain three dictionaries:
myfamily = {
"child1" : {
"name" : "Emil",
"year" : 2004
},
"child2" : {
"name" : "Tobias",
"year" : 2007
},
"child3" : {
"name" : "Linus",
"year" : 2011
}
}
Dictionaries Methods
Numpy: About, Shape, Slicing, Masking, Broadcasting, dtype
Python List are not designed as mathematical objects. Rather, they are purely a
collection of items. In order to get a type of list which behaves like a
mathematical array or matrix, we use Numpy.
a=[2,3,4]
print(2*a)
output:
[2, 3, 4, 2, 3, 4]
Numpy is a general-purpose array-processing package. It provides a high-
performance multidimensional array object, and tools for working with these
arrays. It is the fundamental package for scientific computing with Python.
import numpy as np
a=[Link]([2,3,4])
print(2*a)
Output
[4 6 8]
Arrays in Numpy
Array in Numpy is a table of elements (usually numbers), all of the same type,
indexed by a tuple of positive integers. In Numpy, number of dimensions of the
array is called rank of the array. A tuple of integers giving the size of the array
along each dimension is known as shape of the array. An array class in Numpy
is called as ndarray. Elements in Numpy arrays are accessed by using square
brackets and can be initialized by using nested Python Lists.
Creating a Numpy Array
Arrays in Numpy can be created by multiple ways, with various number of
Ranks, defining the size of the Array. Arrays can also be created with the use of
various data types such as lists, tuples, etc. The type of the resultant array is
deduced from the type of the elements in the sequences.
Note: Type of array can be explicitly defined while creating the array.
import numpy as np
# Creating a rank 1 Array
arr = [Link]([1, 2, 3])
print(arr)
# Creating a rank 2 Array
arr = [Link]([[1, 2, 3],
[4, 5, 6]])
print(arr)
# Creating an array from tuple
arr = [Link]((1, 3, 2))
print(arr)
Output
Array with Rank 1:
[1 2 3]
Array with Rank 2:
[[1 2 3]
[4 5 6]]
Array created using passed tuple:
[1 3 2]
Accessing the array Index
In a numpy array, indexing or accessing the array index can be done in multiple
ways. To print a range of an array, slicing is done. Slicing of an array is defining
a range in a new array which is used to print a range of elements from the
original array. Since, sliced array holds a range of elements of the original array,
modifying content with the help of sliced array modifies the original array
content.
import numpy as np
arr = [Link]([[-1, 2, 0, 4],
[4, -0.5, 6, 0],
[2.6, 0, 7, 8],
[3, -7, 4, 2.0]])
# Printing a range of Array
# with the use of slicing method
arr2 = arr[:2, ::2]
print ("first 2 rows and alternate columns(0 and 2):\n", arr2)
# Printing elements at
# specific Indices
arr3 = arr[[1, 1, 0, 3],
[3, 2, 1, 0]]
print ("\nElements at indices (1, 3), "
"(1, 2), (0, 1), (3, 0):\n", arr3)
Output
first 2 rows and alternate columns(0 and 2):
[[-1. 0.]
[ 4. 6.]]
Elements at indices (1, 3), (1, 2), (0, 1), (3, 0):
[0. 6. 2. 3.]
Basic Array Operations
In numpy, arrays allow a wide range of operations which can be performed on a
particular array or a combination of Arrays. These operation include some basic
Mathematical operation as well as Unary and Binary operations.
import numpy as np
# Defining Array 1
a = [Link]([[1, 2],
[3, 4]])
# Defining Array 2
b = [Link]([[4, 3],
[2, 1]])
# Adding 1 to every element
print ("Adding 1 to every element:", a + 1)
# Subtracting 2 from each element
print ("\nSubtracting 2 from each element:", b - 2)
# sum of array elements
# Performing Unary operations
print ("\nSum of all array elements: ", [Link]())
# Adding two arrays
# Performing Binary operations
print ("\nArray sum:\n", a + b)
Output
Adding 1 to every element: [[2 3]
[4 5]]
Subtracting 2 from each element: [[ 2 1]
[ 0 -1]]
Sum of all array elements: 10
Array sum:
[[5 5]
[5 5]]
Shape
One of the most important properties an array is its shape. Arrays can have any
dimensions. Images for example, consist of a 2D array of pixels. But in color
images every pixel is an RGB tuple: the intensity in red, green and blue. Every
pixel itself is therefore an array as well. This makes a color image 3D overall.
To get the shape of an array, we use shape:
import numpy as np
a=[Link]([2,3,4])
print([Link])
Output:
(3,)
import numpy as np
b=[Link]([
[2,3,8],
[4,5,6]
])
print([Link])
Output:
(2,3)
Slicing
When we need to select certain values from an array. For 1D arrays it works just
like for normal python lists:
import numpy as np
a=[Link]([2,3,8])
print(a[2])
print(a[1:])
Output:
8
[3 8]
import numpy as np
a=[Link]([
[2,3,8],
[4,5,6],
])
print(a[1])
print(a[1][2])
print(a[:,1])
Output:
[4 5 6]
6
[3 5]
Masking:
When we want to throw away all values above a certain cutoff
import numpy as np
a=[Link]([230, 10, 284, 39, 76])
cutoff=200
print(a>cutoff)
Output:
[ True False True False False]
Using the larger than operator. We set all the values above to zero.
import numpy as np
a=[Link]([230, 10, 284, 39, 76])
cutoff=200
a[a>cutoff]=0
print(a)
Output:
[ 0 10 0 39 76]
Broadcasting:
Broadcasting takes place when you perform operations between arrays of
different shapes.
import numpy as np
a=[Link]([
[0,1],
[2,3],
[4,5],
])
b=[Link]([10,100])
print(a*b)
Output:
[[ 0 100]
[ 20 300]
[ 40 500]]
import numpy as np
a=[Link]([
[0,1,2],
[3,4,5],
])
b=[Link]([10,100])
print(a*b)
Output:
ValueError: operands could not be broadcast together with shapes (2,3) (2,)
import numpy as np
a=[Link]([
[0,1,2],
[3,4,5],
])
b=[Link]([10,100])
print(a*b[:, None])
Output:
[[ 0 10 20]
[300 400 500]]
dtype:
File Handling in Python
File handling refers to the process of performing operations on a file, such as
creating, opening, reading, writing and closing it through a programming
interface. It involves managing the data flow between the program and the file
system on the storage device, ensuring that data is handled safely and
efficiently.
Why do we need File Handling
• To store data permanently, even after the program ends.
• To access external files like .txt, .csv, .json, etc.
• To process large files efficiently without using much memory.
• To automate tasks like reading configs or saving outputs.
Opening a File
To open a file, we can use open() function, which requires file-path and mode as
arguments:
Syntax:
file = open('[Link]', 'mode')
• [Link]: name (or path) of the file to be opened.
• mode: mode in which you want to open the file (read, write, append,
etc.).
Basic Example: Opening a File
f = open("[Link]", "r")
print(f)
Explanation: This code opens file [Link] in read mode. If the file exists, it
returns a file object connected to that file; if the file does not exist, Python raises
a FileNotFoundError.
Closing a File
The [Link]() method closes the file and releases the system resources. If the
file was opened in write or append mode, closing ensures that all changes are
properly saved.
file = open("[Link]", "r")
# Perform file operations
[Link]()
Checking File Properties
Once the file is open, we can check some of its properties:
f = open("[Link]", "r")
print("Filename:", [Link])
print("Mode:", [Link])
print("Is Closed?", [Link])
[Link]()
print("Is Closed?", [Link])
Output:
Filename: [Link]
Mode: r
Is Closed? False
Is Closed? True
Explanation:
• [Link]: Returns the name of the file that was opened (in this case,
"[Link]").
• [Link]: Tells us the mode in which the file was opened. Here, it’s 'r'
which means read mode.
• [Link]: Returns a boolean value- False when file is currently open
otherwise True.
File Modes in Python
When working with files in Python, the file mode tells Python what kind of
operations (read, write, etc.) you want to perform on the file. You specify the
mode as the second argument to the open() function.
Different File Mode in Python
Mode Description
‘r’ Read-only. Raises I/O error if file doesn't exist.
‘r+’ Read and write. Raises I/O error if the file does not exist.
‘w’ Write-only. Overwrites file if it exists, else creates a new one.
‘w+’ Read and write. Overwrites file or creates new one.
‘a’ Append-only. Adds data to end. Creates file if it doesn't exist.
‘a+’ Read and append. Pointer at end. Creates file if it doesn't exist.
‘rb’ Read in binary mode. File must exist.
‘rb+’ Read and write in binary mode. File must exist.
‘wb’ Write in binary. Overwrites or creates new.
‘wb+’ Read and write in binary. Overwrites or creates new.
Mode Description
‘ab’ Append in binary. Creates file if not exist.
‘ab+’ Read and append in binary. Creates file if it does not exist.
we have a file named [Link] with the content: Hello World
1. Read Mode ('r')
This mode allows you to open a file for reading only. If the file does not exist, it
will raise a FileNotFoundError.
Example: In this example, a file named '[Link]' is opened in read mode
('r'), and its content is read and stored in the variable 'content' using a 'with'
statement, ensuring proper resource management by automatically closing the
file after use.
with open('[Link]', 'r') as file:
content = [Link]()
Output: Hello World
2. Write Mode ('w')
Opens the file for writing only. If the file exists, its content is deleted. If not, a
new file is created.
Example: In this example, a file named '[Link]' is opened in write mode
('w'), and the string 'Hello, world!' is written into the file.
with open('[Link]', 'w') as file:
[Link]('Hello, Navkis!')
Output (file content after writing):
Hello, world!
Note: If you were to open the file "[Link]" after running this code, you
would find that it contains the text "Hello, Navkis!" as the previous content
"Hello World" will be deleted.
3. Append Mode ('a')
Opens the file to add content at the end without deleting existing data. If the file
doesn’t exist, it creates a new one.
Example: In this example, a file named '[Link]' is opened in append mode
('a'), and the string '\n This is a new line.' is written to the end of the file.
with open('[Link]', 'a') as file:
[Link]('\nThis is a new line.')
Output:
Hello, World!
This is a new line
The code will then write the string "\nThis is a new line." to the file,
appending it to the existing content or creating a new line if the file is empty.
4. Binary Mode ('b')
Used for non-text files like images or audio. Always combined with 'r', 'w', or 'a
Example: In this example, a file named '[Link]' is opened in binary read
mode ('rb'). The binary data is read from the file using the 'read()' method and
stored in the variable 'data'.
with open('[Link]', 'rb') as file:
data = [Link]()
# Process the binary data
5. Read and Write Mode ('r+')
Opens the file for both reading and writing. Starts at the beginning of the file.
Raises FileNotFoundError if the file doesn’t exist.
with open('[Link]', 'r+') as file:
content = [Link]()
[Link]('\nThis is a new line.')
6. Write and Read Mode ('w+')
This mode allows you to open a file for both reading and writing. If the file
already exists, it will truncate the file to zero length. If the file does not exist, it
will create a new file.
Example: In this example, a file named '[Link]' is opened in write and
read mode ('w+').
with open('[Link]', 'w+') as file:
[Link]('Hello, Hassan!')
[Link](0)
content = [Link]()
Turning a file into a list of lines
Read data from file and store all content into a list of lines, then sort the list, and
write the sorted list back to another file:
with open(“[Link]”, “r”) as input_file:
all_lines=input_file.readLines()
all_lines.sort()
with open(“[Link]”, “w”) as output_file:
for line in all_lines:
output_file.write(line)
The readLines method in this 2 reads all the lines and returns a list of the
strings.
Reading the whole file at once
Read the complete contents of the file into a string, and then to use string
processing to work with the contents.
Split method on strings which can break a sting into words.
with open(“[Link]”) as f:
content = [Link]()
words=[Link]()
print(“There are (0) words in the file.”.format(len(words)))
Note: here we left out the “r” mode in line 1. By default, if we don’t supply the
mode, python opens the file for reading.
Working with binary files
Directories:
Files on non-volatile storage media are organized by a set of rules known
as a file system. File systems are made up of files and directories, which are
containers for both files and other directories.
When we create a new file by opening it and writing the new file goes in the
current directory. Similarly when we open a file for reading, python looks for it
in the current directory.
If we want to open a file somewhere else, we have to specify the path to the file,
which is the name of the directory or folder where the file is located.
In Windows path might be “C:/temp/[Link]” or C:\\temp\\[Link]”.
Since backslashes are used to escape things like newlines and tabs, we need to
write two backslashes in a literal string to get one.
Fetching something from the web
Copies the contents at some web URL to a local file.
import [Link]
url= “http: //[Link]/public/rfc/txt/[Link]"
destination_filename = “rfc793,txt”
[Link](url, destination_filename)