What are sets in Python?

Python set is an unordered collection of unique elements. Unlike lists or tuples, sets do not maintain any specific order, and they cannot contain duplicate values. Sets are denoted by curly braces {} or by using the built-in set() function. Let’s take a closer look at how sets work and why they are different from other data structures.

Why use Python sets?

Sets offer several advantages in Python programming. They excel at tasks that involve membership testing, removing duplicates, and performing mathematical operations like union, intersection, and difference between sets. Sets also provide an efficient way to filter unique elements from a list. Their versatility and simplicity make them a valuable tool for a wide range of applications. Now that you understand what sets are and their purpose, let’s begin by creating a set in Python.

I. Creating A Set

To create a set in Python, you can simply enclose elements in curly braces {} or use the set() function. Let’s say we want to create a set of favorite cities:

Example Code
favorite_cities = {"Paris", "New York", "Tokyo"} print(favorite_cities)

In this example, we create a set called favorite_cities that contains three elements: Paris, New York, and Tokyo. We then use the print() function to display the set, which outputs all the cities enclosed in curly braces:

Output
{‘Paris’, ‘New York’, ‘Tokyo’}

II. Adding Elements to a Set

You can easily add elements to a set using the add() method. Let’s expand our favorite cities set:

Example Code
favorite_cities = {"Paris", "New York", "Tokyo"} favorite_cities.add("London") print(favorite_cities)

Here, we use the add() method to add London to our favorite_cities set. After adding the element, we print the updated set, which now includes London along with the existing cities:

Output
{‘Paris’, ‘New York’, ‘Tokyo’, ‘London’}

III. Accessing Elements in a Set

Since sets are unordered, you cannot access elements by their index. However, you can check for membership using the in keyword. Let’s see how we can check if Paris is in our favorite cities set:

Example Code
favorite_cities = {"Paris", "New York", "Tokyo", "London"} if "Paris" in favorite_cities: print("Paris is one of our favorite cities!")

In this example, we use an if statement to check if Paris is present in the favorite_cities set. If the condition is true, we print the message:

Output
Paris is one of our favorite cities!

IV. Removing Elements from a Set

To remove elements from a set you can use the remove() method or the discard() method to eliminate specific elements. If you’re uncertain whether an element exists in the set, discard() is a safer option as it won’t raise an error. Let’s remove London from our favorite cities set:

Example Code
favorite_cities = {"Paris", "New York", "Tokyo", "London"} favorite_cities.remove("London") print(favorite_cities)

Here, we use the remove() method to remove London from the favorite_cities set. If London is present in the set, it will be removed. However, if the element does not exist, a KeyError will be raised. After removing London, we print the updated set, which now includes:

Output
{‘Tokyo’, ‘New York’, ‘Paris’}

Alternatively, you can use the discard() method, which offers a safer way to remove elements without raising an error if the element is not found:

Example Code
favorite_cities = {"Paris", "New York", "Tokyo", "London"} favorite_cities.discard("London") print(favorite_cities)

With the discard() method, we attempt to remove London from the favorite_cities set. If the element exists, it will be removed. However, if the element is not found, no error will be raised.

Remember to choose the appropriate method based on whether you want to handle the possibility of non-existent elements.

V. Modifying Elements in a Set

Sets in Python are mutable, meaning that you can add or remove elements from them, but there is no specific replace() function available to directly modify individual elements in a set. If you want to modify an element in a set, you would typically remove the existing element and add the new element in its place. Let’s say we want to modify our favorite cities set by replacing Tokyo with Sydney:

Example Code
favorite_cities = {"Paris", "New York", "Tokyo", "London"} favorite_cities.remove("Tokyo") favorite_cities.add("Sydney") print(favorite_cities)

Above, we remove “Tokyo” from the favorite_cities set using the remove() method. Then, we add “Sydney” to the set using the add() method. Finally, we print the updated set, which now contains Sydney instead of Tokyo:

Output
{‘London’, ‘Sydney’, ‘Paris’, ‘New York’}

VI. Removing Duplicates from a List Using Sets

Using sets to remove duplicates from a list is a quick and efficient way to obtain a collection of unique elements. Let’s say you have a list with duplicate elements and you want to remove those duplicates to create a new list with unique elements. Python sets provide an efficient way to accomplish this task. Here’s an example:

Example Code
destinations = ["Paris", "New York", "Tokyo", "Tokyo", "London", "Rome"] unique_destinations = list(set(destinations)) print("List with duplicates:", destinations) print("List without duplicates:", unique_destinations)

To remove the duplicates, we convert the list to a set. A set only keeps unique elements, so any duplicates will automatically be eliminated. Let’s see the result. We print the original list with duplicates and the new list without duplicates:

