While poking around with the generator example below to try understanding the concept, some questions popped up:
- Why is the last equality false given that the generator was regenerated?
- With the command
g.f(g.iter[n])
, are we materializing the nᵗʰ element of the generator?
A = [1 2; 3 4]
B = [A^i for i in 0:2]
g = (A*b for b in B) # creates generator
G = collect(g) # 3-element Vector{Matrix{Int64}}
g.f(g.iter[2]) == G[2] # true
g.f(g.iter[3]) == G[3] # true
g.iter[3] = ones(2,2) # assigned to a different matrix here
g.f(g.iter[3]) == G[3] # false (OK)
g = (A*b for b in B) # re-creates generator
g.f(g.iter[2]) == G[2] # true
g.f(g.iter[3]) == G[3] # false (why does the previous assignment still stand?)
Thank you.
Why is the last equality false given that the generator was regenerated?
As there is no copy for B
. The generator g
holds the original reference of the iterator here:
julia> objectid(g.iter)
0x35595f9c567dff49
julia> objectid(B)
0x35595f9c567dff49
With the command g.f(g.iter[n])
, are we materializing the nᵗʰ element of the generator?
Only for (... for element in array)
it can be true
, but in general it is not the case.
There are two counterexamples to your guess.
- not all generators use the notion of “nᵗʰ element”:
julia> res = ( [i, j] for i = 1: 2, j = 1:2)
julia> n = 1; res.iter[1]
ERROR: MethodError: no method matching getindex(::Base.Iterators.ProductIterator{Tuple{UnitRange{Int64}, UnitRange{Int64}}}, ::Int64)
- we use the iterator interface to handle iterations. Random accessing is not available for iterables.
julia> using DataStructures
julia> xs = list(1, 2, 3)
list(1, 2, 3)
julia> g = (k * 2 for k in xs)
Base.Generator{Cons{Int64}, var"#17#18"}(var"#17#18"(), list(1, 2, 3))
julia> collect(g)
3-element Vector{Int64}:
2
4
6
g.iter[1]
ERROR: MethodError: no method matching getindex(::Cons{Int64}, ::Int64)
2 Likes