Sets in Python

Sets are collections of objects without any order. Sets are mutable but cannot contain mutable objects. An example of a set is given below:

Sets are enclosed in braces and can store any immutable objects.

In [98]:
S={'a','b','hello',12,(1,2,3)}
In [99]:
print S
set(['a', 'b', 12, 'hello', (1, 2, 3)])

In [100]:
The cardinality of a set can be checked using 'len':
  File "<ipython-input-100-5b525216f1fb>", line 1
    The cardinality of a set can be checked using 'len':
                  ^
SyntaxError: invalid syntax
In [101]:
print len(S)
5

Since a list is mutable, it cannot be a member of a cell:

In [102]:
notS={[1,2,3]}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-102-fa57760b3459> in <module>()
----> 1 notS={[1,2,3]}

TypeError: unhashable type: 'list'

Whereas a tuple can be:

In [103]:
okS={tuple([1,2,3])}
In [104]:
print okS
set([(1, 2, 3)])

Sets don't contain duplicate members:

In [105]:
anotherS={'a','b','a'}
In [106]:
print anotherS
set(['a', 'b'])

Question: Can Python sets contain other Python sets?

Answer: Try it!

Question: Why can't Python sets contain mutable objects?

Hint: Sets do not allow repeats!

Set operations:

Let's have a set:

In [107]:
S=set(tuple(range(10)))
In [108]:
print S
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

Membership testing:

In [109]:
print 0 in S
True

In [110]:
print -1 not in S
True

Subsets:

In [111]:
S.isdisjoint({13,14})
Out[111]:
True
In [112]:
S.issubset({1,2,3}) #Check if S is a subset of {1,2,3}
Out[112]:
False
In [113]:
S.issubset(set(tuple(range(100))))
Out[113]:
True
In [114]:
S<=set(tuple(range(100))) #Same as issubset above
Out[114]:
True
In [115]:
S<set(tuple(range(100))) #Proper subset test i.e., set <= other and set != other
Out[115]:
True
In [116]:
T=S.union({-1,-2}) #Equivalent operator: set | other I ...
In [117]:
print T
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -2, -1])

In [118]:
T=S.intersection({-1,0,1}) #Equivalent operator: set & other & ...
In [119]:
print T
set([0, 1])

In [120]:
T=S.difference([-1,0,1,2]) #Equivalent operator: set - other - ...
In [121]:
print T
set([3, 4, 5, 6, 7, 8, 9])

In [122]:
T=S.symmetric_difference([-1,0,1,2]) #Equivalent operator: set ^ other. Returns elements that are in either set but not both.
In [123]:
print T
set([3, 4, 5, 6, 7, 8, 9, -1])

Note that in the above two examples, we passed a list. All the above functions accept any 'iterable' as an argument but their operator counter parts will operate only on sets to avoid unexpected results from operations such as set('abc') & 'cbs'. For more details see Python documentation on sets.

There are multiple ways of updating a set:

In [124]:
S.update([-2,-1]) #Same as union. You can also use S|={-2,-1}.
In [125]:
print S
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -2])

Other operators can also be used similarly.

Elements can be added or removed to a set using 'add' or 'remove'.

In [126]:
S.add(100)
In [127]:
print S
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, 100, -2])

In [128]:
S.remove(-1)
In [129]:
print S
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 100, -2])

'remove(elem)' raise a KeyError exception if the element is not contained in the set.

In [130]:
S.remove(1000)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-130-7ff7c8e41a26> in <module>()
----> 1 S.remove(1000)

KeyError: 1000

'discard' does the same as 'remove' without raising any exception in case the element is not found.

In [131]:
S.discard(1000)

'pop' removes and returns an arbitrary element from the set and raises KeyError if the set is empty.

In [132]:
while(1):
    print S
    print S.pop()
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-132-efe053d450e2> in <module>()
      1 while(1):
      2     print S
----> 3     print S.pop()

KeyError: 'pop from an empty set'
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 100, -2])
0
set([1, 2, 3, 4, 5, 6, 7, 8, 9, 100, -2])
1
set([2, 3, 4, 5, 6, 7, 8, 9, 100, -2])
2
set([3, 4, 5, 6, 7, 8, 9, 100, -2])
3
set([4, 5, 6, 7, 8, 9, 100, -2])
4
set([5, 6, 7, 8, 9, 100, -2])
5
set([6, 7, 8, 9, 100, -2])
6
set([7, 8, 9, 100, -2])
7
set([8, 9, 100, -2])
8
set([9, 100, -2])
9
set([100, -2])
100
set([-2])
-2
set([])

'clear' removes all elements from the set. Note that S={} will not make S empty because {} is a dictionary. If you want to create an empty set use:

In [134]:
S=set()

Python also offers immutable sets which are called 'frozenset's.

(c) Dr. Fayyaz ul Amir Afsar Minhas, DCIS, PIEAS, Pakistan.