Output
List with duplicates: [‘Paris’, ‘New York’, ‘Tokyo’, ‘Tokyo’, ‘London’, ‘Rome’]
List without duplicates: [‘Tokyo’, ‘London’, ‘New York’, ‘Paris’, ‘Rome’]

Remember that the order of the elements might change after converting the set back to a list, as sets do not maintain the original order.

Python Sets Operations

Python sets offer a rich variety of operations that allow you to combine, compare, and extract unique elements from sets effortlessly. Let’s start by exploring three fundamental set operations: union, intersection, and difference.

I. Python Set Union

Imagine you have two sets representing favorite travel destinations: dream_destinations and friend_destinations:

dream_destinations = {"Paris", "New York", "Tokyo"}
friend_destinations = {"Tokyo", "London", "Rome"}

To find the union of these sets, which combines all the unique elements, we use the union() method:

Example Code
dream_destinations = {"Paris", "New York", "Tokyo"} friend_destinations = {"Tokyo", "London", "Rome"} all_destinations = dream_destinations.union(friend_destinations) print("Our combined travel destinations:", all_destinations)

Here, we call the union() method on the dream_destinations set and pass friend_destinations as an argument. The union() method performs the operation and returns a new set, which we assign to the variable all_destinations. The output will be:

Output
Our combined travel destinations: {‘Tokyo’, ‘New York’, ‘Paris’, ‘Rome’, ‘London’}

By calling the union() method, we merge the unique elements from both sets into a single set, which gives us a consolidated list of all the travel destinations that you and your friend want to visit.

II. Python Set Intersection

The intersection of sets refers to the common elements between them. We can find it using the intersection() method:

Example Code
dream_destinations = {"Paris", "New York", "Tokyo"} friend_destinations = {"Tokyo", "London", "Rome"} common_destinations = dream_destinations.intersection(friend_destinations) print("Destinations we both want to visit:", common_destinations)

In this example, we have two sets: dream_destinations and friend_destinations, representing your favorite travel destinations and your friend’s favorite travel destinations, respectively. we call the intersection() method on the dream_destinations set and pass friend_destinations as an argument. The intersection() method performs the operation and returns a new set, which we assign to the variable common_destinations.

Output
Destinations we both want to visit: {‘Tokyo’}

By calling the intersection() method, we obtain a set that contains only the travel destinations that both you and your friend have in common.

III. Python Set difference

To determine the elements that exist in dream_destinations but not in friend_destinations, we use the difference() method:

Example Code
dream_destinations = {"Paris", "New York", "Tokyo"} friend_destinations = {"Tokyo", "London", "Rome"} unique_destinations = dream_destinations.difference(friend_destinations) print("Destinations unique to our dreams:", unique_destinations)

Here, , we call the difference() method on the dream_destinations set and pass friend_destinations as an argument. The difference() method performs the operation and returns a new set, which we assign to the variable unique_destinations.

Finally, we display the unique destinations using a print statement:

Output
Destinations unique to our dreams: {‘Paris’, ‘New York’}

By calling the difference() method, we obtain a set that contains the travel destinations that exist in your dreams but not in your friend’s preferences.

Now that you have a solid grasp of the fundamentals of Python sets, it’s time to explore another type of set called a frozenset, which is immutable.

What are Frozensets?

A frozenset is an immutable version of a set. While regular Python sets are mutable, meaning you can add, remove, or modify elements, frozensets are immutable, and their elements cannot be changed once defined. This immutability comes with its own benefits and use cases.

I. Creating Frozensets

Creating a frozenset is as easy as pie. Let’s say we want to create a frozenset of popular cities around the world:

Example Code
popular_cities = frozenset(["Paris", "New York", "Tokyo", "London"]) print("Popular cities:", popular_cities)

In the example, we define a frozenset called popular_cities containing the names of popular cities. We use the frozenset() function and pass a list of city names as an argument. Finally, we display the frozenset using the print() function.

Output
Popular cities: frozenset({‘London’, ‘New York’, ‘Paris’, ‘Tokyo’})

II. Immutable Nature of Frozensets

One of the key features of frozensets is their immutability. Once a frozenset is created, you cannot modify its elements. Let’s see this in action:

Example Code
popular_cities = frozenset(["Paris", "New York", "Tokyo", "London"]) popular_cities.add("Rome") print("Popular cities:", popular_cities)

If you try to execute the above code, you’ll encounter a TypeError. Since frozensets are immutable, any attempt to add, remove, or modify elements will result in an error. This immutability ensures the integrity and consistency of frozensets.

Set Comparison

