# Union of 2 sets does not contain all items

How come when I change the order of the two sets in the unions below, I get different results?

```    set1 = {1, 2, 3}
set2 = {True, False}

print(set1 | set2)
# {False, 1, 2, 3}

print(set2 | set1)
#{False, True, 2, 3}
```

# Why the union() doesn't contain all items

The `1` and `True` are equivalent and considered to be duplicates. Likewise the `0` and `False` are equivalent as well:

```    >>> 1 == True
True
>>> 0 == False
True
```

# Which equivalent value is used

When multiple equivalent values are encountered, sets keep the first one seen:

```    >>> {0, False}
{0}
>>> {False, 0}
{False}
```

# Ways to make the values be distinct

To get them to be treated as distinct, just store them in a `(value, type)` pair:

```    >>> set1 = {(1, int), (2, int), (3, int)}
>>> set2 = {(True, bool), (False, bool)}
>>> set1 | set2
{(3, <class 'int'>), (1, <class 'int'>), (2, <class 'int'>),
(True, <class 'bool'>), (False, <class 'bool'>)}
>>> set1 & set2
set()
```

Another way to make the values distinct is to store them as strings:

```    >>> set1 = {'1', '2', '3'}
>>> set2 = {'True', 'False'}
>>> set1 | set2
{'2', '3', 'False', 'True', '1'}
>>> set1 & set2
set()
```

Hope this clears up the mystery and shows the way forward :-)

This is the standard technique for breaking cross-type equivalence (i.e. `0.0 == 0`, `True == 1`, and `Decimal(8.5) == 8.5)`. The technique is used in Python 2.7's regular expression module to force unicode regexes to be cached distinctly from otherwise equivalent str regexes. The technique is also used in Python 3 for functools.lru_cache() when the typed parameter is true.