We already have a built-in immutable set for Python. It's called frozenset.<br><div class="gmail_quote"><div dir="ltr">On Fri, Dec 29, 2017 at 10:56 AM Chris Angelico <<a href="mailto:rosuav@gmail.com">rosuav@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Sat, Dec 30, 2017 at 2:38 AM, Steven D'Aprano <<a href="mailto:steve@pearwood.info" target="_blank">steve@pearwood.info</a>> wrote:<br>
> The lack of support for the `in` operator is a major difference, but<br>
> there's also `len` (equivalent to "count the one bits"), superset<br>
> and subset testing, various in-place mutator methods, etc. Java has a<br>
> BitSet class, and you can see the typical sorts of operations<br>
> commonly required:<br>
><br>
> <a href="https://docs.oracle.com/javase/8/docs/api/java/util/BitSet.html" rel="noreferrer" target="_blank">https://docs.oracle.com/javase/8/docs/api/java/util/BitSet.html</a><br>
<br>
Okay. A subclass of int could easily add a few more. Counting the 1<br>
bits isn't difficult; superset and subset testing are actually the<br>
same as 'contains' but with more than one bit at a time. (In fact,<br>
checking if a set contains a subset is *easier* with ints than with<br>
actual sets!) Are in-place mutators that big a deal? I'm sure there<br>
are sets in languages with no mutables.<br>
<br>
> Of course we can emulate set-like operations using ints, but the<br>
> interfaces are different, which is my point. Here's how to clear all the<br>
> flags of a set or int:<br>
><br>
>     the_flags.clear()<br>
><br>
>     the_flags = 0  # clear all the bits in an int<br>
<br>
That's a consequence of Python's mutability distinction. I don't think<br>
it's a fundamental difference. You could just as easily use "the_flags<br>
= set()" if it weren't for aliasing.<br>
<br>
> Setting a flag is *almost* the same between the two:<br>
><br>
>     the_flags |= {flag}  # set<br>
><br>
>     the_flags |= flag  # int<br>
<br>
That's because you can implicitly upcast a bitflag to a bitset.<br>
Effectively, ints give you a short-hand that sets can't. But if you<br>
explicitly call BitSet(flag) to create a set containing one flag, it<br>
would have the same effect.<br>
<br>
> although for sets, there are two other ways to set a flag which aren't<br>
> supported by ints:<br>
><br>
>     the_flags.add(flag)<br>
>     the_flags.update({flag})<br>
><br>
> Similarly for clearing flags:<br>
><br>
>     the_flags.discard(flag)<br>
><br>
>     the_flags & ~flag<br>
<br>
Mutability again. If you were to create an ImmutableSet type in<br>
Python, what would its API look like? My suspicion is that it'd<br>
largely use operators, and that it'd end up looking a lot like the<br>
integer API.<br>
<br>
An integer, at its lowest level, is represented as a set of bits. It's<br>
no more crazy to use an int as a set of bits than to use a string as a<br>
set of characters:<br>
<br>
<a href="https://docs.python.org/3/library/stdtypes.html#str.strip" rel="noreferrer" target="_blank">https://docs.python.org/3/library/stdtypes.html#str.strip</a><br>
<br>
ChrisA<br>
_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</blockquote></div>