With Python sets, you can perform various set operations like union, intersection, and difference. But what about comparing sets? Well, Python provides us with handy methods and operators to compare sets based on their elements. Let’s explore how sets can be compared for equality, subset, and superset relationships.

I. Set Equality

To check if two sets are equal, meaning they have exactly the same elements, we can use the == operator or the set1 == set2 syntax. Let’s take a look at an example:

Example Code
set1 = {"apple", "banana", "orange"} set2 = {"banana", "orange", "apple"} if set1 == set2: print("The sets are equal.") else: print("The sets are not equal.")

Above, we have two sets, set1 and set2, which contain the same elements but in different orders. By using the == operator, we compare the sets and determine that they are equal. The output will be:

Output
The sets are equal.

In addition to checking for equality, we can also determine if one set is a subset or superset of another set. A subset is a set that contains all the elements of another set, while a superset is a set that contains all the elements of another set and potentially additional elements. Python provides us with methods and operators to perform these comparisons.

II. Subset Relationship

To check if one set is a subset of another set, we can use the set1.issubset(set2) method or the set1 <= set2 syntax. Let’s see an example:

Example Code
set1 = {"apple", "banana"} set2 = {"banana", "apple", "orange"} if set1.issubset(set2): print("set1 is a subset of set2.") else: print("set1 is not a subset of set2.")

Here, set1 is a subset of set2 because it contains all the elements present in set2. Therefore, the output will be:

Output
set1 is a subset of set2.

III. Superset Relationship

To check if one set is a superset of another set, we can use the set1.issuperset(set2) method or the set1 >= set2 syntax. Let’s take a look at an example:

Example Code
set1 = {"banana", "apple", "orange"} set2 = {"apple", "banana"} if set1.issuperset(set2): print("set1 is a superset of set2.") else: print("set1 is not a superset of set2.")

In this example, set1 is a superset of set2 because it contains all the elements present in set2 and an additional element. Hence, the output will be:

Output
set1 is a superset of set2.

Modifying a Set While Iterating Over It

From this section of tutorial, we will examine the potential pitfalls and unexpected behavior that can arise when attempting to modify a set during iteration. When we iterate over a set using a for loop, we might get tempted to modify the set within the loop. However, this can lead to unexpected and erroneous results. Let’s consider an example:

Example Code
celebrities = {"Brad Pitt", "Jennifer Aniston", "Leonardo DiCaprio"} for celebrity in celebrities: celebrities.remove(celebrity) print(celebrities)

In this example, we attempt to remove each celebrity from the celebrities set while iterating over it. However, you might be surprised by the outcome. Instead of an empty set, you may encounter a RuntimeError with a message like “Set size changed during iteration” or observe that not all elements were removed.

Understanding the Issue:

The issue stems from the internal mechanics of the for loop and how it handles iteration over sets. The loop is based on an iterator that keeps track of the current position in the set. When an element is removed, it disrupts the iterator’s order and can result in elements being skipped or the iteration being prematurely terminated.

Safe Practices for Modifying a Set During Iteration

To avoid the issues mentioned above, it is recommended to follow these safe practices when modifying a set during iteration:

I. Create a Copy

Before iterating, create a copy of Python set using the copy() method or by slicing the set (set_copy = set(original_set)). Iterate over the copy while modifying the original set.

II. Use a List for Deferred Modifications

Instead of modifying Python sets directly, collect the elements that need to be removed or modified in a separate list. After the iteration, iterate over the list and make the desired changes to the set. Below is an example code that demonstrates the safe practices for modifying a set during iteration:

Example Code
celebrities = {"Brad Pitt", "Jennifer Aniston", "Leonardo DiCaprio"} # Creating a copy of the set celebrities_copy = celebrities.copy() # Modifying the original set while iterating over the copy for celebrity in celebrities_copy: if "Brad" in celebrity: celebrities.remove(celebrity) print("Modified set:", celebrities)

In above code, we create a copy of the celebrities set using the copy() method and iterate over the copy. We then check if the name Brad is present in each celebrity’s name. If it is, we remove that celebrity from the original set celebrities. By modifying the original set while iterating over the copy, we ensure that the iteration is not affected by the changes.

Output
Modified set: {‘Jennifer Aniston’, ‘Leonardo DiCaprio’}

III. Iterate Over a Sorted Version

If the order of iteration is not important, you can sort the set elements using the sorted() function. Then, iterate over the sorted list while modifying the set.

Certainly! Here’s an example that demonstrates how to iterate over a sorted version of a set to safely modify it during iteration:

