Chp-10: Sets#
Chapter Objectives
By the end of this chapter, the student should be able to:
Explain the purpose and role of sets.
Create and initialize sets in different ways.
Perform set operations.
Apply set methods.
Recognize uniqueness and mutability of sets.
Use loops to iterate through set elements.
Apply sets to solve real-world problems
Sets#
A set is an unordered collection of values.
Sets can contain a mixed type of elements.
Since there is no order there is no indexing for sets.
Curly brackets
{}
are used to create sets.{}
is NOT an empty set. It is an empty dictionary that will be covered in next chapter.
Sets are mutable. so they can be modified like lists.
A tuple can be an element of a set.
A list cannot be an element of a set.
You can use the
set()
function to convert strings, tuples, and lists into a set.Only unique values are stored in sets (no repetition).
You will lose the order of the elements when you use the conversion.
mylist = [1,4,7,7,8]
myset = set(mylist)
print(myset)
{8, 1, 4, 7}
In the code above, the order of the elements in the mylist has been lost, and one of the 7s has been removed when the list is converted to a set.
Create Sets#
# empty set
empty_set = set()
print(f'Empty set : {empty_set}')
print(f'Type of empty_set: {type(empty_set)}')
Empty set : set()
Type of empty_set: <class 'set'>
# set with mixed values: str, int, bool, float
mixed_set = {'USA', 2, True, 9.123}
print(type(mixed_set))
<class 'set'>
# sets do not contain duplicates
mixed_set = {'USA', 2, True, 9.123, 'USA', 'USA', 'USA', 'USA'}
print(mixed_set) # only one 'USA' will be in the set mixed_set
{True, 2, 'USA', 9.123}
The tuple below contains mixed data types, including strings, integers, booleans, floats, tuples, lists, and sets.
mixed_tuple = ('USA', 2, True, 9.123, (10,20,30), ['NY', 'NJ'], {'a','b'})
print(type(mixed_tuple))
<class 'tuple'>
The list below contains mixed data types, including strings, integers, booleans, floats, tuples, lists, and sets.
mixed_list = ['USA', 2, True, 9.123, (10,20,30), ['NY', 'NJ'], {'a','b'}]
print(type(mixed_list))
<class 'list'>
# a list can not be an element of a set
mixed_set = {'USA', 2, True, 9.123, (10,20,30), ['a','b']} # ERROR
set() function#
The built-in set()
function converts strings, tuples, and lists to a set, removing any duplicates and retaining only unique elements.
char_set = set('Hello') # convert string to set
print(f'Type of char_set: {type(char_set)}')
print(f'char_set : {char_set}')
Type of char_set: <class 'set'>
char_set : {'e', 'o', 'H', 'l'}
number_tuple = (1,2,3,4,4,4)
char_set = set(number_tuple) # convert tuple to set
print(f'Type of char_set: {type(char_set)}')
print(f'char_set : {char_set}')
Type of char_set: <class 'set'>
char_set : {1, 2, 3, 4}
number_list = [1,2,3,4,4,4]
char_set = set(number_list) # convert list to set
print(f'Type of char_set: {type(char_set)}')
print(f'char_set : {char_set}')
Type of char_set: <class 'set'>
char_set : {1, 2, 3, 4}
Remark: By using tuple() and list() functions, sets can be converted to tuples and lists, respectively.
It’s important to note that the conversion doesn’t preserve any specific order, as sets are inherently unordered collections.
number_set = {1,2,3,4} # set
number_tuple = tuple(number_set) # set ---> tuple
print(f'Type of number_tuple: {type(number_tuple)}')
print(f'number_tuple : {number_tuple}')
Type of number_tuple: <class 'tuple'>
number_tuple : (1, 2, 3, 4)
number_set = {1,2,3,4} # set
number_list = list(number_set) # set ---> list
print(f'Type of number_list: {type(number_list)}')
print(f'number_list : {number_list}')
Type of number_list: <class 'list'>
number_list : [1, 2, 3, 4]
Functions on sets#
len(), max(), min(), and sum() functions can be applied to sets, similar to other data types like tuples and lists.
numbers = {7,3,1,9,6,4}
print(f'Length : {len(numbers)}')
print(f'Maximum: {max(numbers)}')
print(f'Minimum: {min(numbers)}')
print(f'Sum : {sum(numbers)}')
Length : 6
Maximum: 9
Minimum: 1
Sum : 30
letters = {'r', 't', 'n', 'a', 'd'}
print(f'Length : {len(letters)}')
print(f'Maximum: {max(letters)}') # dictionary order
print(f'Minimum: {min(letters)}')
Length : 5
Maximum: t
Minimum: a
Set Operations#
The available operators for sets in Python include:
&
(intersection)|
(union)-
(difference)^
(symmetric difference)in
not in
Intersection#
The &
(ampersand) operator returns a new set consisting of the common elements of the two sets.
set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
print(f'Intersection of set1 and set2: {set1&set2}')
Intersection of set1 and set2: {3, 4, 5}
The intersection() method of sets can also be used to find the common elements between two sets.
set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
print(f'set1 intersection set2 : {set1.intersection(set2)}')
print(f'set1 (No change on set1): {set1}')
set1 intersection set2 : {3, 4, 5}
set1 (No change on set1): {1, 2, 3, 4, 5}
Union#
The |
(pipe) operator returns a new set consisting of the combined elements of the two sets.
set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
print(f'Union of set1 and set2: {set1|set2}')
Union of set1 and set2: {1, 2, 3, 4, 5, 6, 7}
The union() method of sets can also be used to combine elements from two sets into a new set.
set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
print(f'set1 union set2 : {set1.union(set2)}')
print(f'set1 (No change on set1): {set1}')
set1 union set2 : {1, 2, 3, 4, 5, 6, 7}
set1 (No change on set1): {1, 2, 3, 4, 5}
Difference#
The -
(dash) operator returns a new set consisting of the elements in the first set but not in the second set.
set1 - set2
: elements in set1 but not in set2.set2 - set1
: elements in set2 but not in set1.
set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
print(f'set1 - set2: {set1-set2}')
print(f'set2 - set1: {set2-set1}')
set1 - set2: {1, 2}
set2 - set1: {6, 7}
The difference() method of sets can also be used to obtain a new set consisting of the elements in the first set but not in the second set.
set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
print(f'set1 - set2: {set1.difference(set2)}')
print(f'set2 - set1: {set2.difference(set1)}')
set1 - set2: {1, 2}
set2 - set1: {6, 7}
Symmetric Difference#
The ^ (caret) operator returns a new set consisting of elements in either one of the two sets but not both.
set1 ^ set2
andset2 ^ set1
are same.
set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
print(f'set1 ^ set2: {set1^set2}')
print(f'set2 ^ set1: {set2^set1}')
set1 ^ set2: {1, 2, 6, 7}
set2 ^ set1: {1, 2, 6, 7}
The symmetric_difference() method of sets can also be used to obtain a new set consisting of the elements in either one of the two sets but not both.
set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
print(f'set1 ^ set2: {set1.symmetric_difference(set2)}')
print(f'set2 ^ set1: {set2.symmetric_difference(set1)}')
set1 ^ set2: {1, 2, 6, 7}
set2 ^ set1: {1, 2, 6, 7}
in & not in#
in
checks if a value is part of a set, while not in
verifies if a value is absent from a set.
Both operations yield a Boolean result, either True or False.
number_set = {1,2,3,4,5}
print(f' 5 is in number_set : {5 in number_set}' )
print(f' 5 is not in number_set: {5 not in number_set}' )
5 is in number_set : True
5 is not in number_set: False
number_set = {1,2,3,4,5}
print(f' 9 is in number_set : {9 in number_set}' )
print(f' 9 is not in number_set: {9 not in number_set}' )
9 is in number_set : False
9 is not in number_set: True
Mutable#
Unlike strings and tuples, and similar to lists, sets are mutable, allowing them to be modified.
The set methods enable the addition of new elements and the removal of existing ones.
Set elements themselves cannot be changed, but new items can be added or existing ones removed.
Set Methods#
Except for the magic methods (those with underscores), there are 17 methods for sets.
We have already covered intersection, union, difference, and symmetric difference above.
You can execute help(set) for more details.
# methods of sets
# dir() returns a list
print(dir(set))
['__and__', '__class__', '__class_getitem__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__iand__', '__init__', '__init_subclass__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
# non magic methods by using slicing
print(dir(set)[-17:])
['add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
add()#
It adds a new element to a set.
number_set = {1,2,3,4,5}
print(f'number_set before using add(99): {number_set}')
# add 99
number_set.add(99)
print(f'number_set after using add(99): {number_set}')
number_set before using add(99): {1, 2, 3, 4, 5}
number_set after using add(99): {1, 2, 3, 4, 5, 99}
clear()#
It removes all elements from the set, making it an empty set.
number_set = {1,2,3,4,5}
print(f'number_set before using clear(): {number_set}')
# removes all elements
number_set.clear()
print(f'number_set after using clear(): {number_set}')
number_set before using clear(): {1, 2, 3, 4, 5}
number_set after using clear(): set()
copy()#
It returns a new set with the same elements.
number_set = {1,2,3,4,5}
print(f'number_set before using copy(): {number_set}')
# make a copy
number_set_copy = number_set.copy()
print(f'number_set after using copy(): {number_set}')
print(f'number_set_copy : {number_set_copy}')
number_set before using copy(): {1, 2, 3, 4, 5}
number_set after using copy(): {1, 2, 3, 4, 5}
number_set_copy : {1, 2, 3, 4, 5}
isdisjoint()#
It checks if there are no common elements between the two given sets.
set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
# False: 3,4,5 are common
print(f'set1 and set2 are disjoint: {set1.isdisjoint(set2)}' )
set1 and set2 are disjoint: False
set1 = {1,2,3,4,5}
set2 = {10,20,30}
# True: no common element
print(f'set1 and set2 are disjoint: {set1.isdisjoint(set2)}' )
set1 and set2 are disjoint: True
issubset()#
It checks if the first set is a subset of the second set.
set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
# False: set1 is not subset of set2
print(f'set1 is subset of set2: {set1.issubset(set2)}' )
set1 is subset of set2: False
set1 = {3,4,5}
set2 = {3,4,5,6,7}
# True: set1 is not subset of set2
print(f'set1 is subset of set2: {set1.issubset(set2)}' )
set1 is subset of set2: True
isuperset()#
It checks if the first set contains the second set.
set1 = {1,2,3,4,5}
set2 = {3,4,5,6,7}
# False: set1 idoes not contain set2
print(f'set1 is superset of set2: {set1.issuperset(set2)}' )
set1 is superset of set2: False
set1 = {1,2,3,4,5}
set2 = {3,4,5}
# True: set1 contains set2
print(f'set1 is superset of set2: {set1.issuperset(set2)}' )
set1 is superset of set2: True
pop()#
It removes a randomly selected element from the set.
If the set is empty, an error message is raised.
number_set = {1,2,3,4,5}
print(f'number_set before using pop(): {number_set}')
# removes a ranodm element
removed_element = number_set.pop()
print(f'number_set after using pop(): {number_set}')
print(f'removed element : {removed_element}')
number_set before using pop(): {1, 2, 3, 4, 5}
number_set after using pop(): {2, 3, 4, 5}
removed element : 1
remove()#
It removes the specified element from the set.
If the element does not exist in the set, an error message is raised.
number_set = {1,2,3,4,5}
print(f'number_set before using remove(): {number_set}')
# removes 3
number_set.remove(3)
print(f'number_set after using remove(): {number_set}')
number_set before using remove(): {1, 2, 3, 4, 5}
number_set after using remove(): {1, 2, 4, 5}
update()#
It adds elements of the second set to the first one.
set1 = {1,2,3}
set2 = {'a', 'b', 'c', 'd'}
print(f'set1 before update: {set1}')
set1.update(set2)
print(f'set1 after update: {set1}')
set1 before update: {1, 2, 3}
set1 after update: {1, 2, 3, 'b', 'd', 'a', 'c'}
You can also add elements from a tuple or list using the update() method.
myset = {1,2,3}
mytuple = ('a', 'b', 'c', 'd')
print(f'myset before update: {myset}')
myset.update(mytuple)
print(f'myset after update: {myset}')
myset before update: {1, 2, 3}
myset after update: {1, 2, 3, 'b', 'a', 'd', 'c'}
myset = {1,2,3}
mylist = ['a', 'b', 'c', 'd']
print(f'myset before update: {myset}')
myset.update(mylist)
print(f'myset after update: {myset}')
myset before update: {1, 2, 3}
myset after update: {1, 2, 3, 'b', 'a', 'd', 'c'}
Iterations and Sets#
We can use a for loop to iterate through values in the set and access each element of the set to perform operations on them.
Indexes cannot be used, as in tuples and lists, since there is no ordering and indexing for sets.
When you run a for loop through a set, the order of the values of the set might be different.
# print state names in states set
states = {'Arizona','Oklahoma', 'Texas', 'Florida', 'California'} # states is a set
for state in states:
print(state) # not in the same order that you see above
Oklahoma
Arizona
Florida
California
Texas