# Python Sets Tutorial With Programming Examples

This Python Sets tutorial explains Python Set syntax, Characteristics, Methods, Operations, etc with practical examples:

Most of us must have studied sets and set theory in mathematics at one point in our academic journey. If not, then don’t worry as this tutorial will be easy to digest.

In mathematics, we define sets as a collection of distinct elements that follow a particular rule or that have something in common. Objects in a set are called elements. As defined above the same goes for Python Sets.

=> Take A Look At The Python Beginners Guide Here

## Python Sets

In Python, a Set is a collection of unordered distinct, and immutable elements. Each element is unique and cannot be changed. A set itself can be modified, i.e elements can be added or removed.

### Python Set Syntax

Python Sets have two ways to be defined, one is to use the set() constructor, and the other is with the Set Literal represented with the curly braces { }. As shown below;

```set([iterable])

OR

{obj[,obj,obj,...]}
```

Using the set() constructor, the argument must be an iterable such as a list, string, tuple, etc. It is similar to the list expand() method where each item of the iterable is added to the Set. The argument can also be a collection of iterables, however, these iterables should be immutable.

NB: The square bracket in the first syntax above denotes that the set() constructor takes in an iterable as an optional argument.

Example 1: Defining Sets with set() constructor

```>>> a = set() # define empty set, takes in no argument
>>> a
set()
>>> b = set([4,5,3,3,3]) # takes in list as argument
>>> b
{3, 4, 5}
>>> c = set((4,5,3,3,3)) # takes in tuple as argument
>>> c
{3, 4, 5}
>>> d = set('abcaacc') # takes in string as argument
>>> d
{'b', 'c', 'a'}
>>> e = set([(3,4),(2,5)]) # takes in a list of tuples
>>> e
{(2, 5), (3, 4)}
```

From the example above, we see that it suffices to call a set() constructor without any argument to create an empty set. Also, we generated Sets from iterables like list, tuple and string.

Lastly, the last line of code demonstrates how we can generate a Set from a collection of iterables. Note here that the iterables should be immutable. If we were to replace the immutable tuples with a mutable object like list, then a TypeError would be raised.

On the other hand, for the Set Literal, the obj inside the curly braces can only be immutable. Also, it is similar to the List append() method such that if an iterable is provided, then the entire iterable is added to the set as a whole.

Example 2: Defining Set with Set Literal

```>>> x = {} # this doesn’t generate empty set
>>> x
{}
>>> type(x) # is of type dict
<class 'dict'>
>>> x = {3,4,5,5,4} # takes numbers as argument
>>> x
{3, 4, 5}
>>> z = {(4,3),(4,3)} # takes tuples as arguments
>>> z
{(4, 3)}
>>> i = {'hello'} # takes string as argument
>>> i
{'hello'}
```

From the example above, we notice that an empty Set is not possible with Set Literals as it will instead generate an empty dictionary.

Also, we notice how the curly braces act as the List append() method with the string argument passed to it. In this case, the string is an iterable but unlike a set() constructor which will assign each item of the string to the set(just like List extend() method), the set literal appends the entire string to the set as a whole.

### Differences Between Set() and Set Literals

Both set() constructor and Set Literals can be used to generate sets. However, they have some differences that are worth knowing.

#### #1) Syntax

As we saw earlier in this tutorial, Set Literals are formed using curly braces { } and must have at least one hashable element. If empty, then it will generate an empty dictionary. Unlike set() constructor which can be called without an argument to create an empty set. Refer to Example 1 and 2 for sample code examples.

The string representation of a set always uses the curly braces annotation except for an empty set. This shows how Set Literals are more readable than set() constructors. Consider the example below.

Example 3: Check Readability between set() constructor and Set Literals

```>>> {4,3,6,7} # more readable
{3, 4, 6, 7}
>>> set([4,3,6,7])
{3, 4, 6, 7}
{(9, 2), (4, 3)}
>>> set([(4,3),(9,2)])
{(9, 2), (4, 3)}
```

#### #3) Speed

Set Literals are faster than calling the set() constructor. This is because many steps are involved with the set() constructor.

For example; set([3]), the Python interpreter needs to look up the set name(LOAD_NAME), and then fetch its constructor(LOAD_CONST), build the iterable(BUILD_LIST), and finally pass it to the constructor(CALL_FUNCTION). While for Set Literals, like {3}, a specialized BUILD_SET bytecode is returned.

