-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Implement keys and pairs for Enumerate #48318
Conversation
23c1f45
to
6ffa806
Compare
See also #34851
In particular, the example in the issue linked above can also be fixed like this: julia> Base.pairs(A) = enumerate(A)
julia> findmin(Iterators.filter(!=(1), [3,2,1]))
(2, 2) |
This PR makes it possible to get |
This PR would lead to weird and confusing behavior: julia> it = enumerate(10:15)
julia> pairs(it)
6-element Vector{Pair{Int64, Int64}}:
1 => 10
2 => 11
3 => 12
4 => 13
5 => 14
6 => 15
julia> pairs(collect(it))
pairs(::Vector{Tuple{Int64, Int64}})(...):
1 => (1, 10)
2 => (2, 11)
3 => (3, 12)
4 => (4, 13)
5 => (5, 14)
6 => (6, 15) One expects that |
I don't think it's so surprising: julia> dict = Dict(:a => 1, :b => 2);
julia> pairs(dict)
Dict{Symbol, Int64} with 2 entries:
:a => 1
:b => 2
julia> pairs(collect(dict))
pairs(::Vector{Pair{Symbol, Int64}})(...):
1 => :a=>1
2 => :b=>2 Each iterator type is free to decide if the keys should be included in the iteration result (collected by But it's true that something is weird: julia> values(enumerate(10:11)) |> collect
2-element Vector{Tuple{Int64, Int64}}:
(1, 10)
(2, 11)
julia> values(Dict(:a => 1, :b => 2))
ValueIterator for a Dict{Symbol, Int64} with 2 entries. Values:
1
2 Ideally, Base.values(it::Iterators.Enumerate) = values(it.itr) but that would be breaking... |
Indeed, thanks for pointing the actual issue better! |
There is a deeper inconsistency in Julia that most iterators iterate only its values, except Dicts, which iterate key/value pairs. I think it'd be best if we, as far as possible, stick with only iterating the values. Hence, I suggest this behavior: julia> println(collect(enumerate("abc")))
[(1, 'a'), (2, 'b'), (3, 'c')]
julia> println(collect(pairs(enumerate("abc"))))
[1 => (1, 'a'), 2 => (2, 'b'), 3 => (3, 'c')] It may seem weird that the latter includes the keys twice - but it really doesn't. The values of an |
That would be more consistent indeed (though note that the special behavior affects all If we really interpret Still, it would be nice to have a wrapper that takes any iterator, and implements |
I agree with @jakobnissen . The fact that Furthermore, |
I'm not sure about that: This gives some freedom, for example to implement (For example Base defines |
Closing this since Probably a better approach is to provide a new type that can wrap any iterator and associate arbitrary keys or pairs (with keys counting from |
This implements
keys
andpairs
for iterators returned byenumerate
.This addresses #47124, enabling e.g.
The definition of
pairs
(in addition tokeys
) is required for iterators that have no length defined, as in the above example.