Data Structures in Python

We deal with a lot of data everyday. It includes the bill of the things bought from grocery shops, the whatsapp text with your contacts, etc. In a program, all these are managed with the help of the data structures.

We will discuss the built-in data structures in this article along with some light on the derived ones. Let’s begin!

Introduction to Data Structures in Python

As discussed above, the data structures are the organizers and storers of data in an efficient manner so that they can be modified and accessed in the future. To suit different uses, there are different data structures in Python. These can be mainly classified into two types:

1. Python Built-in data structures: These are the data structures that come along with Python and can be implemented same as primitive data types like integers, etc. These can be further classified into:

a. Lists
b. Sets
c. Tuples
d. Dictionaries

2. Python User-defined data structures: These data structures are the ones built using the built-in data structures and have their own properties. Based on these features, these are used in suitable situations. These can be subdivided into:

a. Stacks
b. Queues
c. Linked Lists
d. Hash Maps
e. Trees
f. Graphs

In the next few sections we will discuss the built-in data structures in detail.

1. Lists in Python

Lists are the containers of values of different data types. These store the data in a continuous manner in the memory. These are mainly used in situations where there is a need to access the data frequently, which can be done easily using indexing.

We will start with creation and look into many other operations that can be done on lists now.

a. Creating Python lists

Elements in a list are enclosed with square brackets (‘[ ]’) with each separated by comma. It can contain any type of value including lists. An example of creating a list is shown below.

Example of creating a list in Python

list1=[] # creating an empty list
list2=[1,2.4,'abc',(1,2),[6,78,9]] # creating a list of different values

print("The type of",list1,"is:",type(list1))

print("The type of",list2,"is:",type(list2))

Output:

The type of [] is: <class ‘list’>

The type of [1, 2.4, ‘abc’, (1, 2), [6, 78, 9]] is: <class ‘list’>

b. Accessing an element from the Python list

We can access the elements of the list using indexing. In Python, the indexing of lists starts from 0. So, to access the first element you have to specify the index as ‘0’.

We can also access using negative indexes, where the right most value is of index ‘-1’ and it keeps reducing on moving to the left.

Examples of accessing elements of a list in python:

list_1=[1,3,5.6,'a',"PythonGeeks",0.4]
print(list_1[3]) # accessing the 4th element

print(list_1) # accessing the whole list

print(list_1[-2]) # printing the last 2nd element

Output:

a

[1, 3, 5.6, ‘a’, ‘PythonGeeks’, 0.4]

PythonGeeks

However, if we give the index more than the limit then we get an error. And the maximum is one less than the length of the list. We also get errors if we give a noninteger as an index, say float.

Example of getting errors on wrong indexing:

print(list_1[6])

print(list_1[3.0])

Output:

Traceback (most recent call last):
File “<pyshell#4>”, line 1, in <module>
print(list_1[6])
IndexError: list index out of range

Traceback (most recent call last):
File “<pyshell#5>”, line 1, in <module>
print(list_1[3.0])
TypeError: list indices must be integers or slices, not float

c. Slicing the list in Python

We can get more than one element from a list by slicing. We use the indexing of ‘i:j’ to get the elements from ith index to jth index (jth exclusive). Also, We can give negative indexing. For example,

Example of slicing list:

list_1=[1,3,5.6,'a',"PythonGeeks",0.4]

print("list_1[2:5] =",list_1[2:5]) # slicing 3rd to 5th element

print("list_1[:] =",list_1[:]) # getting entire list

print("list_1[-5:-2] =",list_1[-5:-2]) # slicing last 5th to 3rd element

print("list_1[3:] =",list_1[3:]) # slicing all elements after 3rd one

print("list_1[-3:] =",list_1[-3:]) # slicing all elements after last 3rd one

print("list_1[:2] =",list_1[:2]) # slicing all elements till 2nd one

print("list_1[:-2] =",list_1[:-2])# slicing all elements till last 2nd one

Output:

list_1[2:5] = [5.6, ‘a’, ‘PythonGeeks’]

list_1[:] = [1, 3, 5.6, ‘a’, ‘PythonGeeks’, 0.4]

list_1[-5:-2] = [3, 5.6, ‘a’]

list_1[3:] = [‘a’, ‘PythonGeeks’, 0.4]