Let’s compare the bytecodes for set() constructor and Set Literal below:

Example 4: Compare bytecodes between set() constructor and Set Literal.

```>>> from dis import dis
>>> dis('{3}') # for set literal
2 BUILD_SET                1
4 RETURN_VALUE
>>> dis('set([3])') # for set constructor
4 BUILD_LIST               1
6 CALL_FUNCTION            1
8 RETURN_VALUE
```

### Characteristics of Python Sets

Python Sets have the following properties:

• Sets are unordered. That is, the items in the set can be any other; it doesn’t really matter.
• Sets are mutable.
• Sets can contain immutable elements of different data types.

Python Sets have a few unique characteristics that separate it from other data structures.

• Sets do not hold duplicate elements.
• Elements in a Set must be hashable. Meaning that the elements in a set should have hashable data such as int, float, string, and tuple.
• Sets do not support indexing and slicing.

### Differences Between Python Sets and Lists

Lists and Sets are standard Python data types that store values. However, there are some differences between these two data types.

Table 1: Difference between Sets and Lists

SetList
Are unordered collections.Are ordered collections.
Can’t contain duplicates.Can contain duplicates.
Do not support indexing and slicing.Supports indexing and slicing.
Operations like the membership are faster.Are slower.

To know more about Lists, check the tutorial Python Lists.

## Python Set Methods and Operations

These are methods or operators that are used to manipulate a Python Set. In this section,we shall look at a few methods and mathematical operations that can be carried out on Sets.

### #1) Defining a Set

A Set is defined with Set Literals by inserting elements in between curly braces {…} or with set() constructor.

Refer to Example 1 and 2 for how to define sets using these two methods. In this section, we shall demonstrate how to define a Set with elements of different data types.

Example 4: Defining a Set with elements of different data types

```>>> a = {(3,4,0,), 'food', 2.65} # initialize with tuple, string and float
>>> a
{2.65, (3, 4, 0), 'food'}
```

Remember we said sets are unordered? Note the output as how it is not in the same order when initialized.

NB: Your output may look different. Don’t bother as it doesn’t really matter since Sets are unordered.

### #2) Accessing Set Elements

We saw earlier that a Set doesn’t support indexing and slicing. Added to this, Sets don’t provide any methods to retrieve its individual elements.

One may argue that with the .pop() method, we can get an arbitrary Set element. The purpose of this method as we shall see later, is to remove an arbitrary Set element from the Set. That being said, the only way is to loop through the Set as shown below.

Example 5: Loop through elements of a Set

```x = {3, 4, 6, 2, 8, 0, 2} # define set

# loop through set and print each element
for i in x:
print(i)
```

Output

### #3) Adding to a Set

As we saw earlier in this tutorial, the elements of a Set must be immutable. However, the Set itself is mutable. Meaning it can grow or shrink in size. Sets allow us to add new elements to its object via the .add() and .update() methods.

This method adds an element; elem to the Set. It takes only one element argument that must be immutable.

```>>> x = {2, 3, 9} #define set
>>> x
{9, 2, 3, 7}
>>> x
{(0, 1), 2, 3, 7, 9}
```

Update(iter1[,inter2, inter3,…])

This method adds elements of its arguments to the Set. Note that the arguments must be iterables like string, dictionary, set, list, etc.

Example 7: Add elements in a Set with update()

```>>> x = {2, 3, 9} # define main set
>>> x
{9, 2, 3}
>>> x2 = set([0,3,2]) # define another set
>>> x2
{0, 2, 3}
>>> x.update(x2) # update set x with elements of set x2.
>>> x
{0, 2, 3, 9}
>>> x.update('0123') # update set x with a string
>>> x
{0, '0', 2, 3, '1', '3', '2', 9}
>>> x.update({'a':3, 'b':5}, ('h','e','l')) # update set x with a dictionary and tuple
>>> x
{0, 2, 3, '1', 'a', 'l', 9, 'b', '0', '3', 'e', 'h', '2'}
```

Note that the update() method only adds elements into the Set that do not exist in that Set. Secondly, if dictionaries are passed as arguments, then only the keys are added to the Set.

### #4) Set Membership

