Bearing in mind that the bitwise operators in python (&,|,~, etc...) are used precisely to perform operations in a very similar way to how a CPU would do it, my doubt lies in the following: knowing that, in the operations with sets (sets for friends) totally different things are done at the RAM level, why are the same operators used?
You could ask yourself the same question regarding the operator
+
and others. How is it that the same operator is used to do1+1
as to do"1"+"1"
, if what they do is completely different? How is it that the operator/
can be used both to divide numbers, and to separate components of a path if you use the moduluspathlib
? etc...The pragmatic explanation would be: because the language allows it and helps improve readability in many cases. The operator
+
(as well as the/
,|
,&
etc operators) can be overridden to do whatever you want and operate on any data type you define. This can be very useful to implement for example matrix calculation (numpy, pandas) or in cases such as string or path concatenation ofpathlib
. In the case of sets it makes the code more compact.You may object that although the use of those operators is "counterintuitive", what does a bitwise OR operation have to do with the union of sets?
In the case of sets, however, the
&
and operations|
are not as radically different as it seems at first glance from those same bitwise operations. In fact, in a certain sense (which I will exemplify below), they do the same thing.Example
Imagine that to represent a set we chose to use a bitmap (this is not how Python represents them, but it will serve to illustrate my point). That is, we have a bit to represent each possible element of a set, and if that bit is 1, then the element is in the set, while if it is zero, then it is not in the set.
So, for example, if our possible elements were the numbers 1 to 10, we could have 10 bits. The first bit represents element 1, the next bit represents element 2, and so on until the last bit would represent element 10.
With this representation the empty set
Z
would be00000 00000
(ten zeros, since the ten possible elements are absent). A setA
containing 1 and 3 could be10100 00000
. A setB
containing 3, 4, 7 and 10 would be00110 01001
.Well, notice that bitwise operations give the desired result on these set representations!
A|B
at the bit level it would give10110 01001
, which is the result of that union of sets, since elements 1, 3, 4, 7 and 10 are presentA&B
at the bit level it would give00100 00000
, and effectively that represents the intersection set, since it only contains 3.Z & A
exit00000 00000
, whileZ|A
exitA
.You can also read it like this:
A|B
is the set of elements that are in A or in B.A&B
is the set of elements that are in A AND in B.And if you wonder why it was not decided to use the words
and
andor
for this, the answer is that these words are not redefinable operators . They are exclusively reserved for use in boolean contexts.