list_1[-3:] = [‘a’, ‘PythonGeeks’, 0.4]

list_1[:2] = [1, 3]

list_1[:-2] = [1, 3, 5.6, ‘a’]

d. Modifying and deleting elements from Python List

We can modify or delete an element or a set of elements of a list. This is again done by indexing. Examples are shown below.

Example of modifying and deleting an element of a list:

list1=[3,5.7,'y','Python',67,'7.9']

list1[1]=1.2 # reassigning the 2nd element
print(list1)

del list1[2] # deleting the 3rd element
print(list1)

Output:

[3, 1.2, ‘y’, ‘Python’, 67, ‘7.9’]

[3, 1.2, ‘Python’, 67, ‘7.9’]

We can modify and delete a set of values also using the concept of slicing.

Example of modifying and deleting elements of a list:

list1[1:3]=[3.5,8]
print(list1)

del list1[2:5] #deleting 3rd to 5th elements
print(list1)

Output:

[3, 3.5, 8, 67, ‘7.9’]

[3, 3.5]

We can also modify and delete the whole list. On deleting the list, if we try to access it again we get the NameError.

Example of modifying and deleting the list:

list1=[1,2,'p'] # modifying the whole list
print(list1)

del list1 #deleting the whole list
print(list1)

Output:

[1, 2, ‘p’]

Traceback (most recent call last):
File “<pyshell#12>”, line 1, in <module>
print(list1)
NameError: name ‘list1’ is not defined

e. Addition and multiplication of the lists in Python

We can add two lists using the ‘+’ operator and multiply with a positive integer using ‘*’ operator. Using these operators concatenates the elements of one list at the end of the other. For example,

Example of addition and multiplication of the list:

list1=[1,9.0,'t',4.5]
list2=['a',5.9]
list1+list2

list2*3

Output:

[1, 9.0, ‘t’, 4.5, ‘a’, 5.9]

[‘a’, 5.9, ‘a’, 5.9, ‘a’, 5.9]

Python Built-in Functions

There are built-in functions in Python for lists. We will discuss some common ones here.

1. append(): This function is used to add an element to the list at the end.

2. insert(): This function takes the element and the index as arguments and inserts the value in the specified location.

3. pop(): This function deletes the last element if no index passes or deletes the element at that index and returns it.

4. remove(): This function removes the specified value from the list.

5. len(): This function returns the length or number of elements in the list

6. sort(): This arranges the elements of the list in ascending or descending order

7. index(): This is used to find the index of the element passed

8. count(): This finds the number of times the value occurs in a list

Example of using built-in functions on list:

list1=[1,7,3,'a','x','p',4.6,0.2,3.7]

list1.append(2.3)
list1

list1.insert(2,0.9)
list1

list1.pop()
list1

list1.remove('x')
list1

list1.pop(4)
list1

len(list1)

list2=[1,5,3,9,0]
list2.sort()
list2

list2.index(3)

list2.append(3)

list2.count(3)

list2.sort(reverse=True)
list2

Output:

[1, 7, 3, ‘a’, ‘x’, ‘p’, 4.6, 0.2, 3.7, 2.3]

[1, 7, 0.9, 3, ‘a’, ‘x’, ‘p’, 4.6, 0.2, 3.7, 2.3]

2.3
[1, 7, 0.9, 3, ‘a’, ‘x’, ‘p’, 4.6, 0.2, 3.7]

[1, 7, 0.9, 3, ‘a’, ‘p’, 4.6, 0.2, 3.7]

‘a’
[1, 7, 0.9, 3, ‘p’, 4.6, 0.2, 3.7]

8

[0, 1, 3, 5, 9]

2

2

[9, 5, 3, 3, 1, 0]

List Comprehension in Python

List comprehension is a way to create a list in a simple, and efficient way. The syntax of list comprehension is:

[expression(x) for x in list]

An example of creating a new list containing squares of the elements of the list using list comprehension is shown below.

Example of Python list comprehension:

list1=[1,-2,3,-4,5]
list2=[x**2 for x in list1]
print(list2)

Output:

[1, 4, 9, 16, 25]

2. Tuples in Python

A tuple is also a collection of elements of different data types. The difference between a tuple and a list is that lists are mutable whereas tuples are not.

a. Creating Python Tuples

The elements of a tuple are enclosed by round brackets with each element separated by a comma. For example,