Set membership means “is an element of” and the symbol ? is usually used in mathematics to indicate set membership. For example, x ? S means that x is an element of the set S.

In Python, we use the in and not in operators to check for membership.

Example 8: Check for set membership

```>>> my_set = {1,2,3,'test','home'}
>>> 'test' in my_set # check if 'test' exist in set
True
>>> 20 in my_set # check if 20 exist in set
False
>>> 1 not in my_set # check if 1 doesn't exist in set
False
>>> 't' not in my_set # check if 't' doesn't exist in set
True
```

### #5) Removing Elements From a Set

Python Sets provide four methods that can be used to remove elements from its object. These methods are; remove(), discard(), pop() and clear(). Each of these methods have their uniqueness as we shall see in this section.

Example 9: Remove elements from a set

```my_set = {1, 2, 3, 'test', 4, 'money', 9, 'car', 'home'} # define set

print("Original Set\n", my_set)

my_set.remove(2)
print("Remove element:2 with remove()\n", my_set)

my_set.discard(20) # nothing happens because element 20 is not in the set.

elem = my_set.pop() # remove and returns an arbitrary element
print("Remove arbitrary element: {} with pop()\n{}".format(elem, my_set))

my_set.clear()
print("Remove all elements with clear()\n", my_set)
```

Output

Before we close this section, it is important to note the following;

• The .remove(elem) method will raise a KeyError exception if elem doesn’t exist in the Set unlike .discard(elem) which doesn’t raise an exception, but nothing happens if elem is not in Set.
• Of all the methods above, only .pop() removes and returns an arbitrary element from the set.
• The .clear() method removes all elements from a set. An empty set is represented as set() and not {}.

### #6) Mathematical Operations

Most often, when we hear Sets, we think of the math operations such as Union, Intersection, Difference, Symmetric Difference. As we shall see in this section, most of these operations can be achieved with both operators and methods, and represented in Venn diagrams.

Sets Union

The union of two or more Sets is computed with the | operator or .union() method. This creates a new set which contains all elements that are present in either Sets or both Sets. For elements present in both Sets, only one copy is maintained since Sets can’t hold duplicates.

Formula

`A u B`

Syntax

```A | B

A.union(B)
```

In the above diagram the Set Union is represented by the green colored sections. So everything in A, or B, or both make up the union set.

Example 10: Union of Sets

```>>> A = {"laugh","run","kick", 5}
>>> B = {"eat", "laugh", "love", 10}
>>> C = set([5,6,10])
>>> A|B|C # using '| operator'
{'eat', 5, 'laugh', 'love', 6, 10, 'run', 'kick'}
>>> A.union(B).union(C) # using .union() method
{'eat', 5, 'laugh', 'love', 6, 10, 'run', 'kick'}
>>> A.union(B|C) # using operator and method
{'eat', 5, 'laugh', 'love', 6, 10, 'run', 'kick'}
```

Sets Intersection

As its name signifies, intersection between Sets creates a new Set containing only the elements common to both Sets. The intersection of Sets can be computed with the  & operator and .intersection() method.

Formula

`A n B`

Syntax

```A & B

A.intersection(B)
```

In the above diagram, the Set intersection is represented by the green colored section. So, everything common to both A and B make up the intersection Set.

Example 11: Intersection of Sets

```A = {"play", "run", "kick"} # define set A using set literal
B = {"run", "laugh", "love"} # define set B using set literal
C = set(["run", "kick"]) # define set C using set() constructor
print("A: {}\nB: {}\nC: {}".format(A,B,C))

ab = A.intersection(B) # intersect using method
print("A n B: ", ab)

ac = A&C # using operator
print("A n C: ", ac)

abc = A&B&C # using operators
print("A n B n C: ", abc)

abc2 = A.intersection(B).intersection(C) # using methods
print("A n B n C: ", abc2)

abc3 = A.intersection(B&C) # using method and operator
print("A n B n C: ", abc3)

AdisB = A.isdisjoint(B) # check A n B == True
print(" A is disjoint B: ", AdisB)

A.intersection_update(B) # Update A with result of A n B
print("A after intersection update between A and B: ", A)
```

Output:

In the example above, we notice two methods i.e. intersection_update() and isdisjoint(). The former operates the same as intersection() but updates the Set object with the resultant intersection Set while the latter checks if there is an intersection between two Sets, it returns False if Sets intersect and True otherwise.