Example Code
celebrities = {"Brad Pitt", "Jennifer Aniston", "Leonardo DiCaprio"} # Creating a sorted list of set elements sorted_celebrities = sorted(celebrities) # Modifying the set while iterating over the sorted list for celebrity in sorted_celebrities: if "Brad" in celebrity: celebrities.remove(celebrity) print("Modified set:", celebrities)

Here, we create a sorted list sorted_celebrities by using the sorted() function on the celebrities set. This ensures that the set elements are iterated over in a sorted order. We then iterate over the sorted list and check if the name “Brad” is present in each celebrity’s name. If it is, we remove that celebrity from the original set celebrities.

By following this safe practice of creating a copy before modifying the set, you can avoid the potential issues of modifying a set during iteration.

Set vs. List: When to Use Each

In Python, both sets and lists are versatile data structures that serve different purposes and have distinct characteristics. Understanding the differences between sets and lists is crucial in selecting the appropriate data structure for your specific needs. Let’s  explore the key features of sets and lists and provide guidance on when to use each.

I. Python Sets Uniqueness

Sets are unordered collections of unique elements. They are defined by their unique property, meaning that duplicate elements are automatically removed. Sets provide efficient membership testing, making them ideal for scenarios where you need to check if an element exists in a collection without the need for indexing or ordering.

Sets are particularly useful in the following situations:

  1. If you have a list of elements with duplicates and you want to eliminate them, converting the list to a set will automatically remove the duplicates.
  2. Python sets offer powerful set operations such as union, intersection, and difference. These operations allow you to combine sets, find common elements, or identify differences between sets efficiently.
  3. If you frequently need to check if an element exists in a collection, sets provide a fast and efficient solution.

II. Lists: Ordered and Mutable Sequences

Lists, on the other hand, are ordered collections of elements. They preserve the order of insertion and allow duplicates. Lists are mutable, meaning that you can modify them by adding, removing, or updating elements.

Lists are well-suited for the following scenarios:

  1. When the order of elements is important, lists maintain the sequence of elements as they are added.
  2. Lists allow you to access elements using their indices, making it easy to retrieve specific elements or subsets of elements using slicing.
  3. Lists can grow or shrink dynamically, making them suitable for scenarios where the size of the collection may change over time.

Sets in Python 2 vs. Python 3

Python 2 and Python 3 have some differences in the implementation and behavior of sets. Let’s find out the key distinctions between sets in Python 2 and Python 3 to help you understand how sets have evolved.

I. Syntax Differences

The syntax for creating sets is one notable difference between Python 2 and Python 3. In Python 2, you use the set() constructor or a comma-separated list of elements enclosed in curly braces {} to define a set. For example:

set_2 = set([1, 2, 3]) # Using set() constructor
set_3 = {4, 5, 6} # Using curly braces

In Python 3, the syntax for creating sets using curly braces remains the same. However, Python 3 introduced a more concise syntax for creating an empty set using a pair of empty curly braces {}. For example:

set_2 = set([1, 2, 3]) # Using set() constructor
set_3 = {4, 5, 6} # Using curly braces
empty_set = {} # Empty dictionary in Python 3, not a set
empty_set_3 = set() # Empty set in Python 3

II. Handling Immutable Elements

Another difference is how sets handle immutable elements such as strings and tuples. In Python 2, sets can contain only immutable elements. If you attempt to add a mutable element, such as a list, to a set, it will raise an error. Python 2 sets are based on hash tables, and their behavior is similar to dictionaries.

In Python 3, sets can contain both mutable and immutable elements. The implementation of sets in Python 3 has been improved using a data structure called hash set, which allows for efficient membership testing and set operations on both immutable and mutable elements.

III. Methods and Operations

The basic set operations, such as union, intersection, and difference, are consistent between Python 2 and Python 3. However, Python 3 introduced additional set operations, such as symmetric difference (^), which returns elements that are in either of the sets but not in both.

Python 3 also introduced new methods and functionalities for sets, including set.copy() to create a shallow copy of a set, set.add() to add an element to a set, and set.remove() to remove an element from a set. These methods provide more flexibility and convenience when working with sets in Python 3.

Now that you have explored Python Sets, you possess a powerful tool that can simplify and enhance your programming experience. Sets offer a unique way to handle collections of unique elements, providing benefits such as efficient membership testing, removal of duplicates, and performing mathematical operations on sets.

So leverage the versatility and simplicity of sets in your Python programming. Start by creating sets using curly braces or the set() function, adding and removing elements with ease, and accessing elements through membership testing. You can even perform set operations like union, intersection, and difference to manipulate and extract useful information from sets.

Remember, sets are not only efficient but also provide an elegant and intuitive way to handle unique collections of data. Embrace the power of sets in your Python code and unlock new possibilities in your programming journey. Happy coding!

 
Scroll to Top