diff options
author | Georg Brandl <georg@python.org> | 2007-08-15 14:28:01 (GMT) |
---|---|---|
committer | Georg Brandl <georg@python.org> | 2007-08-15 14:28:01 (GMT) |
commit | 8ec7f656134b1230ab23003a94ba3266d7064122 (patch) | |
tree | bc730d5fb3302dc375edd26b26f750d609b61d72 /Doc/library/sets.rst | |
parent | f56181ff53ba00b7bed3997a4dccd9a1b6217b57 (diff) | |
download | cpython-8ec7f656134b1230ab23003a94ba3266d7064122.zip cpython-8ec7f656134b1230ab23003a94ba3266d7064122.tar.gz cpython-8ec7f656134b1230ab23003a94ba3266d7064122.tar.bz2 |
Move the 2.6 reST doc tree in place.
Diffstat (limited to 'Doc/library/sets.rst')
-rw-r--r-- | Doc/library/sets.rst | 287 |
1 files changed, 287 insertions, 0 deletions
diff --git a/Doc/library/sets.rst b/Doc/library/sets.rst new file mode 100644 index 0000000..10cd6a0 --- /dev/null +++ b/Doc/library/sets.rst @@ -0,0 +1,287 @@ + +:mod:`sets` --- Unordered collections of unique elements +======================================================== + +.. module:: sets + :synopsis: Implementation of sets of unique elements. +.. moduleauthor:: Greg V. Wilson <gvwilson@nevex.com> +.. moduleauthor:: Alex Martelli <aleax@aleax.it> +.. moduleauthor:: Guido van Rossum <guido@python.org> +.. sectionauthor:: Raymond D. Hettinger <python@rcn.com> + + +.. versionadded:: 2.3 + +.. deprecated:: 2.6 + The built-in ``set``/``frozenset`` types replace this module. + +The :mod:`sets` module provides classes for constructing and manipulating +unordered collections of unique elements. Common uses include membership +testing, removing duplicates from a sequence, and computing standard math +operations on sets such as intersection, union, difference, and symmetric +difference. + +Like other collections, sets support ``x in set``, ``len(set)``, and ``for x in +set``. Being an unordered collection, sets do not record element position or +order of insertion. Accordingly, sets do not support indexing, slicing, or +other sequence-like behavior. + +Most set applications use the :class:`Set` class which provides every set method +except for :meth:`__hash__`. For advanced applications requiring a hash method, +the :class:`ImmutableSet` class adds a :meth:`__hash__` method but omits methods +which alter the contents of the set. Both :class:`Set` and :class:`ImmutableSet` +derive from :class:`BaseSet`, an abstract class useful for determining whether +something is a set: ``isinstance(obj, BaseSet)``. + +The set classes are implemented using dictionaries. Accordingly, the +requirements for set elements are the same as those for dictionary keys; namely, +that the element defines both :meth:`__eq__` and :meth:`__hash__`. As a result, +sets cannot contain mutable elements such as lists or dictionaries. However, +they can contain immutable collections such as tuples or instances of +:class:`ImmutableSet`. For convenience in implementing sets of sets, inner sets +are automatically converted to immutable form, for example, +``Set([Set(['dog'])])`` is transformed to ``Set([ImmutableSet(['dog'])])``. + + +.. class:: Set([iterable]) + + Constructs a new empty :class:`Set` object. If the optional *iterable* + parameter is supplied, updates the set with elements obtained from iteration. + All of the elements in *iterable* should be immutable or be transformable to an + immutable using the protocol described in section :ref:`immutable-transforms`. + + +.. class:: ImmutableSet([iterable]) + + Constructs a new empty :class:`ImmutableSet` object. If the optional *iterable* + parameter is supplied, updates the set with elements obtained from iteration. + All of the elements in *iterable* should be immutable or be transformable to an + immutable using the protocol described in section :ref:`immutable-transforms`. + + Because :class:`ImmutableSet` objects provide a :meth:`__hash__` method, they + can be used as set elements or as dictionary keys. :class:`ImmutableSet` + objects do not have methods for adding or removing elements, so all of the + elements must be known when the constructor is called. + + +.. _set-objects: + +Set Objects +----------- + +Instances of :class:`Set` and :class:`ImmutableSet` both provide the following +operations: + ++-------------------------------+------------+---------------------------------+ +| Operation | Equivalent | Result | ++===============================+============+=================================+ +| ``len(s)`` | | cardinality of set *s* | ++-------------------------------+------------+---------------------------------+ +| ``x in s`` | | test *x* for membership in *s* | ++-------------------------------+------------+---------------------------------+ +| ``x not in s`` | | test *x* for non-membership in | +| | | *s* | ++-------------------------------+------------+---------------------------------+ +| ``s.issubset(t)`` | ``s <= t`` | test whether every element in | +| | | *s* is in *t* | ++-------------------------------+------------+---------------------------------+ +| ``s.issuperset(t)`` | ``s >= t`` | test whether every element in | +| | | *t* is in *s* | ++-------------------------------+------------+---------------------------------+ +| ``s.union(t)`` | ``s | t`` | new set with elements from both | +| | | *s* and *t* | ++-------------------------------+------------+---------------------------------+ +| ``s.intersection(t)`` | ``s & t`` | new set with elements common to | +| | | *s* and *t* | ++-------------------------------+------------+---------------------------------+ +| ``s.difference(t)`` | ``s - t`` | new set with elements in *s* | +| | | but not in *t* | ++-------------------------------+------------+---------------------------------+ +| ``s.symmetric_difference(t)`` | ``s ^ t`` | new set with elements in either | +| | | *s* or *t* but not both | ++-------------------------------+------------+---------------------------------+ +| ``s.copy()`` | | new set with a shallow copy of | +| | | *s* | ++-------------------------------+------------+---------------------------------+ + +Note, the non-operator versions of :meth:`union`, :meth:`intersection`, +:meth:`difference`, and :meth:`symmetric_difference` will accept any iterable as +an argument. In contrast, their operator based counterparts require their +arguments to be sets. This precludes error-prone constructions like +``Set('abc') & 'cbs'`` in favor of the more readable +``Set('abc').intersection('cbs')``. + +.. versionchanged:: 2.3.1 + Formerly all arguments were required to be sets. + +In addition, both :class:`Set` and :class:`ImmutableSet` support set to set +comparisons. Two sets are equal if and only if every element of each set is +contained in the other (each is a subset of the other). A set is less than +another set if and only if the first set is a proper subset of the second set +(is a subset, but is not equal). A set is greater than another set if and only +if the first set is a proper superset of the second set (is a superset, but is +not equal). + +The subset and equality comparisons do not generalize to a complete ordering +function. For example, any two disjoint sets are not equal and are not subsets +of each other, so *all* of the following return ``False``: ``a<b``, ``a==b``, +or ``a>b``. Accordingly, sets do not implement the :meth:`__cmp__` method. + +Since sets only define partial ordering (subset relationships), the output of +the :meth:`list.sort` method is undefined for lists of sets. + +The following table lists operations available in :class:`ImmutableSet` but not +found in :class:`Set`: + ++-------------+------------------------------+ +| Operation | Result | ++=============+==============================+ +| ``hash(s)`` | returns a hash value for *s* | ++-------------+------------------------------+ + +The following table lists operations available in :class:`Set` but not found in +:class:`ImmutableSet`: + ++--------------------------------------+-------------+---------------------------------+ +| Operation | Equivalent | Result | ++======================================+=============+=================================+ +| ``s.update(t)`` | *s* \|= *t* | return set *s* with elements | +| | | added from *t* | ++--------------------------------------+-------------+---------------------------------+ +| ``s.intersection_update(t)`` | *s* &= *t* | return set *s* keeping only | +| | | elements also found in *t* | ++--------------------------------------+-------------+---------------------------------+ +| ``s.difference_update(t)`` | *s* -= *t* | return set *s* after removing | +| | | elements found in *t* | ++--------------------------------------+-------------+---------------------------------+ +| ``s.symmetric_difference_update(t)`` | *s* ^= *t* | return set *s* with elements | +| | | from *s* or *t* but not both | ++--------------------------------------+-------------+---------------------------------+ +| ``s.add(x)`` | | add element *x* to set *s* | ++--------------------------------------+-------------+---------------------------------+ +| ``s.remove(x)`` | | remove *x* from set *s*; raises | +| | | :exc:`KeyError` if not present | ++--------------------------------------+-------------+---------------------------------+ +| ``s.discard(x)`` | | removes *x* from set *s* if | +| | | present | ++--------------------------------------+-------------+---------------------------------+ +| ``s.pop()`` | | remove and return an arbitrary | +| | | element from *s*; raises | +| | | :exc:`KeyError` if empty | ++--------------------------------------+-------------+---------------------------------+ +| ``s.clear()`` | | remove all elements from set | +| | | *s* | ++--------------------------------------+-------------+---------------------------------+ + +Note, the non-operator versions of :meth:`update`, :meth:`intersection_update`, +:meth:`difference_update`, and :meth:`symmetric_difference_update` will accept +any iterable as an argument. + +.. versionchanged:: 2.3.1 + Formerly all arguments were required to be sets. + +Also note, the module also includes a :meth:`union_update` method which is an +alias for :meth:`update`. The method is included for backwards compatibility. +Programmers should prefer the :meth:`update` method because it is supported by +the builtin :class:`set()` and :class:`frozenset()` types. + + +.. _set-example: + +Example +------- + +:: + + >>> from sets import Set + >>> engineers = Set(['John', 'Jane', 'Jack', 'Janice']) + >>> programmers = Set(['Jack', 'Sam', 'Susan', 'Janice']) + >>> managers = Set(['Jane', 'Jack', 'Susan', 'Zack']) + >>> employees = engineers | programmers | managers # union + >>> engineering_management = engineers & managers # intersection + >>> fulltime_management = managers - engineers - programmers # difference + >>> engineers.add('Marvin') # add element + >>> print engineers + Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack']) + >>> employees.issuperset(engineers) # superset test + False + >>> employees.update(engineers) # update from another set + >>> employees.issuperset(engineers) + True + >>> for group in [engineers, programmers, managers, employees]: + ... group.discard('Susan') # unconditionally remove element + ... print group + ... + Set(['Jane', 'Marvin', 'Janice', 'John', 'Jack']) + Set(['Janice', 'Jack', 'Sam']) + Set(['Jane', 'Zack', 'Jack']) + Set(['Jack', 'Sam', 'Jane', 'Marvin', 'Janice', 'John', 'Zack']) + + +.. _immutable-transforms: + +Protocol for automatic conversion to immutable +---------------------------------------------- + +Sets can only contain immutable elements. For convenience, mutable :class:`Set` +objects are automatically copied to an :class:`ImmutableSet` before being added +as a set element. + +The mechanism is to always add a hashable element, or if it is not hashable, the +element is checked to see if it has an :meth:`__as_immutable__` method which +returns an immutable equivalent. + +Since :class:`Set` objects have a :meth:`__as_immutable__` method returning an +instance of :class:`ImmutableSet`, it is possible to construct sets of sets. + +A similar mechanism is needed by the :meth:`__contains__` and :meth:`remove` +methods which need to hash an element to check for membership in a set. Those +methods check an element for hashability and, if not, check for a +:meth:`__as_temporarily_immutable__` method which returns the element wrapped by +a class that provides temporary methods for :meth:`__hash__`, :meth:`__eq__`, +and :meth:`__ne__`. + +The alternate mechanism spares the need to build a separate copy of the original +mutable object. + +:class:`Set` objects implement the :meth:`__as_temporarily_immutable__` method +which returns the :class:`Set` object wrapped by a new class +:class:`_TemporarilyImmutableSet`. + +The two mechanisms for adding hashability are normally invisible to the user; +however, a conflict can arise in a multi-threaded environment where one thread +is updating a set while another has temporarily wrapped it in +:class:`_TemporarilyImmutableSet`. In other words, sets of mutable sets are not +thread-safe. + + +.. _comparison-to-builtin-set: + +Comparison to the built-in :class:`set` types +--------------------------------------------- + +The built-in :class:`set` and :class:`frozenset` types were designed based on +lessons learned from the :mod:`sets` module. The key differences are: + +* :class:`Set` and :class:`ImmutableSet` were renamed to :class:`set` and + :class:`frozenset`. + +* There is no equivalent to :class:`BaseSet`. Instead, use ``isinstance(x, + (set, frozenset))``. + +* The hash algorithm for the built-ins performs significantly better (fewer + collisions) for most datasets. + +* The built-in versions have more space efficient pickles. + +* The built-in versions do not have a :meth:`union_update` method. Instead, use + the :meth:`update` method which is equivalent. + +* The built-in versions do not have a ``_repr(sorted=True)`` method. + Instead, use the built-in :func:`repr` and :func:`sorted` functions: + ``repr(sorted(s))``. + +* The built-in version does not have a protocol for automatic conversion to + immutable. Many found this feature to be confusing and no one in the community + reported having found real uses for it. + |