3.4.5. Sets¶
In this section we introduce the Python
type set
. As the name suggests,
Python sets are intended to model the standrad
mathematical notion of a set. Like lists, sets are containers
that can contain any kind of object, except
that set elements must obey restriction discussed
ijn the section on mutability. Like
lists, they are mutable (that is, you can add
things to and remove things from a set);
Unlike lists, sets are unordered, so you don’t add or remove things
by referencing a particular index;
you use the add
or remove
method,
as shown below.
Just as with other containers, the in
operator is a valid test for containment:
>>> X = set([1,2,3])
>>> 2 in X
True
>>> 4 in X
False
>>> X[0]
Traceback (most recent call last):
...
TypeError: 'set' object does not support indexing
Also like other containers, sets have lengths, so len will work as expected. Sets are used when we are trying to keep track of a collection of things, don’t care about order, and especially when we don’t want duplicates. Like mathematical sets, Python sets can be unioned and intersected with other sets:
>>> S = set([1,2,3])
>>> T = set([1,2,5])
>>> S.union(T)
set([1, 2, 3, 5])
>>> S.intersection(T)
set([1, 2])
These operations build new sets, and do not change S
and T
:
>>> R = S.union(T)
>>> R
set([1, 2, 3, 5])
>>> S
set([1, 2, 3])
>>> T
set([1, 2, 5])
There are versions of union
and intersection that do change S
and T
:
>>> S.update(T)
>>> S
set([1, 2, 3, 5])
>>> S.intersection_update(T)
>>> S
set([1, 2])
Like other Python types, the name of the type can be used as a function to create instances of the type:
>>> L = [1,2,3,3]
>>> S = set(L)
>>> S
{1, 2, 3}
Here the set
function converts a list into a set,
removing duoplicates in the process. As with
other Python containers, calling the function with no arguments produces
an empty container, in this, the empty set:
>>> S = set()
>>> S
set([])
Python also provides more compact, and perhaps more familiar notation
for sets as well. So in the following code snippet, the first two
lines create sets and the next two are equivalent to the
union
and intersection
methods introduced above:
>>> S = {1,2,3}
>>> T = {1,2,5}
>>> S | T
set([1, 2, 3, 5])
>>> S & T
set([1, 2])
Note that whether curly braces produce a dictionary or a set depends on what’s inside the curly braces:
>>> {('a',0),('b',1)}
set([('b', 1), ('a', 0)])
Here we have a set of tuples. On the other hand:
>>> X = {'a':0 ,'b':1}
>>> type(X)
<type 'dict'>
3.4.5.1. Immutable sets¶
The immutable version of a list is a tuple. Mutability is the only reason we have a distinction between lists and tuples. But sets are lists with the order taken away. Is there a motivation for a comparable distinction between mutable and immutable sets?
There is, and Python has implemented it. Immutable sets are called frozensets. Frozensets have all the same operations as sets, except for the ones that change the sets:
>>> S = frozenset([1,2,3])
>>> Ss = set([1,2,3])
>>> T = frozenset([4,2,5])
>>> S.union(T)
frozenset([1, 2, 3, 4, 5])
>>> S.update(T)
...
AttributeError: 'frozenset' object has no attribute 'update'
>>> Ss.update(T)
>>> Ss
set([1, 2, 3, 4, 5])
>>> S.issuperset(T)
False
>>> S.pop()
....
AttributeError: 'frozenset' object has no attribute 'pop'
>>> Ss.pop()
1
All the set methods that update a set raise
the same error for frozensets (difference_update
, update
,
intersection_update
, symmetric_difference_update
,
and update
), and ditto for pop
and remove
.
See also
Section Mutability (advanced).