Re: giving set.add a return value
Sorry, this got lost in the shuffle without being sent, and the conversation seems to have died down. but since I wrote it ... On Sat, Jul 4, 2020 at 8:25 AM Stephen J. Turnbull < turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
Christopher Barker writes:
I am really confused here -- I'm suggesting that is should NOT be possible to tell the difference.
But it is possible to tell the difference, so that suggestion is moot.
I meant in the context of putting things in, or testing whether they are in, sets. Not in any other context. There are languages where there is no numeric tower, just numbers, and
[0][0], [0][0.0], and [0][0+0j] all just work. Python isn't one of them. Fewer places you can tell in Python 3 than in Python 2, I believe, but several remain.
Sure, but putting them in sets, or using them as a key in a dict is not one of them. set.intern does yield the same result regardless of what's passed in:
whichever is in the set. That's *why* I can call it "intern".[1]
Fair enough. You can of course propose any functionality you want. I’m suggesting that my understanding of what you are proposing doesn’t match well with the rest of how sets work. But to see if I understand correctly, you couldn’t quite use a set to intern objects: once 2.0 was in there you could not put 2 in as well. You could know that 2.0 was already in there when you tried to add 2, but it would still never be added. It seems if you really want to intern objects, you’d need something kind of like, but not quite, a set(). Note: this all is only an issue for object that are of a different type, but can compare equal and have the same hash - maybe the numeric types are the only ones in the stdlib for which this is the case. Nevertheless, they are commonly used :-) Nope: turns out NamedTuples and Tuple are the "same" as far as sets are concerned as well. In [66]: s = {p} In [67]: s Out[67]: {Point(x=2, y=3)} In [68]: s.add((2,3)) In [69]: s Out[69]: {Point(x=2, y=3)} In [70]: s = {(2,3)} In [71]: s.add(p) In [72]: s Out[72]: {(2, 3)} So if you want something that treats different types with the same value as different, you really will need a different storage mechanism than a set. -CHB
Christopher Barker writes:
I meant in the context of putting things in, or testing whether they are in, sets. Not in any other context.
OK, but restricting context that way is asking for eventual trouble, because there's one more thing you can do with sets: get stuff out of them (by iterating).
But to see if I understand correctly, you couldn’t quite use a set to intern objects: once 2.0 was in there you could not put 2 in as well.
Good point. You could delete one and replace it with the other, but not have both. That does kind of defeat the whole idea of the "intern" nomenclature. Steve
On Tue, Jul 7, 2020 at 12:53 PM Stephen J. Turnbull <turnbull.stephen.fw@u.tsukuba.ac.jp> wrote:
Christopher Barker writes:
I meant in the context of putting things in, or testing whether they are in, sets. Not in any other context.
OK, but restricting context that way is asking for eventual trouble, because there's one more thing you can do with sets: get stuff out of them (by iterating).
But to see if I understand correctly, you couldn’t quite use a set to intern objects: once 2.0 was in there you could not put 2 in as well.
Good point. You could delete one and replace it with the other, but not have both. That does kind of defeat the whole idea of the "intern" nomenclature.
"Interning" is usually only done with strings. To get a similar effect, you could put (type(x), x) into the tuple, which would allow you to have both the int 2 and the float 2.0 in the interning set. Or have separate sets for different types. ChrisA
participants (3)
-
Chris Angelico
-
Christopher Barker
-
Stephen J. Turnbull