Example of creating a tuple in Python:

tup=(1,2,'a',4.5,[9,0,7],('s','r'))
print("The type of ",tup,"is:",type(tup))

Output:

The type of (1, 2, ‘a’, 4.5, [9, 0, 7], (‘s’, ‘r’)) is: <class ‘tuple’>

However, to create a tuple with one element, we need to add a comma after that element. Or else, it will be treated as a primitive data type (int, str, etc.).

Example of creating a tuple with single element:

tup2=(2)
print("The type of ",tup2,"is:",type(tup2))

tup3=(2,)
print("The type of ",tup3,"is:",type(tup3))

Output:

The type of 2 is: <class ‘int’>

The type of (2,) is: <class ‘tuple’>

b. Accessing elements of Python Tuple

We can access the elements of a tuple using indexing, same as the case of the list. Examples of indexing to get one or more than one element is shown below.

Example of accessing the elements of a tuple using indexing

tup1=(1,2,'a',4.5)
print(tup1[0]) #accessing the first element

print(tup1[-2]) # accessing the last 2nd element

print(tup1[1:3]) # accessing 2nd to 3rd element

print(tup1[-4:-1]) # accessing last 4th to 2nd elements

print(tup1[2:]) # accessing all the elements from the 3rd element

print(tup1[:-1]) # accessing all the elements till the last element

Output:

1

a

(2, ‘a’)

(1, 2, ‘a’)

(‘a’, 4.5)

(1, 2, ‘a’)

c. Reassigning and Deleting elements of tuples in Python

Tuples do not allow you to change or delete a particular element of a tuple. When we try adding/deleting an element, we get an error. This is shown in the below example.

Example of getting an error on changing or deleting a value:

tup=(1,4,'a',9.0)
tup[3]=8

del tup[2]

Output:

Traceback (most recent call last):
File “<pyshell#1>”, line 1, in <module>
tup[3]=8
TypeError: ‘tuple’ object does not support item assignment

Traceback (most recent call last):
File “<pyshell#2>”, line 1, in <module>
del tup[2]
TypeError: ‘tuple’ object doesn’t support item deletion

Idea of immutability in Python

The immutability of the tuple actually applies to the id of the value of each element of the tuple. When we try to modify the value of a variable, the id of the variable changes to that of the new value.

Every unique element of a tuple has its own id, which represents the memory location of that element. The elements with the same value have the same id. This is shown below.

Example of checking id of the elements in a Python tuple:

tup=(1,’a’,1,7.6,[1.2,3.4])
print(id(tup[0]) ==id(tup[2])) #1st and 3rd elements have same value
print(id(tup[1])==id(tup[4])) #2nd and 5th elements have different values

Output:

True
False

When we try to modify a value of a tuple, we try to change the ids of the elements of the tuple. So, we are allowed to do that. But we can modify a mutable element like a list in a tuple, as the list’s id does not change. This is shown below.

Example of showing that id of the list in a tuple does not change on modifying it :

tup=(1,'a',1,7.6,[1.2,3.4])
id(tup[-1])
tup[-1].append(4)
print("Id of the list inside the tuple after appending:")
id(tup[-1])
tup

Output:

2723740502464
Id of the list inside the tuple after appending:
2723740502464
(1, ‘a’, 1, 7.6, [1.2, 3.4, 4])

d. Adding Tuples in Python

However, you can append a set of values using the ‘+’ operator on a tuple. For example,

Example of appending two tuples:

tup1=(1,2,39)
tup1=tup1+('a','b')
print(tup1)

Output:

(1, 2, 39, ‘a’, ‘b’)

e. Changing Python tuple value by using list():

We can also change the value of a tuple by converting it into a list. Then changing the value and converting it back to the tuple. For example,

Example of changing value of a tuple by using list:

tup=(1,2,3,4,5)

list1=list(tup)
list1[4]=6

tup=tuple(list1)
tup

Output:

(1, 2, 3, 4, 6)

f. Tuple packing and unpacking in Python

We can create a set of elements as a tuple without using parentheses and this is called packing. We can also split the elements of a tuple by assigning the values to the same number of variables and this is called unpacking. To understand this further, look at the below example.

Example of packing and unpacking tuples:

tup=1,2,3 #packing
print("The type of ",tup,"is:",type(tup))