Difference of Sets

The difference of Sets is computed with the – operator or .difference() method. A new Set is created with elements from the first Set which are not in the second Set.

Formula

`A \ B`

Syntax

```A - B

A.difference(B)
```

In the above diagram, the Set Difference is represented by the green colored section. So, everything in A but not in B make up the Set Difference.

Example 12: Difference of sets

```>>> B = {"run", "laugh", "love"}
>>> A = {"play","run","kick"}
>>> C = {"run", "kick"}
>>> A - B # using operator
{'play', 'kick'}
>>> A.difference(B) # using method
{'play', 'kick'}
>>> B.difference(C).difference(A) # using methods
{'love', 'laugh'}
>>> B - C - A # using operators
{'love', 'laugh'}
>>> A.difference_update(B) # Updates A with the set difference
>>> A
{'play', 'kick'}
```

In the example above, we notice the method .difference_update(). This method operates the same as .difference() but updates the object with the resultant Set Difference.

Symmetric Difference of Sets

Python has another form of Set Difference called the Symmetric Difference. It can be computed with ^ operator or symmetric_difference() method and it returns a Set which contains all elements in both Sets excluding the ones which are common(intersection) to both Sets.

Formula

`A ? B`

Syntax

```A ^ B

A.symmetric_differance(B)
```

In the above diagram, the Set Symmetric Difference is represented by the green-colored section. So, everything in A and B but not both make up the Symmetric Difference set.

Example 13: Symmetric Difference of Sets

```>>> B = {"run", "laugh", "love"}
>>> A = {"play","run","kick"}
>>> A.symmetric_difference(B) # use method
{'play', 'kick', 'love', 'laugh'}
>>> A ^ B # use operator
{'play', 'kick', 'love', 'laugh'}
>>> A.symmetric_difference_update(B) # update A with the symmetric difference set.
>>> A
{'play', 'love', 'laugh', 'kick'}
```

In the example above, we notice the method .symmetric_difference_update(). It operates the same as .symmetric_difference() but it updates the Set object with the resultant Set Symmetric Difference.

There are several other methods and operators which can be used with sets. The above methods are just a few that are commonly used in Python.

## Set Comprehensions

Sets have Set comprehensions just as Lists have List comprehensions and Dictionaries have Dictionary comprehensions and can be constructed as follows:

`{ elem for elem in iterable }`

Example 14:

```>>> {x for x in [3,2,4,3,6,7]}
{2, 3, 4, 6, 7}
```

### Frozen Sets

Frozen Sets can be seen as immutable Sets. Meaning unlike Sets, they can’t be changed once created, they can be nested in a set. Also, Frozen Sets are hashable. Meaning they can be used as keys in a dictionary.

NB: Since Frozen Sets are immutable, they support the use of Python Set methods except for methods that modify the Set inplace.

Example 15:

```>>> A = frozenset([1,2,3,4,5]) # define frozen set
>>> A
frozenset({1, 2, 3, 4, 5})
>>> type(A) # check type
<class 'frozenset'>
```

Q #1) Does Python have an ordered set?

Answer: Python doesn’t have an ordered Set built-in. Both Sets and Frozen Sets are unordered. However, there is a Library that is used for this purpose i.e. the ordered-set library. It contains the orderedSet() method that can be used to create ordered Sets.

From the documentation:

```An OrderedSet is a mutable data structure that is a hybrid of a list and a
set. It remembers the order of its entries, and every entry has an index number that can be looked up.```

Q #2) Can Set Literals create empty Sets?

Answer: Unfortunately, we can’t create an empty Set with Set Literals as it will instead create an empty dictionary. However, Python has the set() constructor that can be called without an argument to create an empty Set.

Q #3) How do you turn a list into a Set in Python?

Answer: To turn a list into a Set, we use the set() constructor. Note that this can’t be done with Sets Literals as it doesn’t take in mutable arguments.

## Conclusion

In this tutorial, we had a look at what Python Sets are from its syntax to listing some methods used to manipulate its object like update(), clear(), add(), etc, and operations that are mostly used in mathematics like Union, Intersection, etc.

Lastly we saw how to create Set comprehensions and Frozen Sets.