5 Set Data Structure
5 Set Data Structure
Set:
The set type is mutable - the contents can be changed using methods like add() and remove(). Since it is
mutable, it has no hash value and cannot be used as either a dictionary key or as an element of another set.
Frozenset:
The frozenset type is immutable. Its contents cannot be altered after it is created; it can be used as a
dictionary key or as an element of another set.
We can create a set in different ways,
1. Creating an empty set using set() and add elements to that empty set.
Eg:
>>> se1=set() #creating an empty set with set()
>>> se1.add(10) #adding elements to empty set
>>> se1.add(20) #adding elements to empty set
>>> se1.add(30) #adding elements to empty set
>>> se1.add(10) #adding duplicate value to set
>>> print(se1) ➔ {10, 20, 30}
1
Python Jyoti Chandnani
Performing membership operations:
We use ‘in’ and ‘not in’ to perform membership operations.
‘in’ and ‘not’ are used to check the specific element is a part of the existing set or not
>>> se1={10,20,30,True,100,'Jyoti','Python'}
>>> 'Jyoti' in se1 True
>>> 'Django' in se1 False
>>> 'Oracle' in se1 False
>>> 1 not in se1 False
>>> 100 not in se1 False
>>> 20 in se1 True
Eg2:
>>> st='Jyoti'
>>> print(st) ➔ Jyoti
>>> type(st) ➔<class 'str'>
>>> s=set(st)
>>> print(s) ➔{'n', 'y', 'a', 'r'}
>>> st=''.join(s)
>>> print(st) ➔nyar
Eg3:
>>> t=(10,20,30,20,10,20,30,40)
>>> print(t) ➔ (10, 20, 30, 20, 10, 20, 30, 40)
>>> type(t) ➔<class 'tuple'>
>>> t=tuple(set(t))
>>> print(t) ➔ (40, 10, 20, 30)
>>> type(t) ➔<class 'tuple'>
We can’t update the set existing elements with new elements because set will not support indexing,
>>> se={10,20,40,30,5}
>>> print(se) ➔{5, 40, 10, 20, 30}
>>> type(se) ➔ <class 'set'>
>>> id(se) ➔93189584
>>> se[0]=100 ➔TypeError: 'set' object does not support item assignment
2
Python Jyoti Chandnani
Set functions
Add(): this function adds new elements to existing set.
Eg:
>>> se1={1,2,3,4,5}
>>> print(se1) ➔{1, 2, 3, 4, 5}
>>> se1.add(6) #adding elements
>>> se1.add(7)
>> print(se1) ➔{1, 2, 3, 4, 5, 6, 7}
Remove(): it will remove elements from the set, if that element is not found then it will throw error. Eg:
>>> se1={1,2,3,4,5}
>>> print(se1) ➔{1, 2, 3, 4, 5}
>>> type(se1) ➔<class 'set'>
>>> se1.remove(5) #removing element from set
>>> se1.remove(4) #removing element from set
>>> se1.remove(15) #trying to remove element which is not there in set Error: KeyError: 15
Discard(): it will remove elements from the set, if that element is not found in the set then it will do
nothing.
Eg:
>>> se1={1,2,3,4,5}
>>> print(se1) ➔{1, 2, 3, 4, 5}
>>> se1.discard(7) #trying to remove element which not there in the set.
>>> se1.discard(20) #trying to remove element which not there in the set.
>>> se1.discard(5) #removing element which is there in the set
>>> print(se1) ➔{1, 2, 3, 4}
3
Python Jyoti Chandnani
Copy(): this function copies the elements of one set to another new set.
Eg:
>>> se1={1,2,3,4,5}
>>> se2=se1.copy() #copying se1 elements to se2
>>> se1 {1, 2, 3, 4, 5}
>>> se2 {1, 2, 3, 4, 5}
Del command
>>> se={10,20,30,40,50,60}
>>> print(se) {40, 10, 50, 20, 60, 30}
>>> type(se) <class 'set'>
>>> del se[0] ➔TypeError: 'set' object doesn't support item deletion
>>> del se
>>> print(se) ➔NameError: name 'se' is not defined
Isdisjoint(): this function returns True if both are empty sets or if both sets contains non-matching
elements.
Eg:
>>> se1=set()
>>> se2=set()
>>> se1.isdisjoint(se2) ➔True
>>> se1=set()
>>> se2={1,2,3}
>>> se1.isdisjoint(se2) ➔True
>>> se1={1,2,3}
>>> se2={1,2,3,4}
>>> se1.isdisjoint(se2) ➔False
Issubset():
x.issubset(y) returns True, if x is a subset of y. "<=" is an abbreviation for "Subset of".
>>> se1={1,2,3,4,5}
>>> se2={1,2,3}
>>> se2.issubset(se1) ➔True
>>> se1.issubset(se2) ➔False
Or
>>> se2<=se1 ➔True
>>> se1<=se2 ➔False
4
Python Jyoti Chandnani
Issuperset():
x.issuperset(y) returns True, if x is a superset of y. ">=" is an abbreviation for "issuperset of"
Eg:
>>> se1={1,2,3,4,5}
>>> se2={1,2,3}
>>> se2.issuperset(se1) ➔ False
>>> se1.issuperset(se2) ➔True
>>> se2>=se1 ➔ False
>>> se1>=se2 ➔True
We can also check the elements whether they belong to set or not,
Eg:
>> se1={1,2,3,"Python",3+5j,8}
>>> 4 in se1 ➔False
>>> 1 in se1 ➔True
>>> "Python" in se1 ➔True
>>> 10 not in se1 ➔True
>>> "Jyoti" not in se1 ➔True
Union: it returns the union of two sets, that means it returns all the values from both sets except
duplicate values.
The same result we can get by using ‘|’ between two sets
Syn: <First_Set>.union(<Second_Set>) or
<First_Set> | <Second_Set>
Eg 1:
>>> se1={1,2,3,4,5}
>>> se2={1,2,3,6,7}
>>> se1.union(se2) {1, 2, 3, 4, 5, 6, 7} or
>>> se2.union(se1) {1, 2, 3, 4, 5, 6, 7}
Or
>>> se1|se2 {1, 2, 3, 4, 5, 6, 7}
>>> se2|se1 {1, 2, 3, 4, 5, 6, 7}
Eg2:
>>> se1={1,4,2,'a','Python',False}
>>> se2={False,1,'a',10,20,'Jyoti'}
>>> se1.union(se2) ➔{False, 1, 2, 'Jyoti', 4, 'Python', 10, 20, 'a'}
>>> se2.union(se1) ➔{False, 1, 2, 'Jyoti', 4, 'Python', 10, 20, 'a'}
>>> se1|se2 ➔{False, 1, 2, 'Jyoti', 4, 'Python', 10, 20, 'a'}
>>> se2|se1 ➔{False, 1, 2, 'Jyoti', 4, 'Python', 10, 20, 'a'}
5
Python Jyoti Chandnani
Intersection: it returns an intersection element of two sets, that means it returns only common
elements from both sets.
That same operation we can get by sing ‘&’ operator.
Syn: <First_Set>.intersection(<Second_Set>) or
<First_Set> & <Second_Set>
Eg1:
>>> se1={1,2,3,4,5}
>>> se2={1,2,3,6,7}
>>> se1.intersection(se2) {1, 2, 3} or
>>> se1&se2 ➔{1, 2, 3}
Or
>>> se2.intersection(se1) {1, 2, 3}
>>> se2&se1 ➔{1, 2, 3}
Eg2:
>>> se1={False, 1, 2, 4, 'Python', 'a'}
>>> se2={False, 1, 'Jyoti', 10, 20, 'a'}
>>> se1.intersection(se2) ➔{False, 1, 'a'}
>>> se2.intersection(se1) ➔{False, 1, 'a'}
Or
>>> se1&se2 ➔{False, 1, 'a'}
>>> se2&se1 ➔{False, 1, 'a'}
6
Python Jyoti Chandnani
Diffferenece: It returns all elements from first set which are not there in the second set. Syn:
<First_set>.difference(<Secnd_Set>) or
<First_Set> - <Second_Set>
Eg1:
>>> se1={1,2,3,4,5}
>>> se2={1,2,3,6,7}
>>> se1.difference(se2) ➔{4, 5} or
>>> se1-se2 ➔{4, 5}
Or
>>> se2.difference(se1) ➔{6, 7} or
>>> se2-se1 ➔{6, 7}
Eg2:
>>> se1={False, 1, 2, 4, 'Python', 'a'}
>>> se2={False, 1, 'Jyoti', 10, 20, 'a'}
>>> se1.difference(se2) ➔{2, 4, 'Python'}
>>> se2.difference(se1) ➔{10, 'Jyoti', 20}
Or
>>> se1-se2 ➔{2, 4, 'Python'}
>>> se2-se1 ➔{10, 'Jyoti', 20}
Intersection_update: this function will update the First_Set with the result of intersection between
First_Set and Second_Set.
Syn: <First_Set>.intersection_update(<Second_Set>)
>>> se1={1,2,3,4,5}
>>> se2={1,2,3,6,7}
>>> se1.intersection_update(se2)
>>> print(se1) ➔{1, 2, 3}
>>> print(se2) ➔{1, 2, 3, 6, 7}
Or
>>> se1={1,2,3,4,5}
>>> se2={1,2,3,6,7}
>>> se2.intersection_update(se1)
>>> print(se1) ➔{1, 2, 3, 4, 5}
>>> print(se2) ➔ {1, 2, 3}
Eg2:
>>> se1={False, 1, 2, 4, 'Python', 'a'}
>>> se2={False, 1, 'Jyoti', 10, 20, 'a'}
>>> se1.intersection_update(se2)
>>> print(se1) ➔{False, 1, 'a'}
>>> print(se2) ➔{False, 1, 'Jyoti', 10, 20, 'a'}
or
>>> se1={1,4,2,'a','Python',False}
>>> se2={False,1,'a',10,20,'Jyoti'}
>>> se2.intersection_update(se1)
>>> print(se2) ➔ {False, 1, 'a'}
>>> print(se1) ➔{False, 1, 2, 4, 'Python', 'a'}
7
Python Jyoti Chandnani
Differenece_update: the result of difference between two sets will in First_Set.
Syn: <First_Set>.difference_update(<Second_Set>)
Eg:
>>> se1={1,2,3,4,5}
>>> se2={1,2,3,6,7}
>>> se1.difference_update(se2)
>>> print(se1) ➔{4, 5}
>>> print(se2) ➔{1, 2, 3, 6, 7}
Or
>>> se1={1,2,3,4,5}
>>> se2={1,2,3,6,7}
>>> se2.difference_update(se1)
>>> print(se1) ➔{1, 2, 3, 4, 5}
>>> print(se2) ➔{6, 7}
Eg2:
>>> se1={1,4,2,'a','Python',False}
>>> se2={False,1,'a',10,20,'Jyoti'}
>>> se1.difference_update(se2)
>>> print(se1) ➔{2, 4, 'Python'}
>>> print(se2) ➔{False, 1, 'Jyoti', 10, 20, 'a'}
or
>>> se1={1,4,2,'a','Python',False}
>>> se2={False,1,'a',10,20,'Jyoti'}
>>> se2.difference_update(se1)
>>> print(se2) ➔{'Jyoti', 10, 20}
symmetric_difference_update: it will store the unmatching elements from both sets into
First_Set.
Syn: <First_Set>.symmetric_difference_update(<Secon_Set>)
Eg1:
>>> se1={1,2,3,4,5}
>>> se2={1,2,3,6,7}
>>> se1.symmetric_difference_update(se2)
>>> print(se1) ➔{4, 5, 6, 7}
>>> print(se2) ➔{1, 2, 3, 6, 7}
Or
>>> se1={1,2,3,4,5}
>>> se2={1,2,3,6,7}
>>> se2.symmetric_difference_update(se1)
>>> print(se1) ➔{1, 2, 3, 4, 5}
>>> print(se2) ➔ {4, 5, 6, 7}
8
Python Jyoti Chandnani
Eg2:
>>> se1={1,4,2,'a','Python',False}
>>> se2={False,1,'a',10,20,'Jyoti'}
>>> se1.symmetric_difference_update(se2)
>>> print(se1) ➔{2, 'Jyoti', 4, 'Python', 10, 20}
>>> print(se2) ➔{False, 1, 'Jyoti', 10, 20, 'a'}
>>> se1={1,4,2,'a','Python',False}
>>> se2={False,1,'a',10,20,'Jyoti'}
>>> se2.symmetric_difference_update(se1)
>>> print(se1) ➔{False, 1, 2, 4, 'Python', 'a'}
>>> print(se2) ➔{2, 'Jyoti', 4, 'Python', 10, 20}
Set Packing:
The process of packing multiple variables a single place surrounded by curly braces is called set
packing.
Eg:
a=True
b="Python"
c="Django"
d=1
e=20
se1={a,b,c,d,e}
print(se1) {'Python', True, 20, 'Django'} #here 1 is repeating, so removed
se2={d,b,c,a,e}
print(se2) {'Python', 1, 20, 'Django'} #here True is repeating, so removed
Set unpacking
The process of retrieving all elements of a set into different variables dynamically is called set
unpacking.
The number of variables and the number of set elements must be same
Eg:
Se2= {1, 'Python', 20, 'Django'}
m,n,x,y=se2
print(m)
print(type(m))
print(n)
print(type(n))
print(x)
print(type(x))
print(y)
print(type(y))
9
Python Jyoti Chandnani
>>> lst.index({False,True,2,3}) ➔3
>>> lst[3][0] T ➔TypeError: 'set' object does not support indexing
>>> lst[4] ➔ [1, 2, {200, 100, 300}]
>>> len(lst[4]) ➔3
>>> lst[4][0] ➔1
>>> lst[4][1] ➔2
>>> lst[4][2] ➔{200, 100, 300}
>>> lst[4].index(1) ➔0
>>> lst[4].index(2) ➔1
>>> lst[4].index({200,100,300}) ➔2
>>> lst[4].index({200,300,100}) ➔2
>>> lst[4].index({300,100,200}) ➔2
>>> lst[0:2] ➔ [10, 20]
>>> lst[0:3] ➔ [10, 20, 30]
>>> lst[0:4] ➔ [10, 20, 30, {False, True, 2, 3}]
>>> lst[0:5] ➔ [10, 20, 30, {False, True, 2, 3}, [1, 2, {200, 100, 300}]]
Eg1:
>>> lst[0:lst[5][2]] ➔IndexError: list index out of range
Note: the given list has index number upto 4 only, but we are trying to access 5, which is not avaliable.
Eg2:
>>> lst[0:lst[4][1]] ➔ [10, 20]
Here, the result of lst[4][1] is 2 which is in sublist because lst[4] is sublist in the above example.
So, lst[4][1] is replaced with 2 in the list slicing, like below
So, It is like lst[0:2], the result of lst[0:2] is [10,20]
Eg3:
>>> lst[0:lst[4][0]] ➔ [10]
It works like above exmple..
Eg4:
>>> lst[lst[0]:lst[4][0]] ➔ []
Here, lst[0] means 10.
lst[4][0] means 1.
so, lst[10:1] here the starting value is out of index range so it results in empty list [].
Eg5:
>>> lst[lst[0]:lst[4]] ➔TypeError: slice indices must be integers or None or have an __index__ method
Note: Both starting and ending values must be integers, but in this example, lst[4] is a list. so
Interpreter returned TypeError
Eg6:
>>> lst[lst[0]:lst[3]] ➔TypeError: slice indices must be integers or None or have an __index__ method
In this example, lst[3] is set, so it returned TypeError.
Eg7:
>>> lst[lst[0]:lst[2]] ➔ []
Here lst[0] returns 10 andlst[2] returns 30
so It is like lst[10:30], So here both are out of range values, so interpreter returned [].
10
Python Jyoti Chandnani
Eg8:
>>> lst[lst.index(10):lst[2]] ➔ [10, 20, 30, {False, True, 2, 3}, [1, 2, {200, 100, 300}]]
Here, lst.index(10) returns 0
lst[2] returns 30
So It is like lst[0:30], So the starting index value is 0 and ending index value is 30, thats why it has
returned all from 0 to end of the list. Because ending index value 30 is out of index range.
Eg9:
>>> lst[lst.index(10):lst[4][2]] ➔TypeError: slice indices must be integers or None or have an
__index__method
Here, lst.index(10) returns 0, which is int type
lst[4][2] returns {200,100,300} which is a part sublist and its type set...
here the starting index number is int type but ending index number is not a int type, so interpreter
returned TypeError.
Eg10:
>>> lst[lst.index(10):lst[4].index(2)] ➔ [10]
Here, lst.index(10) returns 0
lst[4].index(2) returns 1 which is a part of sublist, the index number of 2 is 1 in the sublist.
so, It is like lst[0:1], the result of this is [10]
Eg11:
>>> lst[lst.index(10):lst[4].index({100,200,300})] ➔ [10, 20]
Here, lst.index(10) returns 0
lst[4].index({100,200,300}) returns 2 which is a part of sublist, the index number of {100,200,300} is
2 in the sublist.
so, It is like lst[0:2], the result of this is [10,20]
eg2:
>>> t1=(11, True, {1, 2, 3}, 12, 13, (1, 2, [100, 200, 300, {25, 35, 45}]))
>>> t1[1:t1[5][0]] ➔ ()
>>> t1[0:t1[5][1]] ➔ (11, True)
>>> t1[1:t1[5]] ➔TypeError: slice indices must be integers or None or have an __index__ method
>>> t1[1:t1[5][2]] ➔TypeError: slice indices must be integers or None or have an __index__ method
>>> t1[1:t1[5][1]] ➔ (True,)
>>> t1[1:t1[5][3]] ➔IndexError: tuple index out of range
>>> t1[1:t1[5][2][0]] ➔ (True, {1, 2, 3}, 12, 13, (1, 2, [100, 200, 300, {25, 35, 45}]))
>>> t1[1:t1[5][2][3]] ➔TypeError: slice indices must be integers or None or have an __index__ method
12
Python Jyoti Chandnani
Sets and frozen sets support the following operators:
key in s # containment check
key not in s # non-containment check
se1 == se2 # s1 is equivalent to s2
se1 != se2 # s1 is not equivalent to s2
se1 <= se2 # s1 is subset of s2
se1 < se2 # s1 is proper subset of s2
se1 >= se2 # s1is superset of s2
se1 > se2 # s1 is proper superset of s2
se1 | se2 # the union of s1 and s2
se1 & se2 # the intersection of s1 and s2
se1 – se2 # the set of elements in s1 but not s2
se1 ˆ se2 # the set of elements in precisely one of s1 or s2
13