[Python-ideas] a set of enum.Enum values rather than the construction of bit-sets as the "norm"?

Chris Angelico rosuav at gmail.com
Fri Dec 29 10:56:46 EST 2017

On Sat, Dec 30, 2017 at 2:38 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> The lack of support for the `in` operator is a major difference, but
> there's also `len` (equivalent to "count the one bits"), superset
> and subset testing, various in-place mutator methods, etc. Java has a
> BitSet class, and you can see the typical sorts of operations
> commonly required:
> https://docs.oracle.com/javase/8/docs/api/java/util/BitSet.html

Okay. A subclass of int could easily add a few more. Counting the 1
bits isn't difficult; superset and subset testing are actually the
same as 'contains' but with more than one bit at a time. (In fact,
checking if a set contains a subset is *easier* with ints than with
actual sets!) Are in-place mutators that big a deal? I'm sure there
are sets in languages with no mutables.

> Of course we can emulate set-like operations using ints, but the
> interfaces are different, which is my point. Here's how to clear all the
> flags of a set or int:
>     the_flags.clear()
>     the_flags = 0  # clear all the bits in an int

That's a consequence of Python's mutability distinction. I don't think
it's a fundamental difference. You could just as easily use "the_flags
= set()" if it weren't for aliasing.

> Setting a flag is *almost* the same between the two:
>     the_flags |= {flag}  # set
>     the_flags |= flag  # int

That's because you can implicitly upcast a bitflag to a bitset.
Effectively, ints give you a short-hand that sets can't. But if you
explicitly call BitSet(flag) to create a set containing one flag, it
would have the same effect.

> although for sets, there are two other ways to set a flag which aren't
> supported by ints:
>     the_flags.add(flag)
>     the_flags.update({flag})
> Similarly for clearing flags:
>     the_flags.discard(flag)
>     the_flags & ~flag

Mutability again. If you were to create an ImmutableSet type in
Python, what would its API look like? My suspicion is that it'd
largely use operators, and that it'd end up looking a lot like the
integer API.

An integer, at its lowest level, is represented as a set of bits. It's
no more crazy to use an int as a set of bits than to use a string as a
set of characters:



More information about the Python-ideas mailing list