Sets

Tue 27 January 2015

Filed under Python

Sets

First: What is a 'set'?

In very short, a `set` is a collection with no duplicates.

For example: We have a list of names: `names = ['Alice', 'Bill', 'Jane', 'Jack', 'Bill']`. `Bill` is in that list twice. When we call `set(names)`, we will get back that list with `Bill` there only once. `['Alice', 'Bill', 'Jane', 'Jack']`

The Syntax

`set(iterable)`

`frozenset(iterable)`

• The iterable can be any iterable - list, string, etc.

**More about sets from the docs

A few more things about sets

• There are 2 types of sets: the regular `set()` and `frozenset()`.

• set is mutable. So we can add or remove or update items in the set.

• frozenset is immutable. And we cannot change anything about the set.

• Sets are not ordered.

Once we are working with sets, we can do a few more cool things like:

These operations only work on `set` and `frozenset` datatypes.

operation # description syntax 1 syntax 2 results
is subset?
does set1 include all items in set2?
set1.issubset(set2)
set1 <= set2
returns True or False
is **proper** subset?
does set1 include all items in set2 AND set1 != set2?
--
set1 < set2 (without equal sign)
returns True or False
is superset?
are all items in set 1 in set2?
set1.issuperset(set2)
set1 >= set2
returns True or False
is **proper** superset?
are all items in set 1 in set2 AND set1 != set2?
--
set1 > set2
returns True or False
is disjointed?
are *no* items in set1 in set2?
set1.isdisjoint(set2)
--
returns True or False
union
return all elements from all sets
set1.union(set2) ** can have many .union(set3) ...
set1|set2 (| set 3 ...)
returns a set*
intersection
return all elements that all sets have in common
set1.intersection(set2) ** can have many .intersection(set3) ...
set1&set2 (& set 3 ...)
returns a set*
difference
return all elements that are in set1 but not in set 2
set1.difference(set2) ** can have many .difference(set3) ...
set1-set2 (- set 3 ...)
returns a set*
symmetric_difference
return all elements that in **either** set1 **or** set2, but not both.
set1.symmetric_difference(set2)
set1^set2
returns a set*

* If operations mix a `set` and `frozenset`, then the result is an instance of the first. So the result of `set1 | frozenset2` is a `set`. The result of `frozenset1 | set2` is a `frozenset`.

A few examples:

All these examples use these lists:

```co_workers =["Zach", "Dave", "Jack", "Emily", "Zach"]
friends = ["Mary", "Lisa", "Jack", "Mary"]
neighbors = ["Annie", "Bill", "Mary", "Annie"]
```

Notice that each of those lists has a duplicate. So to make sure we don't include any duplicates, we'll call `set()` on each.

```>>>set_coworkers = set(co_workers)
set(["Zach", "Dave", "Jack", "Emily"])

>>>set_friends = set(friends)
set(["Mary", "Lisa", "Jack"])

>>>set_neighbors = set(neighbors)
set(["Annie", "Bill", "Mary"])
```

intersection --> return all elements that all sets have in common

```>>>set_neighbors.intersection(set_friends)
set(['Mary'])
>>>set_neighbors&set_friends
set(['Mary'])
```

union --> return all elements from all sets

```>>>set_neighbors.union(set_friends).union(set_coworkers)
set(['Zach', 'Bill', 'Dave', 'Jack', 'Annie', 'Lisa', 'Mary', 'Emily'])
>>>set_neighbors|set_friends|set_coworkers
set(['Zach', 'Bill', 'Dave', 'Jack', 'Annie', 'Lisa', 'Mary', 'Emily'])
```

difference --> return all elements that are in set1 but not in set 2

```>>>set_neighbors.difference(set_friends)
set(['Bill', 'Annie'])
>>>set_neighbors-set_friends
set(['Bill', 'Annie'])

>>>set_friends.difference(set_neighbors)
set(['Lisa', 'Jack'])
>>>set_friends-set_neighbors
set(['Lisa', 'Jack'])
```

symmetric_difference --> return all elements that in either set1 or set2, but not both.

```>>> set_friends.symmetric_difference(set_neighbors)
set(['Lisa', 'Bill', 'Jack', 'Annie'])
>>> set_friends^set_neighbors
set(['Lisa', 'Bill', 'Jack', 'Annie'])

>>>set_friends.symmetric_difference(set_neighbors)
set(['Lisa', 'Bill', 'Jack', 'Annie'])
>>>set_neighbors^set_friends
set(['Lisa', 'Bill', 'Jack', 'Annie'])
```

Another set of operations for sets (only for set; not frozenset - as they are immutable)

operation # description syntax 1 syntax 2 results
update
update set1 with elements from set2 (and others...)
set1.update(set2)
** can have many .update(set3)
set1|=set2 (|=set3 ...)
returns a set
intersection update
updates set1 only with items that are common set1 and set2 (and other sets ...)
set1.intersection_update(set2)
** can have many more
set1&=set2 (without equal sign)
returns a set
difference update
updates set1 to include the items from set1 that are not found in the other sets (ie: removes from set1 all items that are found in other sets)
set1.difference_update(set2)
set1-=set2
returns a set
symmetric difference update
updates set1 with only the elements that are found in either set, but not both
set1.symmetric_difference_update(set2)
set1^=set2
returns a set
adds an element to the set
--
returns a set
remove
removes an element
set1.remove(element)
returns a set (raises `KeyError` is element is not in set)
removes an element - only if it is present
--
returns a set
pop
removes and returns an arbitrary item from the set
set1.pop()
--
returns the abritrary element (raises `KeyError` if set is empty)
clear
return an empty set (removes all elements in the set)
set1.clear()
--
returns an empty set