Sets

https://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset

INTRODUCTION

A set object is an unordered collection of distinct 'hashable' objects. Common uses include membership testing, removing duplicates from a sequence, and computing mathematical operations such as intersection, union, difference, and symmetric difference.

There are two built-in set types, 'set' (mutable) and 'frozenset' (immutable, hashable).

+-----------------------------+--------------+---------------------------+
| Operation                   | Short        | Meaning                   |
+-----------------------------+--------------+---------------------------+
| S = set() ; S = frozenset() |              | empty sets                |
| S = {item1, item2}          |              | creation (set)            |
| S = set(iterable)           |              | creation                  |
| S = frozenset(iterable)     |              | creation                  |
| S = {c for c in iterable}   |              | set comprehension         |
| len(S)                      |              | cardinality of S          |
| for item in S: pass         |              | iteration                 |
| item in S                   |              | containing O(1)           |
| item not in S               |              | containing O(1)           |
| max(S), min(S)              |              | the largest|smallest item |
| S2 = S1.copy()              |              | shallow copy of S1        |
| S2 = set(S1)                |              | shallow copy of S1        |
| S1 == S2, S1 != S2          |              | comparisons               |
| S1.issubset(S2)             | S1 <= S2     | subset                    |
|                             | S1 < S2      | proper subset, S1 != S2   |
| S1.issuperset(S2)           | S1 >= S2     | superset                  |
|                             | S1 > S2      | proper superset, S1 != S2 |
| S1.union(S2)                | S1 | S2      | union                     |
| S1.union(S2, S3)            | S1 | S2 | S3 | union                     |
| S1.intersection(S2)         | S1 & S2      | iloczyn zbiorów           |
| S1.intersection(S2, S3)     | S1 & S2 & S3 | iloczyn zbiorów           |
| S1.difference(S2)           | S1 - S2      | difference                |
| S1.difference(S2, S3)       | S1 - S2 - S3 | dfference                 |
| S1.symmetric_difference(S2) | S1 ^ S2      | (S1 - S2) | (S2 - S1)     |
| S1.isdisjoint(S2)           |              | if intersection is empty  |
+-----------------------------+--------------+---------------------------+

MUTABLE SETS

+------------------------------------+---------------+
| Operation                          | Short         |
+------------------------------------+---------------+
| S1.update(S2)                      | S1 |= S2      |
| S1.update(S2, S3)                  | S1 |= S2 | S3 |
| S1.intersection_update(S2)         | S1 &= S2      |
| S1.intersection_update(S2, S3)     | S1 &= S2 & S3 |
| S1.difference_update(S2)           | S1 -= S2      |
| S1.difference_update(S2, S3)       | S1 -= S2 | S3 |
| S1.symmetric_difference_update(S2) | S1 ^= S2      |
| S.add(item)                        |               |
| S.remove(item) [item in S]         |               |
| S.discard(item)                    |               |
| S.pop() [non-empty]                |               |
| S.clear()                          |               |
+------------------------------------+---------------+

METHODS


# Creation

# Using a comma-separated list of elements within braces.
{'one', 'two', 'three'}   # Py2.7, Py3

# Using the type constructor.
set(['three', 'two', 'one'])   # known from old Py2
set('abracadabra')   # {'a', 'c', 'b', 'r', 'd'}, different chars
frozenset([1, 2, 1, 2, 3])   # frozenset({1, 2, 3})

# Using a set comprehension.
{c for c in 'abracadabra' if c not in 'abc'}   # {'r', 'd'}

# Instances of 'set' are compared to instances of 'frozenset' based on their members.

assert set('abc') == frozenset('abc')

# Binary operations that mix 'set' instances with 'frozenset'
# return the type of the first operand.

frozenset('ab') | set('bc')   # frozenset({'a', 'c', 'b'})
set('ab') | frozenset('bc')   # {'a', 'c', 'b'}

# Warning: sets only define partial ordering (subset relationships).
set_list.sort()   # result undefined!

EXERCISE

https://stackoverflow.com/questions/9792664/converting-a-list-to-a-set-changes-element-order


Problem.
Remove duplicates from a sequence and preserve the order.
Solution 1.
seen = set()
new_seq = [x for x in old_seq if not (x in seen or seen.add(x))]
Solution 2 (Py3.7+ preserves the insertion order in dict).
D = dict((key, None) for key in old_seq)
new_seq = list(D)