0% found this document useful (0 votes)
4 views13 pages

5 Set Data Structure

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views13 pages

5 Set Data Structure

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Python Jyoti Chandnani

SET Data Structure:


1. A set is unordered collection of unique elements.
2. Set is commonly used in membership testing, removing duplicates from a sequence, and computing
Mathematical operations such as intersection, union, difference, and symmetric difference.
3. Set will not allow duplicate values.
4. Insertion order is not preserved but elements can be sorted.
5. The major advantage of using a set, as opposed to a list, is that it has a highly optimized method for
checking whether a specific element is contained in the set.
6. Sets do not support indexing, slicing.
7. Sets do not support concatenation and multiplication.
8. There are currently two built-in set types,
a. set,
b. frozen set.

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}

2. Creating a set with elements using set().


Eg:
>>> se2=set([1,2,4,'a',2+4j,True]) #creating set with set()
>>> print(se2) ➔{1, 2, 4, (2+4j), 'a'}
>>> type(se2) ➔<class 'set'>

3. Creating a set with curly braces.


Eg:
>>> se3={1,2,3,4,"Jyoti",True} #creating a set with curly braces
>>> print(se3) ➔{1, 2, 3, 4, 'Jyoti'}
>>> type(se3) ➔<class 'set'>

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

Removing duplicate elements from other sequence


Eg1:
>>> lst=[10,20,10,40,50,10,20]
>>> lst=list(set(lst))
>>> print(lst) ➔ [40, 10, 20, 50]
>>> type(lst) ➔<class 'list'>

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}

Note: we cannot add new elements to the frozenset.


>>> fs=frozenset([10,20,30,40])
>>> print(fs) ➔ {10,20,30,40}
>>> fs.add(50) #trying to add new element to frozenset.
Error: AttributeError: 'frozenset' object has no attribute 'add'

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}

the difference between remove() and discard() is,


remove(): if we take the element which is not there in the set then it will throw error.
discard(): if we take the element which is not there in the set then it will do nothing, means it will not
throw error.

Pop(): This function removes set elements randomly


>>> s={10,20,30,40,50}
>>> s.pop() ➔40
>>> s.pop() ➔10
>>> s.pop() ➔50
>>> s.pop(20) ➔TypeError: pop() takes no arguments (1 given)
>>> s.pop() ➔20
>>> print(s) ➔{30}

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}

Clear(): this function clears the existing function.


>>> se1={1,2,3,4,5}
>>> print(se1) ➔{1, 2, 3, 4, 5}
>>> type(se1) ➔<class 'set'>
>>> se1.clear() #clearing the se1, so se1 will become empty set.
>>> print(se1) ➔set()

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: It returns unmatching elements from both sets


Syn: <First_Set>symmetric_difference(<Second_Set>)
Eg:
>>> se1={1,2,3,4,5}
>>> se2={1,2,3,6,7}
>>> se1.symmetric_difference(se2) ➔{4, 5, 6, 7}
>>> se2.symmetric_difference(se1) ➔{4, 5, 6, 7}

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))

Using set in the List:


>>> lst=[10,20,30,{True,2,False,3},[1,2,{100,200,300}]]
>>> print(lst) ➔ [10, 20, 30, {False, True, 2, 3}, [1, 2, {200, 100, 300}]]
>>> len(lst) ➔5
>>> lst[0] ➔10
>>> lst[3] ➔{False, True, 2, 3}
>>> len(lst[3]) ➔4

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]

Using set in the tuple:


eg1:
>>> t=(11,True,{2,3,1},12,13,(10,20,[100,200,300,{25,35,45}]))
>>> print(t) ➔ (11, True, {1, 2, 3}, 12, 13, (10, 20, [100, 200, 300, {25, 35, 45}]))
>>> len(t) ➔6
>>> t[0] ➔11
>>> t[1] ➔True
>>> t[2] ➔{1, 2, 3}
>>> t[2][0] ➔TypeError: 'set' object does not support indexing
>>> t[2][1] ➔TypeError: 'set' object does not support indexing
>>> t[2][2] ➔TypeError: 'set' object does not support indexing
>>> t[3] ➔12
>>> t[4] ➔13
>>> t[5] ➔ (10, 20, [100, 200, 300, {25, 35, 45}])
>>> t[5][0] ➔10
>>> t[5][1] ➔20
>>> t[5][2] ➔ [100, 200, 300, {25, 35, 45}]
>>> t[5][2][0] ➔100
>>> t[5][2][1] ➔200
>>> t[5][2][2] ➔300
11
Python Jyoti Chandnani
>>> t[5][2][3] ➔{25, 35, 45}
>>> t[5][2][3][0] ➔TypeError: 'set' object does not support indexing
>>> t[5][2][3][1] ➔TypeError: 'set' object does not support indexing
>>> t[5][2][3][2] ➔TypeError: 'set' object does not support indexing
>>> t[0:2] ➔ (11, True)
>>> t[0:3] ➔ (11, True, {1, 2, 3})
>>> t[0:4] ➔ (11, True, {1, 2, 3}, 12)
>>> t[0:5] ➔ (11, True, {1, 2, 3}, 12, 13)
>>> t[0:6] ➔ (11, True, {1, 2, 3}, 12, 13, (10, 20, [100, 200, 300, {25, 35, 45}]))
>>> t[1:5] ➔ (True, {1, 2, 3}, 12, 13)
>>> t[1:6] ➔ (True, {1, 2, 3}, 12, 13, (10, 20, [100, 200, 300, {25, 35, 45}]))
>>> t.index(11) ➔0
>>> t.index(True) ➔1
>>> t.index({1,3,2}) ➔2
>>> t.index(12) ➔3
>>> t.index(13) ➔4
>>> t.index((10, 20, [100, 200, 300, {25, 35, 45}])) ➔5
>>> t[5].index(10) ➔0
>>> t[5].index(20) ➔1
>>> t[5].index([100, 200, 300, {25, 35, 45}]) ➔2
>>> t[5][2].index(100) ➔0
>>> t[5][2].index(200) ➔1
>>> t[5][2].index(300) ➔2
>>> t[5][2].index({25,35,45}) ➔3
>>> len(t[5]) ➔3
>>> len(t[5][2]) ➔4
>>> len(t[5][2][3]) ➔3
>>> t[1:t[5][0]] ➔ (True, {1, 2, 3}, 12, 13, (10, 20, [100, 200, 300, {25, 35, 45}]))

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

You might also like