py unit-4
py unit-4
, Basmath
Unit-IV
Exceptions and data structures
Data Structures:-
Array:- Unlike arrays, a single list can store elements of any data type and does everything
an array does. We can store an integer, a float and a string inside the same list. So, it is
more flexible to work with.
[10, 20, 30, 40, 50] is an example of what an array would look like in Python, but it is actually
a list.
Create an Array
We can create a Python array with comma separated elements between square brackets [].
We can access individual elements of an array using index inside square brackets [].
Array Index
Index is the position of element in an array. In Python, arrays are zero-indexed. This means,
the element's position starts with 0 instead of 1.
Python's list implementation of array allows us to delete any elements from an array using
del operator.
Similarly, we can also use remove() and pop() methods to remove elements in an array.
We can change values of elements within an array using indexing and assignment operator
(=). We select the position of any element using indexing and use assignment operator to
provide a new value for the element.
When we print the elements of fruits it shows that Pineapple replaced Banana at index 1.
We also changed last element of fruits to Guava, using negative indexing.
Thus, we can change and update the elements of array easily.
List:-
Python offers a range of compound datatypes often referred to as sequences. List is one of
the most frequently used and very versatile datatype used in Python .
create a list
In Python programming, a list is created by placing all the items (elements) inside a square
bracket [ ], separated by commas.
It can have any number of items and they may be of different types (integer, float, string etc.).
# empty list
my_list = []
Prof. Gajendra D. Dhole 2
MIT College of C.S. & I.T., Basmath
# list of integers
my_list = [1, 2, 3]
# nested list
my_list = ["mouse", [8, 4, 6], ['a']]
There are various ways in which we can access the elements of a list.
List Index
We can use the index operator [] to access an item in a list. Index starts from 0. So, a list
having 5 elements will have index from 0 to 4.
Trying to access an element other that this will raise an IndexError. The index must be an
integer. We can't use float or other types, this will result into TypeError.
>>>my_list=['p','r','o','b','e']
>>>print(my_list(0))
p
>>> print(my_list[2])
o
>>> print(my_list[4])
e
>>> print(my_list[4,0])
>>> n_list=["Happy",[2,0,1,5]]
>>> print(n_list[0][1])
a
>>> print(n_list[1][3])
5
Python allows negative indexing for its sequences. The index of -1 refers to the last item, -2
to the second last item and so on.
>>>my_list=['p','r','o','b','e']
>>>print(my_list[-1])
e
>>>print(my_list[-5])
p
We can access a range of items in a list by using the slicing operator (colon).
>>> my_list=['p','r','o','g','r','a','m','z']
>>> print(my_list[2:5])
['o', 'g', 'r']
>>> print(my_list[:-5])
['p', 'r', 'o']
>>> print(my_list[5:])
['a', 'm', 'z']
>>> print(my_list[:])
['p', 'r', 'o', 'g', 'r', 'a', 'm', 'z']
List are mutable, meaning, their elements can be changed unlike string or tuple.
We can use assignment operator (=) to change an item or a range of items.
>>> odd=[2,4,6,8]
>>> odd
[2, 4, 6, 8]
>>> odd[0]=1
>>> odd
[1, 4, 6, 8]
>>> odd[1:4]=[3,5,7]
>>> odd
[1, 3, 5, 7]
>>>
We can add one item to a list using append() method or add several items using extend()
method.
odd = [1, 3, 5]
odd.append(7)
# Output: [1, 3, 5, 7]
Prof. Gajendra D. Dhole 4
MIT College of C.S. & I.T., Basmath
print(odd)
We can also use + operator to combine two lists. This is also called concatenation.
The * operator repeats a list for the given number of times.
odd = [1, 3, 5]
# Output: [1, 3, 5, 9, 7, 5]
print(odd + [9, 7, 5])
Furthermore, we can insert one item at a desired location by using the method insert() or
insert multiple items by squeezing it into an empty slice of a list.
>>> odd=[1,9]
>>> odd
[1, 9]
>>> odd.insert(1,3)
>>> odd
[1, 3, 9]
>>> odd[2:2]=[5,7]
>>> odd
[1, 3, 5, 7, 9]
>>>
We can delete one or more items from a list using the keyword del. It can even delete the list
entirely.
>>> my_list=['p','r','o','g','r','a','m','z']
>>> my_list
['p', 'r', 'o', 'g', 'r', 'a', 'm', 'z']
>>> del my_list[2]
>>> my_list
['p', 'r', 'g', 'r', 'a', 'm', 'z']
>>> del my_list[1:5]
>>> my_list
['p', 'm', 'z']
>>> del my_list
>>> my_list
We can use remove() method to remove the given item or pop() method to remove an item
at the given index.
The pop() method removes and returns the last item if index is not provided. This helps us
implement lists as stacks (first in, last out data structure).
>>> my_list=['p','r','o','g','r','a','m','z']
>>> my_list.remove('p')
>>> print(my_list)
['r', 'o', 'g', 'r', 'a', 'm', 'z']
>>> print(my_list.pop(1))
o
>>> print(my_list)
['r', 'g', 'r', 'a', 'm', 'z']
>>> print(my_list.pop())
z
>>> print(my_list)
['r', 'g', 'r', 'a', 'm']
Finally, we can also delete items in a list by assigning an empty list to a slice of elements.
Methods that are available with list object in Python programming are tabulated below.
They are accessed as list.method(). Some of the methods have already been used above.
Python dictionary is an unordered collection of items. While other compound data types have
only value as an element, a dictionary has a key: value pair.
Dictionaries are optimized to retrieve values when the key is known.
While values can be of any data type and can repeat, keys must be of immutable type
(string, number or tuple with immutable elements) and must be unique.
# empty dictionary
my_dict = {}
# using dict()
my_dict = dict({1:'apple', 2:'ball'})
As you can see above, we can also create a dictionary using the built-in function dict()
While indexing is used with other container types to access values, dictionary uses keys.
Key can be used either inside square brackets or with the get() method.
The difference while using get() is that it returns None instead of KeyError, if the key is not
found.
. >>> my_dict={'Name':'Jack','Age':26}
>>> print(my_dict)
{'Age': 26, 'Name': 'Jack'}
>>> print(my_dict['Name'])
Jack
>>> print(my_dict.get('Age'))
26
>>> print(my_dict.get('Address'))
None
>>> print(my_dict['Address'])
Dictionary are mutable. We can add new items or change the value of existing items using
assignment operator.
If the key is already present, value gets updated, else a new key: value pair is added to the
dictionary.
>>> my_dict={'Name':'Jack','Age':26}
>>> print(my_dict)
{'Age': 26, 'Name': 'Jack'}
>>> my_dict['Age']=30
>>> print(my_dict)
{'Age': 30, 'Name': 'Jack'}
>>> my_dict['Address']='Nanded'
>>> print(my_dict)
{'Age': 30, 'Name': 'Jack', 'Address': 'Nanded'}
>>>
We can remove a particular item in a dictionary by using the method pop(). This method
removes as item with the provided key and returns the value.
The method, popitem() can be used to remove and return an arbitrary item (key, value) form
the dictionary. All the items can be removed at once using the clear() method.
We can also use the del keyword to remove individual items or the entire dictionary itself.
>>> sqr={1:1,2:4,3:9,4:16,5:25}
>>> print(sqr)
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
>>> print(sqr.pop(4))
16
>>> print(sqr)
{1: 1, 2: 4, 3: 9, 5: 25}
>>> print(sqr.popitem())
(1, 1)
>>> print(sqr)
{2: 4, 3: 9, 5: 25}
>>> del sqr[5]
>>> print(sqr)
{2: 4, 3: 9}
>>> del sqr
>>> print(sqr)
>>> sqr.clear()
>>> print(sqr)
{}
Methods that are available with dictionary are tabulated below. Some of them have already
been used in the above examples.
Method Description
clear() Remove all items form the dictionary.
copy() Return a shallow copy of the dictionary.
fromkeys(seq[, Return a new dictionary with keys from seq and value equal to v (defaults
v]) to None).
get(key[,d]) Return the value of key. If key doesnot exit, return d (defaults to None).
items() Return a new view of the dictionary's items (key, value).
keys() Return a new view of the dictionary's keys.
Remove the item with key and return its value or d if key is not found. If d
pop(key[,d])
is not provided and key is not found, raises KeyError.
Remove and return an arbitary item (key, value). Raises KeyError if the
popitem()
dictionary is empty.
If key is in the dictionary, return its value. If not, insert key with a value of
setdefault(key[,d])
d and return d (defaults to None).
Update the dictionary with the key/value pairs from other, overwriting
update([other])
existing keys.
values() Return a new view of the dictionary's values
Exceptions Handling:-
Python provides a standard mechanism called exception handling that allows programmers
to deal with these kinds of run-time errors and many more. Rather than always terminating
the program’s execution, a program can detect the problem and execute code to correct the
issue or manage it in other ways.
An exception is a special object that the executing program can create when it encounters
an extraordinary situation. Such a situation almost always represents a problem, usually
some sort of run-time error.
In Python, exceptions can be both intercepted and triggered by our programs. They are
processed by two new statements we'll study in this chapter:
try
Catches exceptions raised by Python or a program
raise
With a few exceptions (pun intended), we'll find that exception handling is simple in Python
Error handling
Python raises exceptions when it detects errors in programs at runtime; you can either catch
and respond to the errors internally in your programs or ignore the exception. If ignored,
Python's default exception-handling behavior kicks in; it kills the program and prints an
error message showing where the error occurred.
Event notification
Exceptions can also signal a valid condition, without having to pass result flags around a
program or test them explicitly. For instance, a search routine might raise an exception on
success, rather than return an integer 1.
Special-case handling
Sometimes a condition may happen so rarely that it's hard to justify convoluting code to
handle it. You can often eliminate special-case code by handling unusual cases in exception
handlers instead.
Unusual control-flows
And finally, because exceptions are a type of high-level goto, you can use them as the basis
for implementing exotic control flows. For instance, although back-tracking is not part of
the language itself, it can be implemented in Python with exceptions and a bit of support
logic to unwind assignments.
Exception Basics
Python exceptions are a high-level control flow device. They may be raised either by Python
or by our programs; in both cases, they may be caught by try statements. Python try
statements come in two flavors—one that handles exceptions and one that executes
finalization code whether exceptions occur or not.
try/except/else
The try is another compound statement; its most complete form is sketched below. It starts
with a try header line followed by a block of indented statements, then one or more optional
except clauses that name exceptions to be caught, and an optional else clause at the end:
try:
<statements> # run/call actions
except <name>:
<statements> # if 'name' raised during try block
except <name>, <data>:
<statements> # if 'name' raised; get extra data
else:
<statements> # if no exception was raised
Here's how try statements work. When a try statement is started, Python marks the current
program context, so it can come back if an exception occurs. The statements nested under
the try header are run first; what happens next depends on whether exceptions are raised
while the try block's statements are running or not:
try/finally
The other flavor of the try statement is a specialization and has to do with finalization
actions. If a finally clause is used in a try, its block of statements are always run by
Prof. Gajendra D. Dhole 10
MIT College of C.S. & I.T., Basmath
Python "on the way out," whether an exception occurred while the try block was running
or
not:
try:
<statements>
finally:
<statements> # always run "on the way out"
Raising Exceptions:-
To trigger exceptions, you need to code raise statements. Their general form is simple: the
word raise followed by the name of the exception to be raised. You can also pass an extra
data item (an object) along with the exception, by listing it after the exception name. If extra
data is passed, it can be caught in a try by listing an assignment target to receive it:
except
name, data:
raise <name> # manually trigger an exception
raise <name>, <data> # pass extra data to catcher too
So what's an exception name? It might be the name of a built-in exception from the built-in
scope (e.g., IndexError), or the name of an arbitrary string object you've assigned in your
program. It can also reference a class or class instance; this form generalizes raise
statements, but we'll postpone this topic till later in this chapter. Exceptions are identified by
objects, and at most one is active at any given time. Once caught by an except clause, an
exception dies (won't propagate to another try), unless reraised by a raise or error.
The following may not be the most useful Python code ever penned, but it makes the point—
raising the built-in IndexError exception:
>>> try:
... raise IndexError # Trigger exception manually
... except IndexError:
... print('got exception')
...
got exception
As usual, if they’re not caught, user-triggered exceptions are propagated up to the top-level
default exception handler and terminate the program with a standard error message:
The as is optional in a try handler (if it’s omitted, the instance is simply not assigned to a
name), but including it allows the handler to access both data in the instance and methods in
the exception class.
This model works the same for user-defined exceptions we code with classes—the following,
for example, passes to the exception class constructor arguments that become available in
the handler through the assigned instance:
Because this encroaches on the next chapter’s topic, though, I’ll defer further details until
then. Regardless of how you name them, exceptions are always identified by class instance
objects, and at most one is active at any given time. Once caught by an except clause
anywhere in the program, an exception dies (i.e., won’t propagate to another try), unless it’s
reraised by another raise statement or error.
Error processing:-
Error reporting and processing through exceptions is one of python’s key features. Care
must be taken when handling exceptions to ensure proper application cleanup while
maintaining useful error reporting.
Error reporting and processing through exception is one of python’s key feature. Unlike C,
where the common way to report errors is through function return values that then have to
be checked on every invocation, in python a programmer can raise an exception at any point
in a program. When the exception is raised, program execution is interrupted as the
interpreter searches back up the
Making statements
Writing lists:-
The list is a most versatile datatype available in Python which can be written as a list of
comma-separated values (items) between square brackets. Important thing about a list is
that items in a list need not be of the same type.
Similar to string indices, list indices start at 0, and lists can be sliced, concatenated and so
on.
To access values in lists, use the square brackets for slicing along with the index or indices
to obtain value available at that index. For example −
#!/usr/bin/python
list1[0]: physics
list2[1:5]: [2, 3, 4, 5]
Updating Lists
You can update single or multiple elements of lists by giving the slice on the left-hand side of
the assignment operator, and you can add to elements in a list with the append() method. For
example −
#!/usr/bin/python
To remove a list element, you can use either the del statement if you know exactly which
element(s) you are deleting or the remove() method if you do not know. For example −
#!/usr/bin/python
Example:
num = [1, 2, 3]
# add an item
num.append(8)
print(num) # [1, 2, 3, 8]
my_lst = []
for i in range(5):
my_lst.append(i * i)
You can make a new list by adding two or more lists together.
lst1 = [1, 2, 3]
lst2 = [6, 7, 8, 9]
lst3 = lst1 + lst2
print(lst3) # [1, 2, 3, 6, 7, 8, 9]
The result from "add" operation is a new list (lst3). The existing lists (lst1 and lst2) are not
changed. Compare to append(), which modifies an existing list object.
Multiplying a list with a number creates a new list that repeats the existing list:
my_lst = [1,8]
result = my_lst * 3
print(result) # [1, 8, 1, 8, 1, 8]
Restricting lists:-
Sometimes there is a requirement to restrict the list size to a particular number and remove
all the elements from list which occur after a certain number as decided as list size.
pop function can be repeated a number of times till size of the list reaches the threshold
required as the size of the list.
k =5
n = len(test_list)
for i in range(0, n - k ):
test_list.pop()
del operator can be used to delete all the elements that appear after the specific index,
which is handled by the list slicing technique.
# size desired
k =5
# printing result
print ("The truncated list is : " + str(test_list))
# initializing list
test_list = [1, 4, 5, 8, 3, 10]
# printing value
print ("The value to be attached to each value : " + str(val))
# printing result
print ("The modified attached list is : " + str(res))
output:-