Python 102: Introduction to Data Structures and Algorithms in Python
Tags: beginners, python, codenewbie, algorithms
Published: 2022-02-25 09:40:15

Python has been widely used in different fields such as web development, game development, data science, AI and ML among others. These uses are made possible by the provision of data. In order for a data scientist to design and solve machine learning models in a more effective way, knowledge of data structures and algorithms is key.
In this article, we'll take a look at different types of data structures and algorithms in python.

1. What is Data Structure and Algorithm?
2. Types of Data structures
      1. Built-in Data Structures
      1. User defined data structures
3. Types of Algorithms
     1. Tree Traversal Algorithms
     2. Sorting Algorithm
     3. Searching Algorithm

# Built-in Data Structures
1. List

 A list is defined using square brackets and holds data that is separated by commas. The list is mutable and ordered. It can contain a mix of different data types.

```py
months = ['january','february','march','april','may','june','july','august','september','october','november','december']
print(months[0]) # print the elemment with index 0
print(months[0:7]) # all the elements from index 0 to 6.
months[0] = 'birthday' # exchange the value in index 0 with the word birthday
print(months)
```
Output

`
january
['january', 'february', 'march', 'april', 'may', 'june', 'july']
['birthday', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december']
`
2. Tuple

A tuple is another container. It is a data type for immutable ordered sequences of elements. Immutable because you can’t add and remove elements from tuples, or sort them in place.

```py
length, width, height = 7, 3, 1 # we can assign multiple varibles in one shot
print("The dimensions are {} x {} x {}".format(length, width, height))
```
Output

`The dimensions are 7 x 3 x 1`

3. Set

Set is a mutable and unordered collection of unique elements. It can permit us to remove duplicate quickly from a list.

```py
numbers = [1, 2, 6, 3, 1, 1, 5] 

unique_nums = set(numbers)
print(unique_nums)


artist = {'Chagall', 'Kandinskij', 'Dalí', 'da Vinci', 'Picasso', 'Warhol', 'Basquiat'}

print('Turner' in artist) # check if there is Turner in the set artist
artist.add('Turner')
print(artist.pop()) #remove the last item
```
Output

`{1, 2, 3, 5, 6}
False
Basquiat`

4. Dictionary

Dictionary is a mutable and unordered data structure. It permits storing a pair of items (i.e. keys and values).
As the example below shows, in the dictionary, it is possible to include containers into other containers to create compound data structures.

```py
music = { 'jazz': {"Coltrane": "In a Sentimental Mood",
                          "M.Davis":"Blue in Green" ,
                          "T.Monk":"Don't Blame Me"},
            "classical" : {"Bach": "Cello Suit",
                        "Mozart": "Lacrimosa",
                        "Satie": "Gymnopédie"}}

print(music["jazz"]["Coltrane"]) # we select the value of the key Coltrane
print(music["classical"]["Mozart"])
```
Output

'In a Sentimental Mood
Lacrimosa'

# User-Defined Data Structures

1. Stack using arrays

The stack is a linear data structure where elements are arranged sequentially. It follows the mechanism L.I.F.O which means last in first out. So, the last element inserted will be removed as the first. The operations are:
Push → inserting an element into the stack
Pop → deleting an element from the stack
The conditions to check:
overflow condition → this condition occurs when we try to put one more element into a stack that is already having maximum elements.
underflow condition →this condition occurs when we try to delete an element from an empty stack.

```py
class mystack:
    
    def __init__(self):
        self.data =[]
        
    def length(self): #length of the list
        return len(self.data)
    
    def is_full(self): #check if the list is full or not
        if len(self.data) == 5:
            return True
        else:
            return False
        
    def push(self, element):# insert a new element
        if len(self.data) < 5:
            self.data.append(element)
        else:
            return "overflow"
        
    def pop(self): # # remove the last element from a list
        if len(self.data) == 0:
            return "underflow"
        else:
            return self.data.pop()

a = mystack() # I create my object
a.push(10) # insert the  element
a.push(23)
a.push(25)
a.push(27)
a.push(11)
print(a.length())
print(a.is_full())
print(a.data)
print(a.push(31)) # we try to insert one more element in the list - the output will be overflow
print(a.pop())
print(a.pop())
print(a.pop())
print(a.pop())
print(a.pop())
print(a.pop()) # try to delete an element in a list without elements - the output will be underflow
```
Output

'5
True
[10, 23, 25, 27, 11]
overflow
11
27
25
23
10
underflow'

2. Queue using arrays

The queue is a linear data structure where elements are in a sequential manner. It follows the F.I.F.O mechanism that means first in first out. Think when you go to the cinema with your friends, as you can imagine the first of you that give the ticket is also the first that step out of the line. The mechanism of the queue is the same.
Below the aspects that characterize a queue.
Two ends:
front → points to starting element
rear → points to the last element
There are two operations:
enqueue → inserting an element into the queue. It will be done at the rear.
dequeue → deleting an element from the queue. It will be done at the front.
There are two conditions:
overflow → insertion into a queue that is full
underflow → deletion from the empty queue

```py
class myqueue:
    
    def __init__(self):
        self.data = []
        
    def length(self):
        return len(self.data)
    
    def enque(self, element): # put the element in the queue
        if len(self.data) < 5:
            return self.data.append(element)
        else:
            return "overflow"
        
    def deque(self): # remove the first element that we have put in queue
        if len(self.data) == 0:
             return "underflow"
        else:
            self.data.pop(0)
            
b = myqueue()
b.enque(2) # put the element into the queue
b.enque(3)
b.enque(4)
b.enque(5)
print(b.data)
b.deque()# # remove the first element that we have put in the queue
print(b.data)
```
Output

'[2, 3, 4, 5]
[3, 4, 5]'