Set Types¶
Indices and tables¶
Definition¶
In Python, a set is a container type that stores an unordered set of zero or more references to hashable objects.
Values must always be unique within the set, but, need not be the same type. An attempt to add a value that is already present will result in it being discarded (which is useful for removing duplicates from a sequence).
Sets support the typical membership test using in
, as well as several additional tests based on set theory like union, intersection, difference and symmetric difference.
Set¶
MUTABILITY: Mutable
A set is the mutable brother of the frozenset
type.
Sets can be constructed in a variety of ways:
Using curly brackets
{}
. For example:>>> foo = {'a', 'b', 'c', 99, 'b', 'a', 'z'} >>> foo {99, 'a', 'b', 'c', 'z'}
Note
It is not possible to create an empty set using the curly brackets
{}
as that syntax would create adict
.Using an expression in curly brackets
{}
to create a set comprehension. For example:>>> foo = {x for x in 'foobarbaz' if x in 'fb'} >>> foo {'b', 'f'}
Using the
set
constructor, which allows you to do several things:With no arguments, it creates an empty set:
>>> foo = set() >>> foo set()
When passed something it can iterate over, it builds the set from the items in the sequence:
>>> foo = set('foobarbif') >>> foo {'a', 'b', 'f', 'i', 'o', 'r'}
When passed a set, this is one way of shallow-copy ing the set:
>>> foo = set('foobarbif') >>> bar = set(foo) >>> bar {'a', 'b', 'f', 'i', 'o', 'r'}
Frozen Set¶
MUTABILITY: Immutable
The immutable brother of the set
type. The advantage to frozensets is that because they are immutable, they can be used as elements in another set, or, as dictionary keys.
Frozen sets can only be created using the frozenset
constructor, which operates the same as the set
constructor.
Frozensets support all the same common methods as the set
type.
Set Operations¶
All of the set types support a common set of operations which makes working back and forth between them very fluid and easy.
The mutable type supports an additional set of operations (no pun intended) that take advantage of the fact that you can modify its contents without creating a new object.
Common Set Operations¶
Items in a set can be iterated over. However, the order of items returned is arbitrary. For example:
>>> foo = {'a', 'b', 'c', 99, 'b', 'a', 'z', 4632} >>> foo {4632, 99, 'a', 'b', 'c', 'z'}Which is a different order than that returned when using a loop:
>>> foo = {'a', 'b', 'c', 99, 'b', 'a', 'z', 4632} >>> for item in foo: print(item, end=' ') c 99 a b z 4632
Sets do not support indexing or slicing / striding using the item access operator []
. Attempting to do so will result a TypeError
being thrown.
Sets can be compare to each other. Two sets are considered equal, using the ==
operator, if and only if every element of each set is contained in the other:
>>> foo = {'a', 'b', 'c'}
>>> bar = {'a', 'b', 'c'}
>>> bif = {'a', 'b', 'z'}
>>> baz = {'a', 'b', 'c', 'd'}
>>> foo == bar
True
>>> foo == bif
False
>>> foo == baz
False
Using the other comparison operators, like <
and <=
, does not behave the same as in other types. This difference is discussed further in Table 12, which enumerates the methods common to all set types, mutable and immutable.
Operation | Description |
---|---|
x in s | Membership testing. Returns >>> foo = {'a', 'b', 'c', 'd'}
>>> 'a' in foo
True
|
x not in s | Membership testing. Returns >>> foo = {'a', 'b', 'c', 'd'}
>>> 5 not in foo
True
|
len(s) | Returns the number of items in >>> foo = {'a', 'b', 'c', 'd'}
>>> len(foo)
4
|
s.isdisjoint(t) | Returns >>> foo = {'a', 'b', 'c', 'd'}
>>> bar = {'a', 'b', 'c', 'd'}
>>> bif = {'w', 'x', 'y', 'z'}
>>> foo.isdisjoint(bar)
False
>>> foo.isdisjoint(bif)
True
|
s.issubset(t) s <= t s < t |
Returns Use >>> foo = {'a', 'b', 'c', 'd'}
>>> bar = {'a', 'b', 'c', 'd', 'e', 'f'}
>>> bif = {'w', 'x', 'y', 'z'}
>>> foo <= bar
True
>>> boo <= bif
False
|
s.issuperset(t) s >= t s > t |
Returns Use >>> foo = {'a', 'b', 'c', 'd', 'e', 'f'}
>>> bar = {'a', 'b', 'c', 'd'}
>>> bif = {'w', 'x', 'y', 'z'}
>>> foo >= bar
True
>>> foo >= bif
False
|
s.union(*t) s | t | … |
Return a new set with the element from >>> foo = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
>>> bar = {15, 20}
>>> bif = {300, 999}
>>> foo | bar | bif
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 300, 999}
|
s.intersection(*t) s & t & … |
Return a new set with th elements common to >>> foo = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
>>> bar = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}
>>> bif = {1, 2, 5, 6, 7, 8, 13, 15 }
>>> foo & bar & bif
{1, 5, 7}
|
s.difference(*t) s - t - … |
Return a new set with elements in >>> foo = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
>>> bar = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}
>>> bif = {1, 2, 5, 6, 7, 8, 13, 15 }
>>> foo - bar - bif
{4, 10}
|
s.symmetric_difference(t) s ^ t |
Return a new set with elements in >>> foo = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
>>> bar = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}
>>> foo ^ bar
{2, 4, 6, 8, 10, 11, 13, 15, 17, 19}
|
s.copy() s ^ t |
Return a new set that is a shallow copy of >>> foo = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
>>> bar = foo.copy()
>>> bar
{1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 10}
|
Note
In the table above, t
can be any iterable if called on the non-operator versions of union()
, intersection()
, difference()
, symmetric_difference()
, issubset()
and issuperset()
. For example:
>>> {1, 2, 3, 4}.union([6, 8, 10, 12])
{1, 2, 3, 4, 6, 8, 10, 12}
Mutable Set Operations¶
Mutable set types support additional operations that immutable sets do not. These are shown in Table 13.
Operation | Description |
---|---|
s.update(*t) s |= t | … |
Update set >>> foo = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
>>> bar = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}
>>> bif = {1, 2, 5, 6, 7, 8, 13, 15 }
>>> foo |= bar | bif
>>> foo
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19}
|
s.intersection_update(*t) s &= t & … |
Update set >>> foo = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
>>> bar = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}
>>> bif = {1, 2, 5, 6, 7, 8, 13, 15 }
>>> foo &= bar & bif
>>> foo
{1, 5, 7}
|
s.difference_update(*t) s -= t - … |
Update set >>> foo = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
>>> bar = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}
>>> bif = {1, 2, 5, 6, 7, 8, 13, 15 }
>>> foo -= bar - bif
>>> foo
{1, 2, 4, 5, 6, 7, 8, 10}
|
s.symmetric_difference_update(*t) s ^= t ^ … |
Update set >>> foo = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
>>> bar = {1, 3, 5, 7, 9, 11, 13, 15, 17, 19}
>>> bif = {1, 2, 5, 6, 7, 8, 13, 15 }
>>> foo -= bar - bif
>>> foo
{1, 2, 4, 5, 6, 7, 8, 10}
|
s.add(x) s ^= t ^ … |
Add >>> foo = {1, 2, 3, 4}
>>> foo.add(5)
>>> foo
{1, 2, 3, 4, 5}
|
s.remove(x) s ^= t ^ … |
Remove Raises >>> foo = {1, 2, 3, 4}
>>> foo.remove(2)
>>> foo
{1, 3, 4}
|
s.discard(x) s ^= t ^ … |
Remove Won’t raise >>> foo = {1, 2, 3, 4}
>>> foo.discard(2)
>>> foo
{1, 3, 4}
|
s.pop() s ^= t ^ … |
Remove an arbitrary element from set Raises >>> foo = {1, 2, 3, 4}
>>> foo.pop()
>>> foo
1
|
s.clear() s ^= t ^ … |
Remove all elements from set >>> foo = {1, 2, 3, 4}
>>> foo.clear()
>>> foo
set()
|
Note
In the table above, t
can be any iterable if called on the non-operator versions of update()
, intersection_update()
, difference_update()
and symmetric_difference_update()
. For example:
>>> foo = {1, 2, 3, 4}
>>> foo.update([6, 8, 10, 12])
>>> foo
{1, 2, 3, 4, 6, 8, 10, 12}
Try it!
Try the following:
Create an empty set.
Create a set from the word “basketball”.
Using the set:
s = {2, 8, 9, 11, 15, 19, 32, 29, 30, 45, 46}
- Add the number 32 to the set.
- Remove the number 19 from the set.
- Find the length of the set.
Determine if ‘dogs’ are pets given the following set:
pets = {'cats', 'hamsters', 'snakes', 'dogs', 'rock'}