a,b,c=tup #unpacking
print(a)
print(b)
print(c)

Output:

The type of (1, 2, 3) is: <class ‘tuple’>
1
2
3

Other built-in functions in Python

We can use built-in functions that are used for a list like len(), index(),etc. But we cannot use the ones that modify the list like append(), pop(). Below examples show this.

Example of using built-in functions on tuples:

tup=(9,6,'g','Python',7.4)
print(len(tup))
print(tup.index('g'))

print(tup.count('a'))

Output:

5

2

0

3. Sets in Python

Sets are again a collection of elements. But the difference from the above two is that sets do not hold duplicate values and the elements are not ordered. So, we cannot use indexing here. The elements get automatically arranged in ascending order.

a. Creating Sets in Python

The elements of a set are enclosed between curly brackets and are separated by comma. Sets can have a tuple as its element, but not a list because sets are immutable and lists can be changed.

Example of creating a set:

set1={6,'h',(4,0.5),7}
print("The type of ",set1,"is:",type(set1))

set2={4,1,9,0}
print("set2:",set2)

set3={'h',[3,4,6]}

Output:

The type of {(4, 0.5), ‘h’, 6, 7} is: <class ‘set’>

set2: {0, 1, 4, 9}

Traceback (most recent call last):
File “<pyshell#4>”, line 1, in <module>
set3={‘h’,[3,4,6]}
TypeError: unhashable type: ‘list’

Built-in Functions on Python Sets

Python provides some built-in functions to use on sets like :

1. add(): To add an element to a set.

2. pop():To remove the last element if index is not specified and if specified removes elements at that index.

3. clear(): To delete all the elements of a set.

4. len(): To find the length of a set, etc.

5. remove(): This removes the specified element from the set. This function gives an error if the element is not present in the set.

6. discard(): This removes the specified element from the set. But this function does not give an error if the element is not present in the set.

Let us see some examples.

Example of using built-in functions on sets:

set1={1,2,'a','t',7.5}
set2={'g',2,'u',5.6}

set1.add(5)
print(set1)

print(len(set1))

set2.pop()
print(set2)

set1.remove('a')
print(set1)
set1.discard(1)
print(set1)

set1.remove(5.6)

set1.discard(10)
print(set1)

set2.clear()
print(len(set2))

Output:

{‘t’, 1, 2, 5, 7.5, ‘a’}

6\

‘g’

{2, ‘u’, 5.6}

{1, 2, ‘t’, 5, 7.5}

{2, ‘t’, 5, 7.5}

Traceback (most recent call last):
File “<pyshell#50>”, line 1, in <module>
set1.remove(5.6)
KeyError: 5.6

{2, ‘t’, 5, 7.5}

0

Operations on sets in Python

Also we can do operations that we did in mathematics like union(), intersection(), difference(), and the symmetric_difference().

a. The union() returns the combined values from both the sets. And if any value is matched, then it is returned only once.

b. The intersection() returns the set of common values from both the sets. If no common ones, it returns an empty set.

c. The difference() function returns the set of values of the first set that are not there in the second one.

d. The symmetric_difference() returns the set of values from both the sets that are not common to the sets.

Example of using built-in functions on sets:

set1={1,2,'a','t',7.5}
set2={1,'l',6.7,'a'}
print("Union:",set1.union(set2))
print("Intersection:",set1.intersection(set2))
print("Difference:",set1.difference(set2))
print("Symmetric Difference:",set1.symmetric_difference(set2))

Output:

Union: {1, 2, ‘a’, 6.7, 7.5, ‘l’, ‘t’}
Intersection: {1, ‘a’}
Difference: {2, ‘t’, 7.5}
Symmetric Difference: {2, ‘l’, ‘t’, 6.7, 7.5}

3. Dictionaries in Python

Don’t worry these are not like lists! Dictionaries are data structures that store key-value pairs. These can be thought of as real-life dictionaries, where unique words are lapped to their meanings. These keys should be unique and cannot be changed. So we cannot use unhashable/ modifiable data such as a list as key.

a. Creating Python dictionaries

A dictionary uses curly braces to hold its key-values and commas to separate them. For example:

Example of creating a dictionary in Python:

dict1={1:'a',4:'t',8:9}
print("The type of ",dict1,"is:",type(dict1))

Output:

