Forgive me if this has already been discussed.
Could we add the idea of "negative" sets to Python? That means sets that contain EVERYTHING EXCEPT certain elements.
First, let's have a universal set that contains everything.
assert element in set.UNIVERSAL
The universal set is a superset of every other set.
assert set.UNIVERSAL >= any_set
Adding anything to universal set doesn't change anything.
assert set.UNIVERSAL | element == set.UNIVERSAL
However REMOVING an element from the set puts it on "negative list".
myset = set.UNIVERSAL myset.remove(element) assert element not in myset
Intersection of a "negative set" with a normal set gives again a normal set. Union of two negative sets, or a negative set with a normal set, gives a negative set.
The main issue: negative sets would not be iterable, but you can intersect them with the desired subdomain and iterate over.
You could create such a class with a few lines of code by inheriting from collections.abc.MutableSet
You as anyone with a pontual problem that would benefit from such a construct - I can't see why/when this would be useful unless in a project already dealing with symbolic/lazy mathematical concepts - in which case, the author would be already aware of these possibilities.
On Mon, 10 Aug 2020 at 08:23, haael haael@interia.pl wrote:
Forgive me if this has already been discussed.
Could we add the idea of "negative" sets to Python? That means sets that contain EVERYTHING EXCEPT certain elements.
First, let's have a universal set that contains everything.
assert element in set.UNIVERSAL
The universal set is a superset of every other set.
assert set.UNIVERSAL >= any_set
Adding anything to universal set doesn't change anything.
assert set.UNIVERSAL | element == set.UNIVERSAL
However REMOVING an element from the set puts it on "negative list".
myset = set.UNIVERSAL myset.remove(element) assert element not in myset
Intersection of a "negative set" with a normal set gives again a normal set. Union of two negative sets, or a negative set with a normal set, gives a negative set.
The main issue: negative sets would not be iterable, but you can intersect them with the desired subdomain and iterate over. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/MY77JS... Code of Conduct: http://python.org/psf/codeofconduct/
haael writes:
Could we add the idea of "negative" sets to Python? That means sets that contain EVERYTHING EXCEPT certain elements.
This is usually called the "complement" of a set. Since (in set theory) there is no set of all sets, "absolute" complement is an unfounded concept. The idea of having a universe and defining "absolute complement" as complement relative to the universe is often adopted, but it has set-theoretic problems (the universe doesn't have a powerset, for one thing), and frequently you end up with a hierarchy of universes (categorists who try build category theory on set theory run into that a lot).
Considering those points, this proposal seems very abstract. I think it's fun to think about, and maybe it has practical applications in constructing other sets. But a "set" that isn't iterable, and whose "in" is logically equivalent to "not in" its complement (which is a Python set!), doesn't seem directly useful in itself.
I think this is one where you need to present both use cases and an implementation. Speaking of implementations and fun:
First, let's have a universal set that contains everything.
assert element in set.UNIVERSAL
For what values of "everything"? Python sets cannot contain all the objects of Python. Specifically, an element of a set must be hashable. Will that be true for your universal set?
The universal set is a superset of every other set.
assert set.UNIVERSAL >= any_set
Is it a superset of all iterables (however you want to define the transformation of iterables to sets, given the "hashability" issue)?
However REMOVING an element from the set puts it on "negative list".
myset = set.UNIVERSAL
Shouldn't this be "myset = copy(set.UNIVERSAL)"?
You'd like it to be "myset = set(set.UNIVERSAL)", I guess, and that indeed would require adding set.UNIVERSAL to Python.
myset.remove(element) assert element not in myset
Intersection of a "negative set" with a normal set gives again a normal set. Union of two negative sets, or a negative set with a normal set, gives a negative set.
The main issue: negative sets would not be iterable, but you can intersect them with the desired subdomain and iterate over. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/MY77JS... Code of Conduct: http://python.org/psf/codeofconduct/
On Mon, Aug 10, 2020 at 2:20 PM Stephen J. Turnbull < turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
haael writes:
Could we add the idea of "negative" sets to Python? That means sets that contain EVERYTHING EXCEPT certain elements.
This is usually called the "complement" of a set. Since (in set theory) there is no set of all sets, "absolute" complement is an unfounded concept. The idea of having a universe and defining "absolute complement" as complement relative to the universe is often adopted, but it has set-theoretic problems (the universe doesn't have a powerset, for one thing), and frequently you end up with a hierarchy of universes (categorists who try build category theory on set theory run into that a lot).
Yes, we can implement things in Python that aren't allowed in formal mathematics and some fun questions arise. What should `set.UNIVERSAL in set.UNIVERSAL` return? Bertrand Russell thinks it's False.
Considering those points, this proposal seems very abstract. I think it's fun to think about, and maybe it has practical applications in constructing other sets. But a "set" that isn't iterable, and whose "in" is logically equivalent to "not in" its complement (which is a Python set!), doesn't seem directly useful in itself.
I think it'd be best if such a class was not a subclass of the Set ABC, since it's not iterable. You can use it like a set in certain situations where you know what you're doing, but avoid passing it to generic code that expects a real set.
I think this is one where you need to present both use cases and an implementation. Speaking of implementations and fun:
First, let's have a universal set that contains everything.
assert element in set.UNIVERSAL
For what values of "everything"? Python sets cannot contain all the objects of Python. Specifically, an element of a set must be hashable. Will that be true for your universal set?
The builtin set requires hashability, but you could certainly implement a subclass of the Set ABC that satisfies all contracts and accepts non-hashable elements. It would just be much less performant.
However REMOVING an element from the set puts it on "negative list".
myset = set.UNIVERSAL
Shouldn't this be "myset = copy(set.UNIVERSAL)"?
You'd like it to be "myset = set(set.UNIVERSAL)", I guess, and that indeed would require adding set.UNIVERSAL to Python.
I think the better API would be `myset = UniversalSet()`.
Anyway, in the end, I think we all agree that this is fun to think about but too obscure for the Python language itself. Maybe you could put it on PyPI.
On Mon, Aug 10, 2020 at 9:05 AM Alex Hall alex.mojaki@gmail.com wrote:
Yes, we can implement things in Python that aren't allowed in formal mathematics and some fun questions arise. What should `set.UNIVERSAL in set.UNIVERSAL` return? Bertrand Russell thinks it's False.
Well... Russell thinks that the answer can neither be True nor False. :-) That's why it's a paradox.
But without giving us more (and probably even if the OP does), this seems like a fun formal exercise that has no place in standard Python.
Anyone is perfectly free to define their own custom class (pun intended) `V` ... or maybe `L` for the intuitionists. Just give it an `.__contains__()` method that behaves as you like, and you are done. Maybe there are some more details, but it feels very custom, and not of wide usefulness.
The stuff about removing from V seems silly to me. It's always going to be equivalent to ask `if x not in Vminus` as just asking `if x in excluded`. And the latter we can do right now with regular sets.
On 8/10/20 7:20 AM, haael wrote:
myset = set.UNIVERSAL myset.remove(element)
You do realize that set.UNIVERSAL isn't the set of everything anymore?
You bound myset to be an alias for set.UNIVERSAL and then modified it.
You likely wanted to make a copy of set.UNIVERSAL, not just bind an alias to it here.
On 08/10 12:20, haael wrote:
Forgive me if this has already been discussed.
Could we add the idea of "negative" sets to Python? That means sets that contain EVERYTHING EXCEPT certain elements.
First, let's have a universal set that contains everything.
assert element in set.UNIVERSAL
The universal set is a superset of every other set.
assert set.UNIVERSAL >= any_set
Adding anything to universal set doesn't change anything.
assert set.UNIVERSAL | element == set.UNIVERSAL
However REMOVING an element from the set puts it on "negative list".
myset = set.UNIVERSAL myset.remove(element) assert element not in myset
Intersection of a "negative set" with a normal set gives again a normal set. Union of two negative sets, or a negative set with a normal set, gives a negative set.
The main issue: negative sets would not be iterable, but you can intersect them with the desired subdomain and iterate over. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/MY77JS... Code of Conduct: http://python.org/psf/codeofconduct/
Aside from the amusing thought experiments (that I admin I enjoy), isn't this the same as:
removed = set() assrt element in removed # False, as in it has not yet been "removed from the universal" set removed.add(element) assrt element not in removed # False, as it has been already "removed from the universal" set
If so, it should be relatively easy (as Joao says in some other reply) to implement a class that behaves that way.
On Mon, Aug 10, 2020 at 12:20:49PM +0100, haael wrote:
Forgive me if this has already been discussed.
Could we add the idea of "negative" sets to Python? That means sets that contain EVERYTHING EXCEPT certain elements.
Can you give an example of what you would use this for? A use-case.
It seems to me that the easiest way to use this would be to use invert the meaning of your universal set. Instead of:
unprocessed = set.UNIVERSAL for element in universe(): if element in unprocessed: process(element) unprocessed.remove(element)
do it like this:
processed = set() for element in universe(): if element not in processed: process(element) processed.add(element)
If you have a different use-case to this, I don't know what it would be.