# Set Data Type in Python

## Python Sets

Mathematically a set is a collection of elements, not having any particular order. A Python set is an unordered collection of immutable and unique elements. As the set elements are usually not stored in order of appearance in the set, so there is no index attached to any element. Thus they do not support any indexing or slicing operation.

### Creating Python sets

A Set is created by placing all the elements inside curly braces {} and separating them with a comma, or by using the built-in set() method.

```set1 = {1,2,3,4,1}
print(set1)
print(type(set1))
#Output: {1,2,3,4} #unique elements
<class 'set'>

set2 = set([1,2,3,4,5,6,7,8])
print(set2)
#Output: {1, 2, 3, 4, 5, 6, 7, 8}

list = [23,56,76,52,12,53,45,45,23,35,76,32]
set3 = set(list)
print(set3)
#Output: {32, 35, 76, 12, 45, 52, 53, 23, 56} #unordered collection

str = "Python For You"
set4 = set(str)
print(set4)
#Output: {'o', ' ', 'y', 'n', 'h', 'F', 'u', 'P', 'Y', 't', 'r'}

tup = ('a', 'p', 'p', 'l', 'e',)
set5 = set(tup)
print(set5)
#Output: {'l', 'e', 'p', 'a'}

set6 = set([10,10.0,10.4, "Python", (1, 2, 3)])
print(set6)
#Output: {(1, 2, 3), 10, 10.4, 'Python'}

set7 = {7, (1, 2, 3), 3.14159, ["a", "b", "c"]}
#Output: TypeError: unhashable type: 'list' #elements of list must be immutable and list is mutable
```

Python seizes empty curly bracesĀ {} as an empty dictionary. Thus only set() method is used to define an empty set.

```#creating an empty set with {}
empty1 = {}
print(type(empty1))
#Output: <class 'dict'>

#creating an empty set with set() method
empty2 = set()
print(type(empty2))
#Output: <class 'set'>
```

### Modifying a Python set

Elements of a set are immutable however, a set as a whole is mutable. Elements can be added and removed to a set in python.

```fruits = {"banana", "orange", "apple", "watermelon"}

print(fruits)
#Output: {'watermelon', 'banana', 'apple', 'strawberry', 'orange'}

commmon_fruits = ["apple", "banana", "cherry"]
fruits.update(commmon_fruits)
print(fruits)
#Output: {'strawberry', 'cherry', 'apple', 'orange', 'banana', 'watermelon'}

#removing an element
fruits.remove('orange')
print(fruits)
#Output: {'cherry', 'strawberry', 'banana', 'apple', 'watermelon'}

print(fruits)
#Output: {'cherry', 'banana', 'strawberry', 'apple'}

print(fruits)

fruits.remove('orange')
#Output: KeyError: 'orange' #if element is not foundĀ  remove() method raises an KeyError

fruits.pop()
print(fruits)
#Output: {'strawberry', 'apple', 'banana'} #raises an KeyError for an empty set

#clearing all elements
fruits.clear()
print(fruits)
#Output: set()
```

### Frozenset

A frozen set in python is an immutable set. It has the same characteristics as of a normal set except that it cannot be changed once created. Frozensets are useful in situations where an immutable set is required. As sets are mutable they are unhashable, so they can’t be used as dictionary keys. On the other hand, frozensets are immutable thus they are hashable and can be used as keys to a dictionary.

```set1 = frozenset({1, 2, 3})
print(set1)
print(type(set1))
#Output: frozenset({1, 2, 3})
<class 'frozenset'>

#empty frozen set
set2 = frozenset()
print(set2)
#Output: frozenset()```

The sets in python are typically used for removing duplicate values from a list or tuple and to perform mathematical operations like union, intersection, difference, etc.

### Set Operations

Python set is a mathematical notion of set. It is typically used for removing duplicate values from a list or tuple and performing mathematical operations like union, intersection, difference, etc.

#### Union

Union of set1 and set2 is a set of all elements from both sets. It is performed by using union() function or | operator.

```set1 = {4, 3, 1, 8, 6}
set2 = {2, 1, 3, 7}

#using | operator
print(set1 | set2)
#Output: {1, 2, 3, 4, 6, 7, 8}

#using set union() method
print(set1.union(set2))
#Output: {1, 2, 3, 4, 6, 7, 8}```

### Intersection

Intersection of set1 and set2 is a set of elements that are common in both the sets. It is performed by using intersection() function or & operator.

```set1 = {4, 3, 1, 8, 6}
set2 = {2, 1, 3, 7}

#using & operator
print(set1 & set2)
#Output: {1, 3}

#using set intersection() method
print(set1.intersection(set2))
#Output: {1, 3}
```

#### Difference

Difference of the set1 from set2 is a set of elements that are only in set2 but not in set1. Similarly, difference of the set2 from set1 is a set of elements that are only in set1 but not in set2. It is performed by difference() method or – operator.

```set1 = {4, 3, 1, 8, 6}
set2 = {2, 1, 3, 7}

#using - operator
print("set1 - set2:",set1 - set2)
print("set2 - set1:",set2 - set1)
#Output: set1 - set2: {8, 4, 6}
set2 - set1: {2, 7}

#using set difference() method
print("set1 - set2:",set1.difference(set2))
print("set2 - set1:",set2.difference(set1))
#Output: set1 - set2: {8, 4, 6}
set2 - set1: {2, 7}```

#### Symmetric Difference

Symmetric Difference of set1 and set2 is a set of elements in set1 and set2 but not in both. It is performed by using symmetric_difference() method or ^ operator

```set1 = {4, 3, 1, 8, 6}
set2 = {2, 1, 3, 7}

#using ^ operator
print(set1 ^ set2)
#Output: {2, 4, 6, 7, 8}

#using set symmetric_difference() method
print(set1.symmetric_difference(set2))
#Output: {2, 4, 6, 7, 8}```