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

What You Will Learn:

## 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.

#### #2) Readability

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} >>> {(4,3),(9,2)} # more readable {(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 1 0 LOAD_CONST 0 (3) 2 BUILD_SET 1 4 RETURN_VALUE >>> dis('set([3])') # for set constructor 1 0 LOAD_NAME 0 (set) 2 LOAD_CONST 0 (3) 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

Set | List |
---|---|

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.

**add(elem)**

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

**Example 6**: Add an element in a Set with **add()**

>>> x = {2, 3, 9} #define set >>> x.add(7) # Add element: 7 >>> x {9, 2, 3, 7} >>> x.add((0,1)) # add a tuple >>> 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. my_set.discard(3) print("Remove element:20,3 with discard()\n", my_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'>

## Frequently Asked Questions

**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.

**=> Check ALL Python Tutorials Here**