The type of {1: ‘a’, 4: ‘t’, 8: 9} is: <class ‘dict’>

If we try to give the same key again while creating the dictionary, the new value replaces the old one. For example,

Example of creating a dictionary:

dic={1:'a',2:'b',1:'c',4:'t'}
dic

Output:

{1: ‘c’, 2: ‘b’, 4: ‘t’}

b. Accessing elements of Python Dictionary

We can access the elements of a dictionary using the keys. For example,

Example of accessing elements of a dictionary:

print(dict1[8])

print(dict1[4])

Output:

9

t

c. Changing and adding the value of Python Dictionary

We cannot change the keys but we can change the values using the keys. We can add a key-value by assigning the key in the square brackets and equating to the value. For example,

Example of changing values of a dictionary:

dict1={'a':7,'e':4,"y":6,"ab":10}
dict1['ab']=15
print(dict1)

dict1['z']=34
print(dict1)

Output:

{‘a’: 7, ‘e’: 4, ‘y’: 6, ‘ab’: 15}

{‘a’: 7, ‘e’: 4, ‘y’: 6, ‘ab’: 15, ‘z’: 34}

Built-in functions on Python Dictionary:

Python has built-in functions for dictionaries also like:

1. get(): To get a value of the specified key.

2. pop(): Takes a key as an argument, deletes that key-value, and returns the value.

3. popitem(): Deletes the last key-value and returns the key-value pair as dictionary.

4. clear(): To delete all the elements of a dictionary. It keeps the instance of the dictionary, that is we can access the dictionary after clearing. It gives an empty dictionary.

5. keys(): Get all the keys in the dictionary.

6. values(): Get all the values in the dictionary.

7. items(): Get all the key-value pairs.

The examples of these functions are shown below:

Example of using built-in functions on a dictionary in Python:

dict1={1:'a',2:'e',3:'i',4:'o',5:'u'}
print(dict1.get(4))

print(dict1.keys())

print(dict1.values())

print(dict1.items())

var1=dict1.pop(2)
print("The value of var1 is:",var1)

var2=dict1.popitem()
print("The value of var2 is:",var2)

dict1.clear()
dict1

Output:

o

dict_keys([1, 2, 3, 4, 5])

dict_values([‘a’, ‘e’, ‘i’, ‘o’, ‘u’])

dict_items([(1, ‘a’), (2, ‘e’), (3, ‘i’), (4, ‘o’), (5, ‘u’)])

The value of var1 is: e

The value of var2 is: (5, ‘u’)

{}

User-Defined Data Structures in Python

Besides the built-in data structures, we have the derived data structures that are built using the built-in ones. These have their own properties and have a wide range of uses in real world situations. Let us discuss them and their properties in brief.

1. Arrays in Python

These are the data structures similar to lists. The only difference is that these are homogeneous, that is, have the elements of the same data type.

There is a type of array called Matrix which is a 2 dimensional array, with all the elements having the same size.

2. Stacks in Python

These are the data structures that work following the principle of LIFO (Last In First Out).

a. The elements enter and leave at the same node called the top. We can access only the last entered element using the top node.

b. It is built using arrays. We can do operations like push (adding element), pop (deleting element), and accessing elements.

Stack in Python

We can think of push as appending a value to a list and pop is similar to pop in list without any argument. For example,

Example of doing operations of stack using lists:

stack=[1,2,3,4,5]

stack.append(6) #push
stack

stack.pop() #pop
stack

Output:

[1, 2, 3, 4, 5, 6]

6

[1, 2, 3, 4, 5]

c. The top node represents the entire stack, as it holds the pointer to the stack’s current element.

d. It is used for recursive programs, reversal, undo operations, and so on.

3. Queues in Array

These data structures follow the principle of FIFO (First In First Out).

a. The elements enter at one end and leave at the other end. It is similar to the queues we see ATM centres, mess, etc.

b. The two ends are called front/head and back/tail.

c. It is built using arrays. We can do operations like enque (adding element), deque(deleting element), and accessing elements.

Queue in Python

Here enque can be thought of as appending elements to the list and deque is deleting the first element of the list by giving index as 0 to the pop() function.

Example of doing operations of queues using lists:

queue=[1,2,3,4,5]

queue.append(7) #enque
queue

queue.pop(0) #deque

queue

Output:

