This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author steven.daprano
Recipients george-shuklin, rhettinger, steven.daprano
Date 2019-04-02.15:27:34
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1554218854.53.0.377935378559.issue36507@roundup.psfhosted.org>
In-reply-to
Content
Python is a programming language, and we're probably not going to care too much about compliance with ZFC set theory unless there is good *practical* and not theoretical reason to care. That's not to say that we want to break ZFC, only that if we do so, we won't lose any sleep over it.

And it certainly won't mean that 3 == 2 as you suggest.

But fortunately, we haven't violated ZFC and this is not a bug in Python.

You've made two serious errors in your code. The first is that your second line of code:

    y = frozenset(frozenset())

doesn't do what you think it does. It doesn't create a [frozen]set of a [frozen]set, (a nested set). It creates a simple, non-nested set. Printing the value of y in the interactive interpreter would have shown you that it was a plain old non-nested empty set:

    py> print(y)
    frozenset()

The code you want is something like:

   y = frozenset([frozenset()])

for reasons which I hope will become clear. The code you are actually using is equivalent to:

    temp = set()  # mutable (non-frozen)
    for x in frozenset():  # loop over the contents of the inner frozenset
        temp.add(x)  # since that inner set is empty, nothing gets added
    y = frozenset(temp)  # an empty frozenset


Your second error is using the `is` operator when you are talking about equality. The `is` operator tests for object identity, not equality, and the Python interpreter reserves the right to re-use objects when appropriate. In this case, the interpreter sees that it has two empty frozensets, and since they are indistinguishable and immutable, it saves memory by using the same object for both.

(To put it another way: the interpreter caches certain immutable objects to save memory, and empty frozensets happen to be included.)

Of course had you used `==` rather than `is` you would have got the same result, since two empty sets are equal, but the point still stands that you shouldn't use object identity when you mean equality.

Once we fix the bugs in your code, we see that ZFC is saved:

py> x = frozenset()  # empty set
py> y = frozenset([frozenset()])  # non-empty set
py> print(len(x), len(y))
0 1
py> x == y
False
History
Date User Action Args
2019-04-02 15:27:34steven.dapranosetrecipients: + steven.daprano, rhettinger, george-shuklin
2019-04-02 15:27:34steven.dapranosetmessageid: <1554218854.53.0.377935378559.issue36507@roundup.psfhosted.org>
2019-04-02 15:27:34steven.dapranolinkissue36507 messages
2019-04-02 15:27:34steven.dapranocreate