-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Make keys of a dictionary a set #24580
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
I generally like the idea, but I’m wondering if you wouldn’t mind checking out the different kinds of dictionaries in DataStructures.jl, and see if this change makes sense for those as well? |
base/set.jl
Outdated
|
|
||
| # AbstractSets are idempotent under indexing: | ||
| keys(set::AbstractSet) = set | ||
| @inline function getindex(set::AbstractSet, x) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this change in this PR? Can't we have a PR that just makes KeyIterator into KeySet without adding getindex?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, agreed, I decided to decouple this but haven't got to it just yet
base/set.jl
Outdated
| end | ||
| return x | ||
| end | ||
| eltype(set::Type{<:AbstractSet{T}}) where {T} = T |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@isdefined(T) ? T : Any
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh, how can T be undefined here?
417c3e8 to
4471d08
Compare
|
OK... I've fixed this up a bit, removed #24508, and added news. @kmsquire there's nothing I could see as a problem. Slightly orthogonal issue - but I had assumed that both the |
| end | ||
| KeySet(dict::Associative) = KeySet{keytype(dict), typeof(dict)}(dict) | ||
|
|
||
| struct ValueIterator{T<:Associative} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this to be changed to ValueSet at the same time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unlike keys, values don’t have to be unique, so they aren’t really a set.
Hmmm... that |
Well, |
|
@kmsquire I am predisposed to a very tight coupling between indexing in iteration in both We don’t support infinite arrays (even sparse ones) that can’t be iterated to completion (eg I do think there is a place for infinite sets and indexable containers, and maybe the type tree needs tweaking here. For users I think it is important that the interface of abstract types is well-specified and IMO the most useful semantic is that arrays and associatives are extensions of the iteration API that let you get to the iterated elements quickly via indexing. I think this is important because generic code may use a mixture of |
`keys(::Associative)` now returns an `AbstractSet`.
4471d08 to
c66ed3e
Compare
|
@andyferris, thanks, I think I see now what you were referring to when you said that it wasn't iterable. Are you assuming that essentially every possible key has a value in a That isn't how I was thinking of the This still doesn't quite fit your requirement that "keys(dict) should include all valid keys (those that don’t throw errors upon indexing...)," since, well, the point of a |
|
Yes, I certainly see the practicality of My point was more about the generic |
|
Wait - I think I misunderstood. So
means that |
Yes, this is true--if there is such a promise, this I appreciate the rigor that you're applying here, trying to unify That said, I'm hoping we don't throw out the baby with the bath water. A |
|
What about OrderedDict? I'd expect |
Presumably, the answer should be yes, and similarly, for a |
|
Yes, agreed that we shouldn’t get rid of useful things. Ordered and sorted sets seem quite doable to me (I’d guess |
|
Yes, let's go ahead with this. Any additional properties that special dict types have can be reflected in the types of their respective iterators, e.g. ordered/sorted. Need to rerun CI probably. |
|
Funnily enough, without #24508 this PR has actually made some of the things I was trying to achieve with indexing of associatives worse. E.g. one thing I am chasing is that |
|
@andyferris, I'm confused, why should |
|
Currently |
I belatedly address this at #26359 (comment). In the meantime, it might be necessary to back out of this change (this PR) unless we do something much more drastic. |
|
Just FYI - python3 has keys as view: https://docs.python.org/3/library/stdtypes.html#dictionary-view-objects |
|
Yes we definitely want a view - both the earlier (I just realised that |
The keys of an
Associativeare unique, and generally support fastinbecause dictionaries generally support fast lookup. They are ideal candidates for being anAbstractSet.This PR renames
KeyIteratortoKeySetand makes it a subtype ofAbstractSet. The code changes are pretty much mechanical.This also plays into #24019 by building on #24508 (on which this PR is currently based). Briefly, in the future this may be useful for a multiple-index
getindex(or related) method forAssociativethat behaves consistently with those forAbstractArray.