[1, 2, 3, 4, 5, 7]

1

[2, 3, 4, 5, 7]

d. It is used for task scheduling in the operating systems, handling interrupts, and so on.

4. Linked Lists in Python

These are linear data structures that hold the values of the next element using the pointers.

a. A node consists of two values, one is the data and the other is the pointer to the next node.

b. The linked lists can be extended easily compared to the lists.

c. We can do operations like adding/deleting nodes at the end, at the beginning or in the middle, and accessing elements.

Linked Lists in Python

d. These are used in the applications like music player, image viewing applications, building the other data structures like stacks, and queues and so on.

5. Tree in Python

Remember making a family tree in your childhood! The trees in Python resemble them. These are non linear data structures that form a hierarchy like structure.

a. A tree has a root node, from where the tree starts and which represents the tree.

b. The other nodes are formed by descending to the root.

c. For a node, the preceding node is called the parent and succeeding node is called the child.

d. tree can have multiple levels, with each level representing the nodes in that depth/ height.

Tree in Python

e. The nodes at the last level are called leaves and they do not have any children.

f. Applications of trees include maintaining tags in HTML pages, implementing priority, etc.

g. There are many types of trees. One of the frequently used ones is the Binary tree, where the maximum number of childs is two. A subclass of this tree is the binary search tree which is used to search the closet item in the real world.

h. Another type of tree is the heap where the tree is built by following either of these conditions, parent nodes are either strictly greater than/ equal to or strictly less than their childs.

6. Graph in Python

These are also non linear data structures that store nodes and edges connecting the nodes.

a. These have the different nodes connecting to the other nodes, representing a real word map like structure.

b. It is used in applications like google maps to find the least distance between two places, finding friends in social media apps, etc.

Graph in Python

7. HashMaps in Python

Hashmaps are the data structures similar to the dictionaries in Python.

a. The only difference is that it maps the keys to the values by taking the hash value of that key.

b. These are used to build phone books, store user data in web applications, and so on.

HashMaps in Python

Python Interview Questions on Data Structures in Python

Q1. How do you find the number of times the last element of the list repeats in a list?

Ans 1. We can use the built-in function count() to find. And to get the last element we can use indexing.

Example of counting number of times the last element repeats:

list=['a','g','y','l','a','r','a']
last=list[-1]
print(list.count(last))

Output:

3

Q2. You are given a list of numbers. How do you remove the duplicates and arrange them in ascending order without using sort function or using for loops for checking every element?

Ans 2. We can convert the list into a set. And then convert back to a list as shown below.

Example of converting list to set and back to list:

list1=[8,4,2,7,0,2,7]
set1=set(list1)
list1=list(set1)
print(list1)

Output:

[0, 2, 4, 7, 8]

Q3. Show two ways to access every third element of a tuple?
Ans 3. We can use slicing, by giving the third argument as 3 or -3.

Example of accessing every third element of a tuple:

tup=(1,2,3,4,5,6,7,8,9,10)
print(tup[::3])

print(tup[::-3])

Output:

(1, 4, 7, 10)

(10, 7, 4, 1)

Q4. Write a program to create a list with one of the elements as a list and accessing the 2nd element of the inner list.
Ans 4. Below is the example of accessing element of inner list:

list_1=[[1,2,3],[4,5,6],8,9,'h']
print(list_1[1][1])

Output:

5

Q5. Write a program to access the 5th value of a dictionary.

Ans 5. We can get all the key values using the built-in function and convert it into a list. Then find the 5th key from the list to get the value.

Example of getting 5th value of a dictionary:

dict1={1:'a',2:'b',3:'c',4:'d',5:'e',6:'f'}
list1=list(dict1.keys())
key=list1[4]
print(dict1[key])

Output:

e

Quiz on Data Structures in Python

Conclusion

In this article, we saw different built-in and user defined data structures in Python. We discussed each of the built-in ones in detail with coding. Then we discussed briefly the user-defined data types. And at the end, we practiced some interview questions.

Hoping that you enjoyed and learned some new concepts reading this article. Happy coding!

Did we exceed your expectations?
If Yes, share your valuable feedback on Google | Facebook


1 Response

  1. Amrish says:

    Simple and great explanation. I have learned this concept clean and neat.

Leave a Reply

Your email address will not be published. Required fields are marked *